changeset 6703:04ab1ba96ce2

Automated merge with https://lafo.ssw.uni-linz.ac.at/hg/graalvm
author Laurent Daynes <Laurent.Daynes@oracle.com>
date Mon, 12 Nov 2012 11:48:01 +0100
parents 3a93ae3a6c9e (diff) 602ee4d1db61 (current diff)
children 4d6c13994690
files
diffstat 20 files changed, 604 insertions(+), 567 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/CompilationResult.java	Fri Nov 09 19:41:52 2012 +0100
+++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/CompilationResult.java	Mon Nov 12 11:48:01 2012 +0100
@@ -326,6 +326,9 @@
     private int frameSize = -1;
     private int customStackAreaOffset = -1;
     private int registerRestoreEpilogueOffset = -1;
+
+    private CalleeSaveLayout calleeSaveLayout;
+
     /**
      * The buffer containing the emitted machine code.
      */
@@ -370,6 +373,15 @@
     }
 
     /**
+     * Sets the info on callee-saved registers used by this method.
+     *
+     * @param csl the register-saving info.
+     */
+    public void setCalleeSaveLayout(CalleeSaveLayout csl) {
+        calleeSaveLayout = csl;
+    }
+
+    /**
      * 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
@@ -483,6 +495,13 @@
     }
 
     /**
+     * @return the layout information for callee-saved registers used by this method.
+     */
+    public CalleeSaveLayout getCalleeSaveLayout() {
+        return calleeSaveLayout;
+    }
+
+    /**
      * @return the machine code generated for this method
      */
     public byte[] getTargetCode() {
--- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/MetaUtil.java	Fri Nov 09 19:41:52 2012 +0100
+++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/MetaUtil.java	Mon Nov 12 11:48:01 2012 +0100
@@ -37,6 +37,15 @@
 public class MetaUtil {
 
     /**
+     * Returns true if the specified typed is exactly the type {@link java.lang.Object}.
+     */
+    public static boolean isJavaLangObject(ResolvedJavaType type) {
+        boolean result = type.getSuperclass() == null && !type.isInterface() && type.getKind() == Kind.Object;
+        assert result == type.getName().equals("Ljava/lang/Object;") : type.getName();
+        return result;
+    }
+
+    /**
      * Extends the functionality of {@link Class#getSimpleName()} to include a non-empty string for anonymous and local
      * classes.
      * 
--- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ResolvedJavaType.java	Fri Nov 09 19:41:52 2012 +0100
+++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ResolvedJavaType.java	Mon Nov 12 11:48:01 2012 +0100
@@ -152,6 +152,11 @@
     ResolvedJavaType getSuperclass();
 
     /**
+     * Gets the interfaces that this type defines. This method is analogous to {@link Class#getInterfaces()}.
+     */
+    ResolvedJavaType[] getInterfaces();
+
+    /**
      * Walks the class hierarchy upwards and returns the least common class that is a superclass of both the current and
      * the given type.
      *
--- a/graal/com.oracle.graal.graph/.checkstyle_checks.xml	Fri Nov 09 19:41:52 2012 +0100
+++ b/graal/com.oracle.graal.graph/.checkstyle_checks.xml	Mon Nov 12 11:48:01 2012 +0100
@@ -59,9 +59,6 @@
     <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"/>
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HexCodeFile.java	Fri Nov 09 19:41:52 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,434 +0,0 @@
-/*
- * 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.graal.hotspot;
-
-import java.io.*;
-import java.util.*;
-import java.util.regex.*;
-
-import com.oracle.graal.api.code.*;
-import com.oracle.graal.api.code.CompilationResult.CodeAnnotation;
-import com.oracle.graal.api.code.CompilationResult.CodeComment;
-import com.oracle.graal.api.code.CompilationResult.JumpTable;
-import com.oracle.graal.api.code.CompilationResult.LookupTable;
-
-
-/**
- * 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 = CodeUtil.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 input, int sourceOffset, String source, String sourceName) {
-        return new Parser(input, sourceOffset, source, sourceName).hcf;
-    }
-
-    /**
-     * Formats this HexCodeFile as a string that can be parsed with {@link #parse(String, int, 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 input) {
-        int index;
-        String s = input;
-        while ((index = s.indexOf(SECTION_DELIM)) != -1) {
-            s = s.substring(0, index) + " < |@" + s.substring(index + SECTION_DELIM.length());
-        }
-        return s;
-    }
-
-    /**
-     * Helper class to parse a string in the format produced by {@link HexCodeFile#toString()}
-     * and produce a {@link HexCodeFile} object.
-     */
-    static class Parser {
-
-        final String input;
-        final String inputSource;
-        String isa;
-        int wordWidth;
-        byte[] code;
-        long startAddress;
-        HexCodeFile hcf;
-
-        Parser(String input, int sourceOffset, String source, String sourceName) {
-            this.input = input;
-            this.inputSource = sourceName;
-            parseSections(sourceOffset, source);
-        }
-
-        void makeHCF() {
-            if (hcf == null) {
-                if (isa != null && wordWidth != 0 && code != null) {
-                    hcf = new HexCodeFile(code, startAddress, isa, wordWidth);
-                }
-            }
-        }
-
-        void checkHCF(String section, int offset) {
-            check(hcf != null, offset, section + " section must be after Platform and HexCode section");
-        }
-
-        void check(boolean condition, int offset, String message) {
-            if (!condition) {
-                error(offset, message);
-            }
-        }
-
-        Error error(int offset, String message) {
-            throw new Error(errorMessage(offset, message));
-        }
-
-        void warning(int offset, String message) {
-            System.err.println("Warning: " + errorMessage(offset, 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 lineStart = input.lastIndexOf(HexCodeFile.NEW_LINE, index) + 1;
-
-            String l = input.substring(lineStart, lineStart + 10);
-            System.out.println("YYY" + input.substring(index, index + 10) + "...");
-            System.out.println("XXX" + l + "...");
-
-            int pos = input.indexOf(HexCodeFile.NEW_LINE, 0);
-            int line = 1;
-            while (pos > 0 && pos < index) {
-                line++;
-                pos = input.indexOf(HexCodeFile.NEW_LINE, pos + 1);
-            }
-            return new InputPos(line, index - lineStart);
-        }
-
-        void parseSections(int offset, String source) {
-            assert input.startsWith(source, offset);
-            int index = 0;
-            int endIndex = source.indexOf(SECTION_DELIM);
-            while (endIndex != -1) {
-                while (source.charAt(index) <= ' ') {
-                    index++;
-                }
-                String section = source.substring(index, endIndex).trim();
-                parseSection(offset + index, section);
-                index = endIndex + SECTION_DELIM.length();
-                endIndex = source.indexOf(SECTION_DELIM, index);
-            }
-        }
-
-        int parseInt(int offset, String value) {
-            try {
-                return Integer.parseInt(value);
-            } catch (NumberFormatException e) {
-                throw error(offset, "Not a valid integer: " + value);
-            }
-        }
-
-        void parseSection(int offset, String section) {
-            if (section.isEmpty()) {
-                return;
-            }
-            assert input.startsWith(section, offset);
-            Matcher m = HexCodeFile.SECTION.matcher(section);
-            check(m.matches(), offset, "Section does not match pattern " + HexCodeFile.SECTION);
-
-            String header = m.group(1);
-            String body = m.group(2);
-            int headerOffset = offset + m.start(1);
-            int bodyOffset = offset + m.start(2);
-
-            if (header.equals("Platform")) {
-                check(isa == null, bodyOffset, "Duplicate Platform section found");
-                m = HexCodeFile.PLATFORM.matcher(body);
-                check(m.matches(), bodyOffset, "Platform does not match pattern " + HexCodeFile.PLATFORM);
-                isa = m.group(1);
-                wordWidth = parseInt(bodyOffset + m.start(2), m.group(2));
-                makeHCF();
-            } else if (header.equals("HexCode")) {
-                check(code == null, bodyOffset, "Duplicate Code section found");
-                m = HexCodeFile.HEX_CODE.matcher(body);
-                check(m.matches(), bodyOffset, "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, bodyOffset, "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", headerOffset);
-                m = HexCodeFile.COMMENT.matcher(body);
-                check(m.matches(), bodyOffset, "Comment does not match pattern " + HexCodeFile.COMMENT);
-                int pos = parseInt(bodyOffset + m.start(1), m.group(1));
-                String comment = m.group(2);
-                hcf.addComment(pos, comment);
-            } else if (header.equals("OperandComment")) {
-                checkHCF("OperandComment", headerOffset);
-                m = HexCodeFile.OPERAND_COMMENT.matcher(body);
-                check(m.matches(), bodyOffset, "OperandComment does not match pattern " + HexCodeFile.OPERAND_COMMENT);
-                int pos = parseInt(bodyOffset + m.start(1), m.group(1));
-                String comment = m.group(2);
-                hcf.addOperandComment(pos, comment);
-            } else if (header.equals("JumpTable")) {
-                checkHCF("JumpTable", headerOffset);
-                m = HexCodeFile.JUMP_TABLE.matcher(body);
-                check(m.matches(), bodyOffset, "JumpTable does not match pattern " + HexCodeFile.JUMP_TABLE);
-                int pos = parseInt(bodyOffset + m.start(1), m.group(1));
-                int entrySize = parseInt(bodyOffset + m.start(2), m.group(2));
-                int low = parseInt(bodyOffset + m.start(3), m.group(3));
-                int high = parseInt(bodyOffset + m.start(4), m.group(4));
-                hcf.jumpTables.add(new JumpTable(pos, low, high, entrySize));
-            } else if (header.equals("LookupTable")) {
-                checkHCF("LookupTable", headerOffset);
-                m = HexCodeFile.LOOKUP_TABLE.matcher(body);
-                check(m.matches(), bodyOffset, "LookupTable does not match pattern " + HexCodeFile.LOOKUP_TABLE);
-                int pos = parseInt(bodyOffset + m.start(1), m.group(1));
-                int npairs = parseInt(bodyOffset + m.start(2), m.group(2));
-                int keySize = parseInt(bodyOffset + m.start(3), m.group(3));
-                int offsetSize = parseInt(bodyOffset + m.start(4), m.group(4));
-                hcf.lookupTables.add(new LookupTable(pos, npairs, keySize, offsetSize));
-            } else {
-                error(offset, "Unknown section header: " + header);
-            }
-        }
-    }
-}
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaType.java	Fri Nov 09 19:41:52 2012 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaType.java	Mon Nov 12 11:48:01 2012 +0100
@@ -49,6 +49,7 @@
     private int instanceSize;
     private HashMap<Long, ResolvedJavaField> fieldCache;
     private ResolvedJavaType superType;
+    private ResolvedJavaType[] interfaces;
     private boolean superTypeSet;
     private ResolvedJavaField[] fields;
     private ConstantPool constantPool;
@@ -94,13 +95,31 @@
     @Override
     public ResolvedJavaType getSuperclass() {
         if (!superTypeSet) {
-            superType = (ResolvedJavaType) HotSpotGraalRuntime.getInstance().getCompilerToVM().getSuperType(this);
+            Class<?> javaSuper = toJava().getSuperclass();
+            if (javaSuper == null) {
+                superType = null;
+            } else {
+                superType = HotSpotGraalRuntime.getInstance().getRuntime().lookupJavaType(javaSuper);
+            }
             superTypeSet = true;
         }
         return superType;
     }
 
     @Override
+    public ResolvedJavaType[] getInterfaces() {
+        if (interfaces == null) {
+            Class[] javaInterfaces = toJava().getInterfaces();
+            ResolvedJavaType[] result = new ResolvedJavaType[javaInterfaces.length];
+            for (int i = 0; i < javaInterfaces.length; i++) {
+                result[i] = HotSpotGraalRuntime.getInstance().getRuntime().lookupJavaType(javaInterfaces[i]);
+            }
+            interfaces = result;
+        }
+        return interfaces;
+    }
+
+    @Override
     public ResolvedJavaType findLeastCommonAncestor(ResolvedJavaType otherType) {
         if (otherType instanceof HotSpotTypePrimitive) {
             return null;
@@ -145,6 +164,7 @@
 
     @Override
     public boolean isArrayClass() {
+        assert isArrayClass ^ (isInterface || isInstanceClass);
         return isArrayClass;
     }
 
@@ -171,11 +191,13 @@
 
     @Override
     public boolean isInstanceClass() {
+        assert isInstanceClass ^ (isInterface || isArrayClass);
         return isInstanceClass;
     }
 
     @Override
     public boolean isInterface() {
+        assert isInterface ^ (isInstanceClass || isArrayClass);
         return isInterface;
     }
 
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java	Fri Nov 09 19:41:52 2012 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java	Mon Nov 12 11:48:01 2012 +0100
@@ -57,6 +57,7 @@
 import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.nodes.type.*;
 import com.oracle.graal.phases.*;
+import com.oracle.graal.printer.*;
 import com.oracle.graal.snippets.*;
 
 /**
@@ -482,12 +483,10 @@
                 ResolvedJavaType arrayType = array.objectStamp().type();
                 if (arrayType != null && array.objectStamp().isExactType()) {
                     ResolvedJavaType elementType = arrayType.getComponentType();
-                    if (elementType.getSuperclass() != null) {
+                    if (!MetaUtil.isJavaLangObject(elementType)) {
                         CheckCastNode checkcast = graph.add(new CheckCastNode(elementType, value, null));
                         graph.addBeforeFixed(storeIndexed, checkcast);
                         value = checkcast;
-                    } else {
-                        assert elementType.getName().equals("Ljava/lang/Object;") : elementType.getName();
                     }
                 } else {
                     LoadHubNode arrayClass = graph.add(new LoadHubNode(array));
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotTypePrimitive.java	Fri Nov 09 19:41:52 2012 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotTypePrimitive.java	Mon Nov 12 11:48:01 2012 +0100
@@ -71,6 +71,11 @@
     }
 
     @Override
+    public ResolvedJavaType[] getInterfaces() {
+        return new ResolvedJavaType[0];
+    }
+
+    @Override
     public ResolvedJavaType findLeastCommonAncestor(ResolvedJavaType otherType) {
         return null;
     }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/UnsignedMathSnippets.java	Fri Nov 09 19:41:52 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,86 +0,0 @@
-/*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.graal.hotspot.snippets;
-
-import static com.oracle.graal.nodes.MaterializeNode.*;
-import static com.oracle.graal.nodes.calc.Condition.*;
-
-import com.oracle.graal.api.code.*;
-import com.oracle.graal.snippets.*;
-
-/**
- * Snippets for {@link UnsignedMath}.
- */
-@ClassSubstitution(UnsignedMath.class)
-public class UnsignedMathSnippets implements SnippetsInterface {
-
-    public static boolean aboveThan(int a, int b) {
-        return materialize(BT, b, a);
-    }
-
-    public static boolean aboveOrEqual(int a, int b) {
-        return !materialize(BT, a, b);
-    }
-
-    /**
-     * Unsigned comparison belowThan for two numbers.
-     */
-    public static boolean belowThan(int a, int b) {
-        return materialize(BT, a, b);
-    }
-
-    /**
-     * Unsigned comparison belowOrEqual for two numbers.
-     */
-    public static boolean belowOrEqual(int a, int b) {
-        return !materialize(BT, b, a);
-    }
-
-    /**
-     * Unsigned comparison aboveThan for two numbers.
-     */
-    public static boolean aboveThan(long a, long b) {
-        return materialize(BT, b, a);
-    }
-
-    /**
-     * Unsigned comparison aboveOrEqual for two numbers.
-     */
-    public static boolean aboveOrEqual(long a, long b) {
-        return !materialize(BT, a, b);
-    }
-
-    /**
-     * Unsigned comparison belowThan for two numbers.
-     */
-    public static boolean belowThan(long a, long b) {
-        return materialize(BT, a, b);
-    }
-
-    /**
-     * Unsigned comparison belowOrEqual for two numbers.
-     */
-    public static boolean belowOrEqual(long a, long b) {
-        return !materialize(BT, b, a);
-    }
-}
--- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/BciBlockMapping.java	Fri Nov 09 19:41:52 2012 +0100
+++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/BciBlockMapping.java	Mon Nov 12 11:48:01 2012 +0100
@@ -762,7 +762,7 @@
         while (stream.currentBCI() <= block.endBci) {
             switch (stream.currentBC()) {
                 case RETURN:
-                    if (method.isConstructor() && method.getDeclaringClass().getSuperclass() == null) {
+                    if (method.isConstructor() && MetaUtil.isJavaLangObject(method.getDeclaringClass())) {
                         // return from Object.init implicitly registers a finalizer
                         // for the receiver if needed, so keep it alive.
                         loadOne(block, 0);
--- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/FrameStateBuilder.java	Fri Nov 09 19:41:52 2012 +0100
+++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/FrameStateBuilder.java	Mon Nov 12 11:48:01 2012 +0100
@@ -339,7 +339,7 @@
      * @param i the index into the locals
      * @return the instruction that produced the value for the specified local
      */
-    protected final ValueNode localAt(int i) {
+    public final ValueNode localAt(int i) {
         return locals[i];
     }
 
@@ -349,7 +349,7 @@
      * @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
      */
-    protected final ValueNode stackAt(int i) {
+    public final ValueNode stackAt(int i) {
         return stack[i];
     }
 
--- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java	Fri Nov 09 19:41:52 2012 +0100
+++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java	Mon Nov 12 11:48:01 2012 +0100
@@ -173,11 +173,16 @@
 
         // finish the start block
         ((StateSplit) lastInstr).setStateAfter(frameState.create(0));
+
+        currentBlock = blockMap.startBlock;
+        blockMap.startBlock.entryState = frameState;
         if (blockMap.startBlock.isLoopHeader) {
+            // TODO(lstadler,gduboscq) createTarget might not be safe at this position, since it expects currentBlock,
+            // etc. to be set up correctly. A better solution to this problem of start blocks that are loop headers
+            // would be to create a dummy block in BciBlockMapping.
             appendGoto(createTarget(blockMap.startBlock, frameState));
         } else {
             blockMap.startBlock.firstInstruction = lastInstr;
-            blockMap.startBlock.entryState = frameState;
         }
 
         for (Block block : blockMap.blocks) {
@@ -1358,7 +1363,7 @@
     }
 
     private void createReturn() {
-        if (method.isConstructor() && method.getDeclaringClass().getSuperclass() == null) {
+        if (method.isConstructor() && MetaUtil.isJavaLangObject(method.getDeclaringClass())) {
             callRegisterFinalizer();
         }
         Kind returnKind = method.getSignature().getReturnKind().getStackKind();
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/asm/TargetMethodAssembler.java	Fri Nov 09 19:41:52 2012 +0100
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/asm/TargetMethodAssembler.java	Mon Nov 12 11:48:01 2012 +0100
@@ -108,6 +108,9 @@
             }
         }
 
+        // Set the info on callee-saved registers
+        targetMethod.setCalleeSaveLayout(frameMap.registerConfig.getCalleeSaveLayout());
+
         Debug.metric("TargetMethods").increment();
         Debug.metric("CodeBytesEmitted").add(targetMethod.getTargetCodeSize());
         Debug.metric("SafepointsEmitted").add(targetMethod.getSafepoints().size());
--- a/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/GraphPrinterDumpHandler.java	Fri Nov 09 19:41:52 2012 +0100
+++ b/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/GraphPrinterDumpHandler.java	Mon Nov 12 11:48:01 2012 +0100
@@ -204,6 +204,8 @@
         for (int i = 0; i < previousInlineContext.size(); i++) {
             closeScope();
         }
-        printer.close();
+        if (printer != null) {
+            printer.close();
+        }
     }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/HexCodeFile.java	Mon Nov 12 11:48:01 2012 +0100
@@ -0,0 +1,434 @@
+/*
+ * 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.graal.printer;
+
+import java.io.*;
+import java.util.*;
+import java.util.regex.*;
+
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.code.CompilationResult.CodeAnnotation;
+import com.oracle.graal.api.code.CompilationResult.CodeComment;
+import com.oracle.graal.api.code.CompilationResult.JumpTable;
+import com.oracle.graal.api.code.CompilationResult.LookupTable;
+
+
+/**
+ * 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 = CodeUtil.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 input, int sourceOffset, String source, String sourceName) {
+        return new Parser(input, sourceOffset, source, sourceName).hcf;
+    }
+
+    /**
+     * Formats this HexCodeFile as a string that can be parsed with {@link #parse(String, int, 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 input) {
+        int index;
+        String s = input;
+        while ((index = s.indexOf(SECTION_DELIM)) != -1) {
+            s = s.substring(0, index) + " < |@" + s.substring(index + SECTION_DELIM.length());
+        }
+        return s;
+    }
+
+    /**
+     * Helper class to parse a string in the format produced by {@link HexCodeFile#toString()}
+     * and produce a {@link HexCodeFile} object.
+     */
+    static class Parser {
+
+        final String input;
+        final String inputSource;
+        String isa;
+        int wordWidth;
+        byte[] code;
+        long startAddress;
+        HexCodeFile hcf;
+
+        Parser(String input, int sourceOffset, String source, String sourceName) {
+            this.input = input;
+            this.inputSource = sourceName;
+            parseSections(sourceOffset, source);
+        }
+
+        void makeHCF() {
+            if (hcf == null) {
+                if (isa != null && wordWidth != 0 && code != null) {
+                    hcf = new HexCodeFile(code, startAddress, isa, wordWidth);
+                }
+            }
+        }
+
+        void checkHCF(String section, int offset) {
+            check(hcf != null, offset, section + " section must be after Platform and HexCode section");
+        }
+
+        void check(boolean condition, int offset, String message) {
+            if (!condition) {
+                error(offset, message);
+            }
+        }
+
+        Error error(int offset, String message) {
+            throw new Error(errorMessage(offset, message));
+        }
+
+        void warning(int offset, String message) {
+            System.err.println("Warning: " + errorMessage(offset, 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 lineStart = input.lastIndexOf(HexCodeFile.NEW_LINE, index) + 1;
+
+            String l = input.substring(lineStart, lineStart + 10);
+            System.out.println("YYY" + input.substring(index, index + 10) + "...");
+            System.out.println("XXX" + l + "...");
+
+            int pos = input.indexOf(HexCodeFile.NEW_LINE, 0);
+            int line = 1;
+            while (pos > 0 && pos < index) {
+                line++;
+                pos = input.indexOf(HexCodeFile.NEW_LINE, pos + 1);
+            }
+            return new InputPos(line, index - lineStart);
+        }
+
+        void parseSections(int offset, String source) {
+            assert input.startsWith(source, offset);
+            int index = 0;
+            int endIndex = source.indexOf(SECTION_DELIM);
+            while (endIndex != -1) {
+                while (source.charAt(index) <= ' ') {
+                    index++;
+                }
+                String section = source.substring(index, endIndex).trim();
+                parseSection(offset + index, section);
+                index = endIndex + SECTION_DELIM.length();
+                endIndex = source.indexOf(SECTION_DELIM, index);
+            }
+        }
+
+        int parseInt(int offset, String value) {
+            try {
+                return Integer.parseInt(value);
+            } catch (NumberFormatException e) {
+                throw error(offset, "Not a valid integer: " + value);
+            }
+        }
+
+        void parseSection(int offset, String section) {
+            if (section.isEmpty()) {
+                return;
+            }
+            assert input.startsWith(section, offset);
+            Matcher m = HexCodeFile.SECTION.matcher(section);
+            check(m.matches(), offset, "Section does not match pattern " + HexCodeFile.SECTION);
+
+            String header = m.group(1);
+            String body = m.group(2);
+            int headerOffset = offset + m.start(1);
+            int bodyOffset = offset + m.start(2);
+
+            if (header.equals("Platform")) {
+                check(isa == null, bodyOffset, "Duplicate Platform section found");
+                m = HexCodeFile.PLATFORM.matcher(body);
+                check(m.matches(), bodyOffset, "Platform does not match pattern " + HexCodeFile.PLATFORM);
+                isa = m.group(1);
+                wordWidth = parseInt(bodyOffset + m.start(2), m.group(2));
+                makeHCF();
+            } else if (header.equals("HexCode")) {
+                check(code == null, bodyOffset, "Duplicate Code section found");
+                m = HexCodeFile.HEX_CODE.matcher(body);
+                check(m.matches(), bodyOffset, "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, bodyOffset, "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", headerOffset);
+                m = HexCodeFile.COMMENT.matcher(body);
+                check(m.matches(), bodyOffset, "Comment does not match pattern " + HexCodeFile.COMMENT);
+                int pos = parseInt(bodyOffset + m.start(1), m.group(1));
+                String comment = m.group(2);
+                hcf.addComment(pos, comment);
+            } else if (header.equals("OperandComment")) {
+                checkHCF("OperandComment", headerOffset);
+                m = HexCodeFile.OPERAND_COMMENT.matcher(body);
+                check(m.matches(), bodyOffset, "OperandComment does not match pattern " + HexCodeFile.OPERAND_COMMENT);
+                int pos = parseInt(bodyOffset + m.start(1), m.group(1));
+                String comment = m.group(2);
+                hcf.addOperandComment(pos, comment);
+            } else if (header.equals("JumpTable")) {
+                checkHCF("JumpTable", headerOffset);
+                m = HexCodeFile.JUMP_TABLE.matcher(body);
+                check(m.matches(), bodyOffset, "JumpTable does not match pattern " + HexCodeFile.JUMP_TABLE);
+                int pos = parseInt(bodyOffset + m.start(1), m.group(1));
+                int entrySize = parseInt(bodyOffset + m.start(2), m.group(2));
+                int low = parseInt(bodyOffset + m.start(3), m.group(3));
+                int high = parseInt(bodyOffset + m.start(4), m.group(4));
+                hcf.jumpTables.add(new JumpTable(pos, low, high, entrySize));
+            } else if (header.equals("LookupTable")) {
+                checkHCF("LookupTable", headerOffset);
+                m = HexCodeFile.LOOKUP_TABLE.matcher(body);
+                check(m.matches(), bodyOffset, "LookupTable does not match pattern " + HexCodeFile.LOOKUP_TABLE);
+                int pos = parseInt(bodyOffset + m.start(1), m.group(1));
+                int npairs = parseInt(bodyOffset + m.start(2), m.group(2));
+                int keySize = parseInt(bodyOffset + m.start(3), m.group(3));
+                int offsetSize = parseInt(bodyOffset + m.start(4), m.group(4));
+                hcf.lookupTables.add(new LookupTable(pos, npairs, keySize, offsetSize));
+            } else {
+                error(offset, "Unknown section header: " + header);
+            }
+        }
+    }
+}
--- a/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/GraalIntrinsics.java	Fri Nov 09 19:41:52 2012 +0100
+++ b/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/GraalIntrinsics.java	Mon Nov 12 11:48:01 2012 +0100
@@ -36,6 +36,7 @@
             installer.install(NodeClassSnippets.class);
             installer.install(LongSnippets.class);
             installer.install(IntegerSnippets.class);
+            installer.install(UnsignedMathSnippets.class);
         }
     }
 }
--- a/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/InstanceOfSnippetsTemplates.java	Fri Nov 09 19:41:52 2012 +0100
+++ b/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/InstanceOfSnippetsTemplates.java	Mon Nov 12 11:48:01 2012 +0100
@@ -272,7 +272,10 @@
         }
 
         private static void connectEnds(MergeNode merge, List<EndNode> ends, BeginNode successor) {
-            if (ends.size() == 1) {
+            if (ends.size() == 0) {
+                // InstanceOf has been lowered to always true or always false - this successor is therefore unreachable.
+                GraphUtil.killCFG(successor);
+            } else if (ends.size() == 1) {
                 EndNode end = ends.get(0);
                 ((FixedWithNextNode) end.predecessor()).setNext(successor);
                 merge.removeEnd(end);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/UnsignedMathSnippets.java	Mon Nov 12 11:48:01 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.graal.snippets;
+
+import static com.oracle.graal.nodes.MaterializeNode.*;
+import static com.oracle.graal.nodes.calc.Condition.*;
+
+import com.oracle.graal.api.code.*;
+
+/**
+ * Snippets for {@link UnsignedMath}.
+ */
+@ClassSubstitution(UnsignedMath.class)
+public class UnsignedMathSnippets implements SnippetsInterface {
+
+    public static boolean aboveThan(int a, int b) {
+        return materialize(BT, b, a);
+    }
+
+    public static boolean aboveOrEqual(int a, int b) {
+        return !materialize(BT, a, b);
+    }
+
+    /**
+     * Unsigned comparison belowThan for two numbers.
+     */
+    public static boolean belowThan(int a, int b) {
+        return materialize(BT, a, b);
+    }
+
+    /**
+     * Unsigned comparison belowOrEqual for two numbers.
+     */
+    public static boolean belowOrEqual(int a, int b) {
+        return !materialize(BT, b, a);
+    }
+
+    /**
+     * Unsigned comparison aboveThan for two numbers.
+     */
+    public static boolean aboveThan(long a, long b) {
+        return materialize(BT, b, a);
+    }
+
+    /**
+     * Unsigned comparison aboveOrEqual for two numbers.
+     */
+    public static boolean aboveOrEqual(long a, long b) {
+        return !materialize(BT, a, b);
+    }
+
+    /**
+     * Unsigned comparison belowThan for two numbers.
+     */
+    public static boolean belowThan(long a, long b) {
+        return materialize(BT, a, b);
+    }
+
+    /**
+     * Unsigned comparison belowOrEqual for two numbers.
+     */
+    public static boolean belowOrEqual(long a, long b) {
+        return !materialize(BT, b, a);
+    }
+}
--- a/make/solaris/makefiles/mapfile-vers-graal	Fri Nov 09 19:41:52 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,32 +0,0 @@
-#
-
-#
-# Copyright (c) 2006, 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.
-#  
-#
-
-# Define public interface.
-SUNWprivate_1.1 {
-        global:
-      # GRAAL JVM
-      JVM_InitializeGraalRuntime;
-};
--- a/src/share/vm/graal/graalCompiler.cpp	Fri Nov 09 19:41:52 2012 +0100
+++ b/src/share/vm/graal/graalCompiler.cpp	Mon Nov 12 11:48:01 2012 +0100
@@ -286,7 +286,7 @@
   HotSpotResolvedJavaType::set_accessFlags(obj, klass->access_flags().as_int());
   HotSpotResolvedJavaType::set_isInterface(obj, klass->is_interface());
   HotSpotResolvedJavaType::set_superCheckOffset(obj, klass->super_check_offset());
-  HotSpotResolvedJavaType::set_isInstanceClass(obj, klass->oop_is_instance());
+  HotSpotResolvedJavaType::set_isInstanceClass(obj, klass->oop_is_instance() && !klass->is_interface());
 
   if (klass->oop_is_javaArray()) {
     HotSpotResolvedJavaType::set_isArrayClass(obj, true);