changeset 11390:a313367eb5c2

Merge.
author Doug Simon <doug.simon@oracle.com>
date Wed, 21 Aug 2013 18:45:45 +0200
parents 7040c65689c5 9088d13767f3
children f34b01673b6a
files graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/IntegerStampTest.java graal/com.oracle.graal.nodes.test/src/com/oracle/graal/nodes/test/StampTest.java
diffstat 17 files changed, 395 insertions(+), 363 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/IntegerStampTest.java	Wed Aug 21 18:15:55 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,183 +0,0 @@
-/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.graal.compiler.test;
-
-import static org.junit.Assert.*;
-
-import org.junit.*;
-
-import com.oracle.graal.api.meta.*;
-import com.oracle.graal.nodes.*;
-import com.oracle.graal.nodes.type.*;
-
-/**
- * This class tests that integer stamps are created correctly for constants.
- */
-public class IntegerStampTest {
-
-    private StructuredGraph graph;
-
-    @Before
-    public void before() {
-        graph = new StructuredGraph();
-    }
-
-    @Test
-    public void testBooleanConstant() {
-        assertEquals(new IntegerStamp(Kind.Int, 1, 1, 0x1, 0x1), ConstantNode.forBoolean(true, graph).stamp());
-        assertEquals(new IntegerStamp(Kind.Int, 0, 0, 0x0, 0x0), ConstantNode.forBoolean(false, graph).stamp());
-    }
-
-    @Test
-    public void testByteConstant() {
-        assertEquals(new IntegerStamp(Kind.Int, 0, 0, 0x0, 0x0), ConstantNode.forByte((byte) 0, graph).stamp());
-        assertEquals(new IntegerStamp(Kind.Int, 16, 16, 0x10, 0x10), ConstantNode.forByte((byte) 16, graph).stamp());
-        assertEquals(new IntegerStamp(Kind.Int, -16, -16, 0xf0, 0xf0), ConstantNode.forByte((byte) -16, graph).stamp());
-        assertEquals(new IntegerStamp(Kind.Int, 127, 127, 0x7f, 0x7f), ConstantNode.forByte((byte) 127, graph).stamp());
-        assertEquals(new IntegerStamp(Kind.Int, -128, -128, 0x80, 0x80), ConstantNode.forByte((byte) -128, graph).stamp());
-    }
-
-    @Test
-    public void testShortConstant() {
-        assertEquals(new IntegerStamp(Kind.Int, 0, 0, 0x0, 0x0), ConstantNode.forShort((short) 0, graph).stamp());
-        assertEquals(new IntegerStamp(Kind.Int, 128, 128, 0x80, 0x80), ConstantNode.forShort((short) 128, graph).stamp());
-        assertEquals(new IntegerStamp(Kind.Int, -128, -128, 0xff80, 0xff80), ConstantNode.forShort((short) -128, graph).stamp());
-        assertEquals(new IntegerStamp(Kind.Int, 32767, 32767, 0x7fff, 0x7fff), ConstantNode.forShort((short) 32767, graph).stamp());
-        assertEquals(new IntegerStamp(Kind.Int, -32768, -32768, 0x8000, 0x8000), ConstantNode.forShort((short) -32768, graph).stamp());
-    }
-
-    @Test
-    public void testCharConstant() {
-        assertEquals(new IntegerStamp(Kind.Int, 0, 0, 0x0, 0x0), ConstantNode.forChar((char) 0, graph).stamp());
-        assertEquals(new IntegerStamp(Kind.Int, 'A', 'A', 'A', 'A'), ConstantNode.forChar('A', graph).stamp());
-        assertEquals(new IntegerStamp(Kind.Int, 128, 128, 0x80, 0x80), ConstantNode.forChar((char) 128, graph).stamp());
-        assertEquals(new IntegerStamp(Kind.Int, 65535, 65535, 0xffff, 0xffff), ConstantNode.forChar((char) 65535, graph).stamp());
-    }
-
-    @Test
-    public void testIntConstant() {
-        assertEquals(new IntegerStamp(Kind.Int, 0, 0, 0x0, 0x0), ConstantNode.forInt(0, graph).stamp());
-        assertEquals(new IntegerStamp(Kind.Int, 128, 128, 0x80, 0x80), ConstantNode.forInt(128, graph).stamp());
-        assertEquals(new IntegerStamp(Kind.Int, -128, -128, 0xffffff80L, 0xffffff80L), ConstantNode.forInt(-128, graph).stamp());
-        assertEquals(new IntegerStamp(Kind.Int, Integer.MAX_VALUE, Integer.MAX_VALUE, 0x7fffffff, 0x7fffffff), ConstantNode.forInt(Integer.MAX_VALUE, graph).stamp());
-        assertEquals(new IntegerStamp(Kind.Int, Integer.MIN_VALUE, Integer.MIN_VALUE, 0x80000000L, 0x80000000L), ConstantNode.forInt(Integer.MIN_VALUE, graph).stamp());
-    }
-
-    @Test
-    public void testLongConstant() {
-        assertEquals(new IntegerStamp(Kind.Long, 0, 0, 0x0, 0x0), ConstantNode.forLong(0, graph).stamp());
-        assertEquals(new IntegerStamp(Kind.Long, 128, 128, 0x80, 0x80), ConstantNode.forLong(128, graph).stamp());
-        assertEquals(new IntegerStamp(Kind.Long, -128, -128, 0xffffffffffffff80L, 0xffffffffffffff80L), ConstantNode.forLong(-128, graph).stamp());
-        assertEquals(new IntegerStamp(Kind.Long, Long.MAX_VALUE, Long.MAX_VALUE, 0x7fffffffffffffffL, 0x7fffffffffffffffL), ConstantNode.forLong(Long.MAX_VALUE, graph).stamp());
-        assertEquals(new IntegerStamp(Kind.Long, Long.MIN_VALUE, Long.MIN_VALUE, 0x8000000000000000L, 0x8000000000000000L), ConstantNode.forLong(Long.MIN_VALUE, graph).stamp());
-    }
-
-    @Test
-    public void testPositiveRanges() {
-        assertEquals(new IntegerStamp(Kind.Int, 0, 0, 0, 0), StampFactory.forInteger(Kind.Int, 0, 0));
-        assertEquals(new IntegerStamp(Kind.Int, 0, 1, 0, 1), StampFactory.forInteger(Kind.Int, 0, 1));
-        assertEquals(new IntegerStamp(Kind.Int, 0, 0x123, 0, 0x1ff), StampFactory.forInteger(Kind.Int, 0, 0x123));
-        assertEquals(new IntegerStamp(Kind.Int, 0x120, 0x123, 0x120, 0x123), StampFactory.forInteger(Kind.Int, 0x120, 0x123));
-        assertEquals(new IntegerStamp(Kind.Int, 10000, 15000, 0x2000, 0x3fff), StampFactory.forInteger(Kind.Int, 10000, 15000));
-        assertEquals(new IntegerStamp(Kind.Long, 0, 1, 0, 1), StampFactory.forInteger(Kind.Long, 0, 1));
-        assertEquals(new IntegerStamp(Kind.Long, 10000, 15000, 0x2000, 0x3fff), StampFactory.forInteger(Kind.Long, 10000, 15000));
-        assertEquals(new IntegerStamp(Kind.Long, 140000000000L, 150000000000L, 0x2000000000L, 0x23ffffffffL), StampFactory.forInteger(Kind.Long, 140000000000L, 150000000000L));
-    }
-
-    @Test
-    public void testNegativeRanges() {
-        assertEquals(new IntegerStamp(Kind.Int, -2, -1, 0xfffffffeL, 0xffffffffL), StampFactory.forInteger(Kind.Int, -2, -1));
-        assertEquals(new IntegerStamp(Kind.Int, -20, -10, 0xffffffe0L, 0xffffffffL), StampFactory.forInteger(Kind.Int, -20, -10));
-        assertEquals(new IntegerStamp(Kind.Int, -10000, 0, 0, 0xffffffffL), StampFactory.forInteger(Kind.Int, -10000, 0));
-        assertEquals(new IntegerStamp(Kind.Int, -10000, -1, 0xffffc000L, 0xffffffffL), StampFactory.forInteger(Kind.Int, -10000, -1));
-        assertEquals(new IntegerStamp(Kind.Int, -10010, -10000, 0xffffd8e0L, 0xffffd8ffL), StampFactory.forInteger(Kind.Int, -10010, -10000));
-        assertEquals(new IntegerStamp(Kind.Long, -2, -1, 0xfffffffffffffffeL, 0xffffffffffffffffL), StampFactory.forInteger(Kind.Long, -2, -1));
-        assertEquals(new IntegerStamp(Kind.Long, -10010, -10000, 0xffffffffffffd8e0L, 0xffffffffffffd8ffL), StampFactory.forInteger(Kind.Long, -10010, -10000));
-        assertEquals(new IntegerStamp(Kind.Long, -150000000000L, -140000000000L, 0xffffffdc00000000L, 0xffffffdfffffffffL), StampFactory.forInteger(Kind.Long, -150000000000L, -140000000000L));
-    }
-
-    @Test
-    public void testMixedRanges() {
-        assertEquals(new IntegerStamp(Kind.Int, -1, 0, 0, 0xffffffffL), StampFactory.forInteger(Kind.Int, -1, 0));
-        assertEquals(new IntegerStamp(Kind.Int, -10000, 1000, 0, 0xffffffffL), StampFactory.forInteger(Kind.Int, -10000, 1000));
-        assertEquals(new IntegerStamp(Kind.Long, -10000, 1000, 0, 0xffffffffffffffffL), StampFactory.forInteger(Kind.Long, -10000, 1000));
-    }
-
-    @Test
-    public void testNarrowingConversions() {
-        // byte cases
-        assertEquals(StampFactory.forInteger(Kind.Int, 0, 0), StampTool.intToByte(StampFactory.forInteger(Kind.Int, 0, 0)));
-        assertEquals(StampFactory.forInteger(Kind.Int, 0, 10), StampTool.intToByte(StampFactory.forInteger(Kind.Int, 0, 10)));
-        assertEquals(StampFactory.forInteger(Kind.Int, 10, 20), StampTool.intToByte(StampFactory.forInteger(Kind.Int, 10, 20)));
-        assertEquals(StampFactory.forInteger(Kind.Int, -10, 0), StampTool.intToByte(StampFactory.forInteger(Kind.Int, -10, 0)));
-        assertEquals(StampFactory.forInteger(Kind.Int, -20, -10), StampTool.intToByte(StampFactory.forInteger(Kind.Int, -20, -10)));
-        assertEquals(StampFactory.forInteger(Kind.Int, Byte.MIN_VALUE, Byte.MAX_VALUE), StampTool.intToByte(StampFactory.forInteger(Kind.Int, 100, 200)));
-        assertEquals(StampFactory.forInteger(Kind.Int, Byte.MIN_VALUE, Byte.MAX_VALUE), StampTool.intToByte(StampFactory.forInteger(Kind.Int, -100, 200)));
-        assertEquals(StampFactory.forInteger(Kind.Int, Byte.MIN_VALUE, Byte.MAX_VALUE), StampTool.intToByte(StampFactory.forInteger(Kind.Int, -200, -100)));
-        // char cases
-        assertEquals(StampFactory.forInteger(Kind.Int, 0, 10), StampTool.intToChar(StampFactory.forInteger(Kind.Int, 0, 10)));
-        assertEquals(StampFactory.forInteger(Kind.Int, 10, 20), StampTool.intToChar(StampFactory.forInteger(Kind.Int, 10, 20)));
-        assertEquals(StampFactory.forInteger(Kind.Int, Character.MIN_VALUE, Character.MAX_VALUE), StampTool.intToChar(StampFactory.forInteger(Kind.Int, 20000, 80000)));
-        assertEquals(StampFactory.forInteger(Kind.Int, Character.MIN_VALUE, Character.MAX_VALUE), StampTool.intToChar(StampFactory.forInteger(Kind.Int, -10000, 40000)));
-        assertEquals(StampFactory.forInteger(Kind.Int, Character.MIN_VALUE, Character.MAX_VALUE), StampTool.intToChar(StampFactory.forInteger(Kind.Int, -40000, -10000)));
-        // short cases
-        assertEquals(StampFactory.forInteger(Kind.Int, 0, 10), StampTool.intToShort(StampFactory.forInteger(Kind.Int, 0, 10)));
-        assertEquals(StampFactory.forInteger(Kind.Int, 10, 20), StampTool.intToShort(StampFactory.forInteger(Kind.Int, 10, 20)));
-        assertEquals(StampFactory.forInteger(Kind.Int, Short.MIN_VALUE, Short.MAX_VALUE), StampTool.intToShort(StampFactory.forInteger(Kind.Int, 20000, 40000)));
-        assertEquals(StampFactory.forInteger(Kind.Int, Short.MIN_VALUE, Short.MAX_VALUE), StampTool.intToShort(StampFactory.forInteger(Kind.Int, -10000, 40000)));
-        assertEquals(StampFactory.forInteger(Kind.Int, Short.MIN_VALUE, Short.MAX_VALUE), StampTool.intToShort(StampFactory.forInteger(Kind.Int, -40000, -10000)));
-        // int cases
-        assertEquals(StampFactory.forInteger(Kind.Int, 0, 10), StampTool.longToInt(StampFactory.forInteger(Kind.Long, 0, 10)));
-        assertEquals(StampFactory.forInteger(Kind.Int, 10, 20), StampTool.longToInt(StampFactory.forInteger(Kind.Long, 10, 20)));
-        assertEquals(StampFactory.forInteger(Kind.Int, Integer.MIN_VALUE, Integer.MAX_VALUE), StampTool.longToInt(StampFactory.forInteger(Kind.Long, 20000000000L, 40000000000L)));
-        assertEquals(StampFactory.forInteger(Kind.Int, Integer.MIN_VALUE, Integer.MAX_VALUE), StampTool.longToInt(StampFactory.forInteger(Kind.Long, -10000000000L, 40000000000L)));
-        assertEquals(StampFactory.forInteger(Kind.Int, Integer.MIN_VALUE, Integer.MAX_VALUE), StampTool.longToInt(StampFactory.forInteger(Kind.Long, -40000000000L, -10000000000L)));
-    }
-
-    @Test
-    public void testXor() {
-        assertEquals(new IntegerStamp(Kind.Int, 0, 0xff, 0, 0xff), StampTool.xor(new IntegerStamp(Kind.Int, 0, 0, 0, 0), new IntegerStamp(Kind.Int, 0, 0xff, 0, 0xff)));
-        assertEquals(new IntegerStamp(Kind.Int, 0x10, 0x1f, 0x10, 0x1f), StampTool.xor(new IntegerStamp(Kind.Int, 0, 0, 0, 0), new IntegerStamp(Kind.Int, 0x10, 0x1f, 0x10, 0x1f)));
-        assertEquals(new IntegerStamp(Kind.Int, 0x0, 0xf, 0x0, 0xf), StampTool.xor(new IntegerStamp(Kind.Int, 0x10, 0x10, 0x10, 0x10), new IntegerStamp(Kind.Int, 0x10, 0x1f, 0x10, 0x1f)));
-        assertEquals(new IntegerStamp(Kind.Int, 0x10, 0x1f, 0x10, 0x1f), StampTool.xor(new IntegerStamp(Kind.Int, 0x10, 0x10, 0x10, 0x10), new IntegerStamp(Kind.Int, 0x0, 0xf, 0x0, 0xf)));
-    }
-
-    @Test
-    public void testNot() {
-        assertEquals(new IntegerStamp(Kind.Int, -11, -1, 0xfffffff0L, 0xffffffffL), StampTool.not(new IntegerStamp(Kind.Int, 0, 10, 0, 0xf)));
-    }
-
-    @Test
-    public void testAdd() {
-        assertEquals(StampFactory.forInteger(Kind.Int, 0, 30), StampTool.add(StampFactory.forInteger(Kind.Int, 0, 10), StampFactory.forInteger(Kind.Int, 0, 20)));
-        assertEquals(StampFactory.forKind(Kind.Long),
-                        StampTool.add(StampFactory.forInteger(Kind.Long, Long.MIN_VALUE, Long.MIN_VALUE + 1), StampFactory.forInteger(Kind.Long, Integer.MIN_VALUE, Integer.MAX_VALUE)));
-        assertEquals(StampFactory.forInteger(Kind.Int, -2147483647, 31 - 2147483647),
-                        StampTool.add(StampFactory.forInteger(Kind.Int, 0, 31), StampFactory.forInteger(Kind.Int, -2147483647, -2147483647)));
-    }
-
-    @Test
-    public void testAnd() {
-        assertEquals(new IntegerStamp(Kind.Int, Integer.MIN_VALUE, 0x40000000L, 0, 0xc0000000L), StampTool.and(StampFactory.forKind(Kind.Int), StampFactory.forConstant(Constant.forInt(0xc0000000))));
-    }
-}
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/LIRGenerator.java	Wed Aug 21 18:15:55 2013 +0200
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/LIRGenerator.java	Wed Aug 21 18:45:45 2013 +0200
@@ -367,7 +367,7 @@
     }
 
     protected void emitNode(ValueNode node) {
-        if (Debug.isLogEnabled() && node.stamp() == StampFactory.illegal()) {
+        if (Debug.isLogEnabled() && node.stamp() instanceof IllegalStamp) {
             Debug.log("This node has invalid type, we are emitting dead code(?): %s", node);
         }
         if (node instanceof LIRGenLowerable) {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.nodes.test/src/com/oracle/graal/nodes/test/IntegerStampTest.java	Wed Aug 21 18:45:45 2013 +0200
@@ -0,0 +1,183 @@
+/*
+ * 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.nodes.test;
+
+import static org.junit.Assert.*;
+
+import org.junit.*;
+
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.type.*;
+
+/**
+ * This class tests that integer stamps are created correctly for constants.
+ */
+public class IntegerStampTest {
+
+    private StructuredGraph graph;
+
+    @Before
+    public void before() {
+        graph = new StructuredGraph();
+    }
+
+    @Test
+    public void testBooleanConstant() {
+        assertEquals(new IntegerStamp(Kind.Int, 1, 1, 0x1, 0x1), ConstantNode.forBoolean(true, graph).stamp());
+        assertEquals(new IntegerStamp(Kind.Int, 0, 0, 0x0, 0x0), ConstantNode.forBoolean(false, graph).stamp());
+    }
+
+    @Test
+    public void testByteConstant() {
+        assertEquals(new IntegerStamp(Kind.Int, 0, 0, 0x0, 0x0), ConstantNode.forByte((byte) 0, graph).stamp());
+        assertEquals(new IntegerStamp(Kind.Int, 16, 16, 0x10, 0x10), ConstantNode.forByte((byte) 16, graph).stamp());
+        assertEquals(new IntegerStamp(Kind.Int, -16, -16, 0xf0, 0xf0), ConstantNode.forByte((byte) -16, graph).stamp());
+        assertEquals(new IntegerStamp(Kind.Int, 127, 127, 0x7f, 0x7f), ConstantNode.forByte((byte) 127, graph).stamp());
+        assertEquals(new IntegerStamp(Kind.Int, -128, -128, 0x80, 0x80), ConstantNode.forByte((byte) -128, graph).stamp());
+    }
+
+    @Test
+    public void testShortConstant() {
+        assertEquals(new IntegerStamp(Kind.Int, 0, 0, 0x0, 0x0), ConstantNode.forShort((short) 0, graph).stamp());
+        assertEquals(new IntegerStamp(Kind.Int, 128, 128, 0x80, 0x80), ConstantNode.forShort((short) 128, graph).stamp());
+        assertEquals(new IntegerStamp(Kind.Int, -128, -128, 0xff80, 0xff80), ConstantNode.forShort((short) -128, graph).stamp());
+        assertEquals(new IntegerStamp(Kind.Int, 32767, 32767, 0x7fff, 0x7fff), ConstantNode.forShort((short) 32767, graph).stamp());
+        assertEquals(new IntegerStamp(Kind.Int, -32768, -32768, 0x8000, 0x8000), ConstantNode.forShort((short) -32768, graph).stamp());
+    }
+
+    @Test
+    public void testCharConstant() {
+        assertEquals(new IntegerStamp(Kind.Int, 0, 0, 0x0, 0x0), ConstantNode.forChar((char) 0, graph).stamp());
+        assertEquals(new IntegerStamp(Kind.Int, 'A', 'A', 'A', 'A'), ConstantNode.forChar('A', graph).stamp());
+        assertEquals(new IntegerStamp(Kind.Int, 128, 128, 0x80, 0x80), ConstantNode.forChar((char) 128, graph).stamp());
+        assertEquals(new IntegerStamp(Kind.Int, 65535, 65535, 0xffff, 0xffff), ConstantNode.forChar((char) 65535, graph).stamp());
+    }
+
+    @Test
+    public void testIntConstant() {
+        assertEquals(new IntegerStamp(Kind.Int, 0, 0, 0x0, 0x0), ConstantNode.forInt(0, graph).stamp());
+        assertEquals(new IntegerStamp(Kind.Int, 128, 128, 0x80, 0x80), ConstantNode.forInt(128, graph).stamp());
+        assertEquals(new IntegerStamp(Kind.Int, -128, -128, 0xffffff80L, 0xffffff80L), ConstantNode.forInt(-128, graph).stamp());
+        assertEquals(new IntegerStamp(Kind.Int, Integer.MAX_VALUE, Integer.MAX_VALUE, 0x7fffffff, 0x7fffffff), ConstantNode.forInt(Integer.MAX_VALUE, graph).stamp());
+        assertEquals(new IntegerStamp(Kind.Int, Integer.MIN_VALUE, Integer.MIN_VALUE, 0x80000000L, 0x80000000L), ConstantNode.forInt(Integer.MIN_VALUE, graph).stamp());
+    }
+
+    @Test
+    public void testLongConstant() {
+        assertEquals(new IntegerStamp(Kind.Long, 0, 0, 0x0, 0x0), ConstantNode.forLong(0, graph).stamp());
+        assertEquals(new IntegerStamp(Kind.Long, 128, 128, 0x80, 0x80), ConstantNode.forLong(128, graph).stamp());
+        assertEquals(new IntegerStamp(Kind.Long, -128, -128, 0xffffffffffffff80L, 0xffffffffffffff80L), ConstantNode.forLong(-128, graph).stamp());
+        assertEquals(new IntegerStamp(Kind.Long, Long.MAX_VALUE, Long.MAX_VALUE, 0x7fffffffffffffffL, 0x7fffffffffffffffL), ConstantNode.forLong(Long.MAX_VALUE, graph).stamp());
+        assertEquals(new IntegerStamp(Kind.Long, Long.MIN_VALUE, Long.MIN_VALUE, 0x8000000000000000L, 0x8000000000000000L), ConstantNode.forLong(Long.MIN_VALUE, graph).stamp());
+    }
+
+    @Test
+    public void testPositiveRanges() {
+        assertEquals(new IntegerStamp(Kind.Int, 0, 0, 0, 0), StampFactory.forInteger(Kind.Int, 0, 0));
+        assertEquals(new IntegerStamp(Kind.Int, 0, 1, 0, 1), StampFactory.forInteger(Kind.Int, 0, 1));
+        assertEquals(new IntegerStamp(Kind.Int, 0, 0x123, 0, 0x1ff), StampFactory.forInteger(Kind.Int, 0, 0x123));
+        assertEquals(new IntegerStamp(Kind.Int, 0x120, 0x123, 0x120, 0x123), StampFactory.forInteger(Kind.Int, 0x120, 0x123));
+        assertEquals(new IntegerStamp(Kind.Int, 10000, 15000, 0x2000, 0x3fff), StampFactory.forInteger(Kind.Int, 10000, 15000));
+        assertEquals(new IntegerStamp(Kind.Long, 0, 1, 0, 1), StampFactory.forInteger(Kind.Long, 0, 1));
+        assertEquals(new IntegerStamp(Kind.Long, 10000, 15000, 0x2000, 0x3fff), StampFactory.forInteger(Kind.Long, 10000, 15000));
+        assertEquals(new IntegerStamp(Kind.Long, 140000000000L, 150000000000L, 0x2000000000L, 0x23ffffffffL), StampFactory.forInteger(Kind.Long, 140000000000L, 150000000000L));
+    }
+
+    @Test
+    public void testNegativeRanges() {
+        assertEquals(new IntegerStamp(Kind.Int, -2, -1, 0xfffffffeL, 0xffffffffL), StampFactory.forInteger(Kind.Int, -2, -1));
+        assertEquals(new IntegerStamp(Kind.Int, -20, -10, 0xffffffe0L, 0xffffffffL), StampFactory.forInteger(Kind.Int, -20, -10));
+        assertEquals(new IntegerStamp(Kind.Int, -10000, 0, 0, 0xffffffffL), StampFactory.forInteger(Kind.Int, -10000, 0));
+        assertEquals(new IntegerStamp(Kind.Int, -10000, -1, 0xffffc000L, 0xffffffffL), StampFactory.forInteger(Kind.Int, -10000, -1));
+        assertEquals(new IntegerStamp(Kind.Int, -10010, -10000, 0xffffd8e0L, 0xffffd8ffL), StampFactory.forInteger(Kind.Int, -10010, -10000));
+        assertEquals(new IntegerStamp(Kind.Long, -2, -1, 0xfffffffffffffffeL, 0xffffffffffffffffL), StampFactory.forInteger(Kind.Long, -2, -1));
+        assertEquals(new IntegerStamp(Kind.Long, -10010, -10000, 0xffffffffffffd8e0L, 0xffffffffffffd8ffL), StampFactory.forInteger(Kind.Long, -10010, -10000));
+        assertEquals(new IntegerStamp(Kind.Long, -150000000000L, -140000000000L, 0xffffffdc00000000L, 0xffffffdfffffffffL), StampFactory.forInteger(Kind.Long, -150000000000L, -140000000000L));
+    }
+
+    @Test
+    public void testMixedRanges() {
+        assertEquals(new IntegerStamp(Kind.Int, -1, 0, 0, 0xffffffffL), StampFactory.forInteger(Kind.Int, -1, 0));
+        assertEquals(new IntegerStamp(Kind.Int, -10000, 1000, 0, 0xffffffffL), StampFactory.forInteger(Kind.Int, -10000, 1000));
+        assertEquals(new IntegerStamp(Kind.Long, -10000, 1000, 0, 0xffffffffffffffffL), StampFactory.forInteger(Kind.Long, -10000, 1000));
+    }
+
+    @Test
+    public void testNarrowingConversions() {
+        // byte cases
+        assertEquals(StampFactory.forInteger(Kind.Int, 0, 0), StampTool.intToByte(StampFactory.forInteger(Kind.Int, 0, 0)));
+        assertEquals(StampFactory.forInteger(Kind.Int, 0, 10), StampTool.intToByte(StampFactory.forInteger(Kind.Int, 0, 10)));
+        assertEquals(StampFactory.forInteger(Kind.Int, 10, 20), StampTool.intToByte(StampFactory.forInteger(Kind.Int, 10, 20)));
+        assertEquals(StampFactory.forInteger(Kind.Int, -10, 0), StampTool.intToByte(StampFactory.forInteger(Kind.Int, -10, 0)));
+        assertEquals(StampFactory.forInteger(Kind.Int, -20, -10), StampTool.intToByte(StampFactory.forInteger(Kind.Int, -20, -10)));
+        assertEquals(StampFactory.forInteger(Kind.Int, Byte.MIN_VALUE, Byte.MAX_VALUE), StampTool.intToByte(StampFactory.forInteger(Kind.Int, 100, 200)));
+        assertEquals(StampFactory.forInteger(Kind.Int, Byte.MIN_VALUE, Byte.MAX_VALUE), StampTool.intToByte(StampFactory.forInteger(Kind.Int, -100, 200)));
+        assertEquals(StampFactory.forInteger(Kind.Int, Byte.MIN_VALUE, Byte.MAX_VALUE), StampTool.intToByte(StampFactory.forInteger(Kind.Int, -200, -100)));
+        // char cases
+        assertEquals(StampFactory.forInteger(Kind.Int, 0, 10), StampTool.intToChar(StampFactory.forInteger(Kind.Int, 0, 10)));
+        assertEquals(StampFactory.forInteger(Kind.Int, 10, 20), StampTool.intToChar(StampFactory.forInteger(Kind.Int, 10, 20)));
+        assertEquals(StampFactory.forInteger(Kind.Int, Character.MIN_VALUE, Character.MAX_VALUE), StampTool.intToChar(StampFactory.forInteger(Kind.Int, 20000, 80000)));
+        assertEquals(StampFactory.forInteger(Kind.Int, Character.MIN_VALUE, Character.MAX_VALUE), StampTool.intToChar(StampFactory.forInteger(Kind.Int, -10000, 40000)));
+        assertEquals(StampFactory.forInteger(Kind.Int, Character.MIN_VALUE, Character.MAX_VALUE), StampTool.intToChar(StampFactory.forInteger(Kind.Int, -40000, -10000)));
+        // short cases
+        assertEquals(StampFactory.forInteger(Kind.Int, 0, 10), StampTool.intToShort(StampFactory.forInteger(Kind.Int, 0, 10)));
+        assertEquals(StampFactory.forInteger(Kind.Int, 10, 20), StampTool.intToShort(StampFactory.forInteger(Kind.Int, 10, 20)));
+        assertEquals(StampFactory.forInteger(Kind.Int, Short.MIN_VALUE, Short.MAX_VALUE), StampTool.intToShort(StampFactory.forInteger(Kind.Int, 20000, 40000)));
+        assertEquals(StampFactory.forInteger(Kind.Int, Short.MIN_VALUE, Short.MAX_VALUE), StampTool.intToShort(StampFactory.forInteger(Kind.Int, -10000, 40000)));
+        assertEquals(StampFactory.forInteger(Kind.Int, Short.MIN_VALUE, Short.MAX_VALUE), StampTool.intToShort(StampFactory.forInteger(Kind.Int, -40000, -10000)));
+        // int cases
+        assertEquals(StampFactory.forInteger(Kind.Int, 0, 10), StampTool.longToInt(StampFactory.forInteger(Kind.Long, 0, 10)));
+        assertEquals(StampFactory.forInteger(Kind.Int, 10, 20), StampTool.longToInt(StampFactory.forInteger(Kind.Long, 10, 20)));
+        assertEquals(StampFactory.forInteger(Kind.Int, Integer.MIN_VALUE, Integer.MAX_VALUE), StampTool.longToInt(StampFactory.forInteger(Kind.Long, 20000000000L, 40000000000L)));
+        assertEquals(StampFactory.forInteger(Kind.Int, Integer.MIN_VALUE, Integer.MAX_VALUE), StampTool.longToInt(StampFactory.forInteger(Kind.Long, -10000000000L, 40000000000L)));
+        assertEquals(StampFactory.forInteger(Kind.Int, Integer.MIN_VALUE, Integer.MAX_VALUE), StampTool.longToInt(StampFactory.forInteger(Kind.Long, -40000000000L, -10000000000L)));
+    }
+
+    @Test
+    public void testXor() {
+        assertEquals(new IntegerStamp(Kind.Int, 0, 0xff, 0, 0xff), StampTool.xor(new IntegerStamp(Kind.Int, 0, 0, 0, 0), new IntegerStamp(Kind.Int, 0, 0xff, 0, 0xff)));
+        assertEquals(new IntegerStamp(Kind.Int, 0x10, 0x1f, 0x10, 0x1f), StampTool.xor(new IntegerStamp(Kind.Int, 0, 0, 0, 0), new IntegerStamp(Kind.Int, 0x10, 0x1f, 0x10, 0x1f)));
+        assertEquals(new IntegerStamp(Kind.Int, 0x0, 0xf, 0x0, 0xf), StampTool.xor(new IntegerStamp(Kind.Int, 0x10, 0x10, 0x10, 0x10), new IntegerStamp(Kind.Int, 0x10, 0x1f, 0x10, 0x1f)));
+        assertEquals(new IntegerStamp(Kind.Int, 0x10, 0x1f, 0x10, 0x1f), StampTool.xor(new IntegerStamp(Kind.Int, 0x10, 0x10, 0x10, 0x10), new IntegerStamp(Kind.Int, 0x0, 0xf, 0x0, 0xf)));
+    }
+
+    @Test
+    public void testNot() {
+        assertEquals(new IntegerStamp(Kind.Int, -11, -1, 0xfffffff0L, 0xffffffffL), StampTool.not(new IntegerStamp(Kind.Int, 0, 10, 0, 0xf)));
+    }
+
+    @Test
+    public void testAdd() {
+        assertEquals(StampFactory.forInteger(Kind.Int, 0, 30), StampTool.add(StampFactory.forInteger(Kind.Int, 0, 10), StampFactory.forInteger(Kind.Int, 0, 20)));
+        assertEquals(StampFactory.forKind(Kind.Long),
+                        StampTool.add(StampFactory.forInteger(Kind.Long, Long.MIN_VALUE, Long.MIN_VALUE + 1), StampFactory.forInteger(Kind.Long, Integer.MIN_VALUE, Integer.MAX_VALUE)));
+        assertEquals(StampFactory.forInteger(Kind.Int, -2147483647, 31 - 2147483647),
+                        StampTool.add(StampFactory.forInteger(Kind.Int, 0, 31), StampFactory.forInteger(Kind.Int, -2147483647, -2147483647)));
+    }
+
+    @Test
+    public void testAnd() {
+        assertEquals(new IntegerStamp(Kind.Int, Integer.MIN_VALUE, 0x40000000L, 0, 0xc0000000L), StampTool.and(StampFactory.forKind(Kind.Int), StampFactory.forConstant(Constant.forInt(0xc0000000))));
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.nodes.test/src/com/oracle/graal/nodes/test/ObjectStampJoinTest.java	Wed Aug 21 18:45:45 2013 +0200
@@ -0,0 +1,139 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 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.nodes.test;
+
+import org.junit.*;
+
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.compiler.test.*;
+import com.oracle.graal.nodes.type.*;
+
+public class ObjectStampJoinTest extends GraalCompilerTest {
+
+    private static class A {
+
+    }
+
+    private static class B extends A {
+
+    }
+
+    private static class C extends B implements I {
+
+    }
+
+    private static class D extends A {
+
+    }
+
+    private interface I {
+
+    }
+
+    @Test
+    public void testJoin0() {
+        Stamp a = StampFactory.declared(getType(A.class));
+        Stamp b = StampFactory.declared(getType(B.class));
+        Assert.assertEquals(b, join(a, b));
+    }
+
+    @Test
+    public void testJoin1() {
+        Stamp aNonNull = StampFactory.declaredNonNull(getType(A.class));
+        Stamp b = StampFactory.declared(getType(B.class));
+        Stamp bNonNull = StampFactory.declaredNonNull(getType(B.class));
+        Assert.assertEquals(bNonNull, join(aNonNull, b));
+    }
+
+    @Test
+    public void testJoin2() {
+        Stamp aExact = StampFactory.exactNonNull(getType(A.class));
+        Stamp b = StampFactory.declared(getType(B.class));
+        Assert.assertEquals(StampFactory.illegal(Kind.Object), join(aExact, b));
+    }
+
+    @Test
+    public void testJoin3() {
+        Stamp d = StampFactory.declared(getType(D.class));
+        Stamp c = StampFactory.declared(getType(C.class));
+        Assert.assertTrue(ObjectStamp.isObjectAlwaysNull(join(c, d)));
+    }
+
+    @Test
+    public void testJoin4() {
+        Stamp dExactNonNull = StampFactory.exactNonNull(getType(D.class));
+        Stamp c = StampFactory.declared(getType(C.class));
+        Assert.assertEquals(StampFactory.illegal(Kind.Object), join(c, dExactNonNull));
+    }
+
+    @Test
+    public void testJoin5() {
+        Stamp dExact = StampFactory.exact(getType(D.class));
+        Stamp c = StampFactory.declared(getType(C.class));
+        Assert.assertTrue(ObjectStamp.isObjectAlwaysNull(join(c, dExact)));
+    }
+
+    @Test
+    public void testJoin6() {
+        Stamp dExactNonNull = StampFactory.exactNonNull(getType(D.class));
+        Stamp allwaysNull = StampFactory.alwaysNull();
+        Stamp join = join(allwaysNull, dExactNonNull);
+        Assert.assertFalse(ObjectStamp.isObjectNonNull(join));
+        Assert.assertFalse(ObjectStamp.isObjectAlwaysNull(join));
+    }
+
+    @Test
+    public void testJoinInterface0() {
+        Stamp a = StampFactory.declared(getType(A.class));
+        Stamp b = StampFactory.declared(getType(I.class));
+        Assert.assertNotSame(StampFactory.illegal(Kind.Object), join(a, b));
+    }
+
+    @Test
+    public void testJoinInterface1() {
+        Stamp aNonNull = StampFactory.declaredNonNull(getType(A.class));
+        Stamp i = StampFactory.declared(getType(I.class));
+        Stamp join = join(aNonNull, i);
+        Assert.assertTrue(join instanceof ObjectStamp);
+        Assert.assertTrue(((ObjectStamp) join).nonNull());
+    }
+
+    @Test
+    public void testJoinInterface2() {
+        Stamp bExact = StampFactory.exactNonNull(getType(B.class));
+        Stamp i = StampFactory.declared(getType(I.class));
+        Stamp join = join(i, bExact);
+        Assert.assertEquals(StampFactory.illegal(Kind.Object), join);
+    }
+
+    private static Stamp join(Stamp a, Stamp b) {
+        Stamp ab = a.join(b);
+        Stamp ba = b.join(a);
+        Assert.assertEquals(ab, ba);
+        return ab;
+    }
+
+    private ResolvedJavaType getType(Class<?> clazz) {
+        return runtime().lookupJavaType(clazz);
+    }
+}
--- a/graal/com.oracle.graal.nodes.test/src/com/oracle/graal/nodes/test/StampTest.java	Wed Aug 21 18:15:55 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,139 +0,0 @@
-/*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 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.nodes.test;
-
-import org.junit.*;
-
-import com.oracle.graal.api.meta.*;
-import com.oracle.graal.compiler.test.*;
-import com.oracle.graal.nodes.type.*;
-
-public class StampTest extends GraalCompilerTest {
-
-    private static class A {
-
-    }
-
-    private static class B extends A {
-
-    }
-
-    private static class C extends B implements I {
-
-    }
-
-    private static class D extends A {
-
-    }
-
-    private interface I {
-
-    }
-
-    @Test
-    public void testJoin0() {
-        Stamp a = StampFactory.declared(getType(A.class));
-        Stamp b = StampFactory.declared(getType(B.class));
-        Assert.assertEquals(b, join(a, b));
-    }
-
-    @Test
-    public void testJoin1() {
-        Stamp aNonNull = StampFactory.declaredNonNull(getType(A.class));
-        Stamp b = StampFactory.declared(getType(B.class));
-        Stamp bNonNull = StampFactory.declaredNonNull(getType(B.class));
-        Assert.assertEquals(bNonNull, join(aNonNull, b));
-    }
-
-    @Test
-    public void testJoin2() {
-        Stamp aExact = StampFactory.exactNonNull(getType(A.class));
-        Stamp b = StampFactory.declared(getType(B.class));
-        Assert.assertEquals(StampFactory.illegal(), join(aExact, b));
-    }
-
-    @Test
-    public void testJoin3() {
-        Stamp d = StampFactory.declared(getType(D.class));
-        Stamp c = StampFactory.declared(getType(C.class));
-        Assert.assertTrue(ObjectStamp.isObjectAlwaysNull(join(c, d)));
-    }
-
-    @Test
-    public void testJoin4() {
-        Stamp dExactNonNull = StampFactory.exactNonNull(getType(D.class));
-        Stamp c = StampFactory.declared(getType(C.class));
-        Assert.assertEquals(StampFactory.illegal(), join(c, dExactNonNull));
-    }
-
-    @Test
-    public void testJoin5() {
-        Stamp dExact = StampFactory.exact(getType(D.class));
-        Stamp c = StampFactory.declared(getType(C.class));
-        Assert.assertTrue(ObjectStamp.isObjectAlwaysNull(join(c, dExact)));
-    }
-
-    @Test
-    public void testJoin6() {
-        Stamp dExactNonNull = StampFactory.exactNonNull(getType(D.class));
-        Stamp allwaysNull = StampFactory.alwaysNull();
-        Stamp join = join(allwaysNull, dExactNonNull);
-        Assert.assertFalse(ObjectStamp.isObjectNonNull(join));
-        Assert.assertFalse(ObjectStamp.isObjectAlwaysNull(join));
-    }
-
-    @Test
-    public void testJoinInterface0() {
-        Stamp a = StampFactory.declared(getType(A.class));
-        Stamp b = StampFactory.declared(getType(I.class));
-        Assert.assertNotSame(StampFactory.illegal(), join(a, b));
-    }
-
-    @Test
-    public void testJoinInterface1() {
-        Stamp aNonNull = StampFactory.declaredNonNull(getType(A.class));
-        Stamp i = StampFactory.declared(getType(I.class));
-        Stamp join = join(aNonNull, i);
-        Assert.assertTrue(join instanceof ObjectStamp);
-        Assert.assertTrue(((ObjectStamp) join).nonNull());
-    }
-
-    @Test
-    public void testJoinInterface2() {
-        Stamp bExact = StampFactory.exactNonNull(getType(B.class));
-        Stamp i = StampFactory.declared(getType(I.class));
-        Stamp join = join(i, bExact);
-        Assert.assertEquals(StampFactory.illegal(), join);
-    }
-
-    private static Stamp join(Stamp a, Stamp b) {
-        Stamp ab = a.join(b);
-        Stamp ba = b.join(a);
-        Assert.assertEquals(ab, ba);
-        return ab;
-    }
-
-    private ResolvedJavaType getType(Class<?> clazz) {
-        return runtime().lookupJavaType(clazz);
-    }
-}
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ConvertNode.java	Wed Aug 21 18:15:55 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ConvertNode.java	Wed Aug 21 18:45:45 2013 +0200
@@ -207,7 +207,8 @@
             if (stamp instanceof FloatStamp) {
                 return false;
             }
-            return updateStamp(StampFactory.illegal());
+            assert stamp instanceof IllegalStamp;
+            return updateStamp(stamp);
         }
         Stamp newStamp;
         IntegerStamp integerStamp = (IntegerStamp) stamp;
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IsNullNode.java	Wed Aug 21 18:15:55 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IsNullNode.java	Wed Aug 21 18:45:45 2013 +0200
@@ -55,7 +55,7 @@
     @Override
     public boolean verify() {
         assertTrue(object() != null, "is null input must not be null");
-        assertTrue(object().stamp() instanceof ObjectStamp || object().stamp() == StampFactory.illegal(), "is null input must be an object");
+        assertTrue(object().stamp() instanceof ObjectStamp || object().stamp() instanceof IllegalStamp, "is null input must be an object");
         return super.verify();
     }
 
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/CheckCastNode.java	Wed Aug 21 18:15:55 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/CheckCastNode.java	Wed Aug 21 18:45:45 2013 +0200
@@ -103,7 +103,7 @@
             stamp = ((ObjectStamp) object().stamp()).castTo((ObjectStamp) stamp);
         }
         ValueNode condition;
-        if (stamp == StampFactory.illegal()) {
+        if (stamp instanceof IllegalStamp) {
             // This is a check cast that will always fail
             condition = LogicConstantNode.contradiction(graph());
             stamp = StampFactory.declared(type);
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/InstanceOfDynamicNode.java	Wed Aug 21 18:15:55 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/InstanceOfDynamicNode.java	Wed Aug 21 18:45:45 2013 +0200
@@ -47,8 +47,8 @@
         this.mirror = mirror;
         this.object = object;
         assert mirror.kind() == Kind.Object : mirror.kind();
-        assert mirror.stamp() instanceof ObjectStamp;
-        assert ((ObjectStamp) mirror.stamp()).type().getName().equals("Ljava/lang/Class;");
+        assert ObjectStamp.isExactType(mirror);
+        assert ObjectStamp.typeOrNull(mirror).getName().equals("Ljava/lang/Class;");
     }
 
     @Override
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/FloatStamp.java	Wed Aug 21 18:15:55 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/FloatStamp.java	Wed Aug 21 18:45:45 2013 +0200
@@ -106,7 +106,7 @@
             return otherStamp.meet(this);
         }
         if (!(otherStamp instanceof FloatStamp)) {
-            return StampFactory.illegal();
+            return StampFactory.illegal(Kind.Illegal);
         }
         FloatStamp other = (FloatStamp) otherStamp;
         assert kind() == other.kind();
@@ -131,7 +131,7 @@
             return otherStamp.join(this);
         }
         if (!(otherStamp instanceof FloatStamp)) {
-            return StampFactory.illegal();
+            return StampFactory.illegal(Kind.Illegal);
         }
         FloatStamp other = (FloatStamp) otherStamp;
         assert kind() == other.kind();
@@ -143,7 +143,7 @@
         } else if (joinLowerBound == other.lowerBound && joinUpperBound == other.upperBound && joinNonNaN == other.nonNaN) {
             return other;
         } else if (joinLowerBound > joinUpperBound) {
-            return StampFactory.illegal();
+            return StampFactory.illegal(kind());
         } else {
             return new FloatStamp(kind(), joinLowerBound, joinUpperBound, joinNonNaN);
         }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/GenericStamp.java	Wed Aug 21 18:15:55 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/GenericStamp.java	Wed Aug 21 18:45:45 2013 +0200
@@ -62,7 +62,7 @@
             return other.join(this);
         }
         if (!(other instanceof GenericStamp) || ((GenericStamp) other).type != type) {
-            return StampFactory.illegal();
+            return StampFactory.illegal(Kind.Illegal);
         }
         return this;
     }
@@ -73,7 +73,7 @@
             return other.join(this);
         }
         if (!(other instanceof GenericStamp) || ((GenericStamp) other).type != type) {
-            return StampFactory.illegal();
+            return StampFactory.illegal(Kind.Illegal);
         }
         return this;
     }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/IllegalStamp.java	Wed Aug 21 18:15:55 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/IllegalStamp.java	Wed Aug 21 18:45:45 2013 +0200
@@ -24,12 +24,14 @@
 
 import com.oracle.graal.api.meta.*;
 
+/**
+ * This stamp represents the illegal type. Values with this type can not exist at run time.
+ * 
+ */
 public final class IllegalStamp extends Stamp {
 
-    public static final IllegalStamp ILLEGAL = new IllegalStamp();
-
-    private IllegalStamp() {
-        super(Kind.Illegal);
+    public IllegalStamp(Kind kind) {
+        super(kind);
     }
 
     @Override
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/IntegerStamp.java	Wed Aug 21 18:15:55 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/IntegerStamp.java	Wed Aug 21 18:45:45 2013 +0200
@@ -159,7 +159,7 @@
     private Stamp createStamp(IntegerStamp other, long newUpperBound, long newLowerBound, long newDownMask, long newUpMask) {
         assert kind() == other.kind();
         if (newLowerBound > newUpperBound || (newDownMask & (~newUpMask)) != 0) {
-            return StampFactory.illegal();
+            return StampFactory.illegal(kind());
         } else if (newLowerBound == lowerBound && newUpperBound == upperBound && newDownMask == downMask && newUpMask == upMask) {
             return this;
         } else if (newLowerBound == other.lowerBound && newUpperBound == other.upperBound && newDownMask == other.downMask && newUpMask == other.upMask) {
@@ -178,7 +178,7 @@
             return otherStamp.meet(this);
         }
         if (!(otherStamp instanceof IntegerStamp)) {
-            return StampFactory.illegal();
+            return StampFactory.illegal(Kind.Illegal);
         }
         IntegerStamp other = (IntegerStamp) otherStamp;
         return createStamp(other, Math.max(upperBound, other.upperBound), Math.min(lowerBound, other.lowerBound), downMask & other.downMask, upMask | other.upMask);
@@ -193,7 +193,7 @@
             return otherStamp.join(this);
         }
         if (!(otherStamp instanceof IntegerStamp)) {
-            return StampFactory.illegal();
+            return StampFactory.illegal(Kind.Illegal);
         }
         IntegerStamp other = (IntegerStamp) otherStamp;
         return createStamp(other, Math.min(upperBound, other.upperBound), Math.max(lowerBound, other.lowerBound), downMask | other.downMask, upMask & other.upMask);
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/ObjectStamp.java	Wed Aug 21 18:15:55 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/ObjectStamp.java	Wed Aug 21 18:45:45 2013 +0200
@@ -23,6 +23,7 @@
 package com.oracle.graal.nodes.type;
 
 import java.lang.reflect.*;
+import java.util.*;
 
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.nodes.*;
@@ -83,7 +84,7 @@
             return otherStamp.meet(this);
         }
         if (!(otherStamp instanceof ObjectStamp)) {
-            return StampFactory.illegal();
+            return StampFactory.illegal(Kind.Illegal);
         }
         ObjectStamp other = (ObjectStamp) otherStamp;
         ResolvedJavaType meetType;
@@ -121,11 +122,26 @@
         return join0(otherStamp, false);
     }
 
+    /**
+     * Returns the stamp representing the type of this stamp after a cast to the type represented by
+     * the {@code to} stamp. While this is very similar to a {@link #join} operation, in the case
+     * where both types are not obviously related, the cast operation will prefer the type of the
+     * {@code to} stamp. This is necessary as long as ObjectStamps are not able to accurately
+     * represent union types.
+     * 
+     * For example when joining the {@link RandomAccess} type with the {@link AbstractList} type,
+     * without union types, this would result in the most generic type ({@link Object}). For this
+     * reason, in some cases a {@code castTo} operation is preferable in order to keep at least the
+     * {@link AbstractList} type.
+     * 
+     * @param to the stamp this stamp should be casted to
+     * @return This stamp casted to the {@code to} stamp
+     */
     public Stamp castTo(ObjectStamp to) {
         return join0(to, true);
     }
 
-    public Stamp join0(Stamp otherStamp, boolean castToOther) {
+    private Stamp join0(Stamp otherStamp, boolean castToOther) {
         if (this == otherStamp) {
             return this;
         }
@@ -133,14 +149,14 @@
             return otherStamp.join(this);
         }
         if (!(otherStamp instanceof ObjectStamp)) {
-            return StampFactory.illegal();
+            return StampFactory.illegal(Kind.Illegal);
         }
         ObjectStamp other = (ObjectStamp) otherStamp;
         ResolvedJavaType joinType;
         boolean joinAlwaysNull = alwaysNull || other.alwaysNull;
         boolean joinNonNull = nonNull || other.nonNull;
         if (joinAlwaysNull && joinNonNull) {
-            return StampFactory.illegal();
+            return StampFactory.illegal(Kind.Object);
         }
         boolean joinExactType = exactType || other.exactType;
         if (type == other.type) {
@@ -148,7 +164,7 @@
         } else if (type == null && other.type == null) {
             joinType = null;
             if (joinExactType) {
-                return StampFactory.illegal();
+                return StampFactory.illegal(Kind.Object);
             }
         } else if (type == null) {
             joinType = other.type;
@@ -172,20 +188,18 @@
                     joinExactType = other.exactType;
                 } else {
                     joinType = null;
-                    if (joinExactType || (!type.isInterface() && !other.type.isInterface())) {
-                        joinAlwaysNull = true;
-                    }
+                }
+                if (joinExactType || (!type.isInterface() && !other.type.isInterface())) {
+                    joinAlwaysNull = true;
                 }
             }
         }
         if (joinAlwaysNull) {
             if (joinNonNull) {
-                return StampFactory.illegal();
+                return StampFactory.illegal(Kind.Object);
             }
-            joinExactType = false;
-            joinType = null;
         } else if (joinExactType && Modifier.isAbstract(joinType.getModifiers()) && !joinType.isArray()) {
-            return StampFactory.illegal();
+            return StampFactory.illegal(Kind.Object);
         }
         if (joinType == type && joinExactType == exactType && joinNonNull == nonNull && joinAlwaysNull == alwaysNull) {
             return this;
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/Stamp.java	Wed Aug 21 18:15:55 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/Stamp.java	Wed Aug 21 18:45:45 2013 +0200
@@ -47,7 +47,7 @@
     public abstract ResolvedJavaType javaType(MetaAccessProvider metaAccess);
 
     public boolean alwaysDistinct(Stamp other) {
-        return join(other) == StampFactory.illegal();
+        return join(other) instanceof IllegalStamp;
     }
 
     /**
@@ -71,7 +71,7 @@
      * If this stamp represents a single value, the methods returns this single value. It returns
      * null otherwise.
      * 
-     * @return the constant corresponding to the single value of this stamp and null if this tamp
+     * @return the constant corresponding to the single value of this stamp and null if this stamp
      *         can represent less or more than one value.
      */
     public Constant asConstant() {
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/StampFactory.java	Wed Aug 21 18:15:55 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/StampFactory.java	Wed Aug 21 18:45:45 2013 +0200
@@ -33,6 +33,7 @@
     // JaCoCo Exclude
 
     private static final Stamp[] stampCache = new Stamp[Kind.values().length];
+    private static final Stamp[] illegalStampCache = new Stamp[Kind.values().length];
     private static final Stamp objectStamp = new ObjectStamp(null, false, false, false);
     private static final Stamp objectNonNullStamp = new ObjectStamp(null, false, true, false);
     private static final Stamp objectAlwaysNullStamp = new ObjectStamp(null, false, false, true);
@@ -62,6 +63,9 @@
 
         setCache(Kind.Object, objectStamp);
         setCache(Kind.Void, voidStamp);
+        for (Kind k : Kind.values()) {
+            illegalStampCache[k.ordinal()] = new IllegalStamp(k);
+        }
     }
 
     public static Stamp forKind(Kind kind) {
@@ -113,8 +117,8 @@
         return positiveInt;
     }
 
-    public static Stamp illegal() {
-        return IllegalStamp.ILLEGAL;
+    public static Stamp illegal(Kind kind) {
+        return illegalStampCache[kind.ordinal()];
     }
 
     public static IntegerStamp forInteger(Kind kind, long lowerBound, long upperBound, long downMask, long upMask) {
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/StampTool.java	Wed Aug 21 18:15:55 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/StampTool.java	Wed Aug 21 18:45:45 2013 +0200
@@ -31,6 +31,17 @@
  */
 public class StampTool {
 
+    public static Kind joinKind(Kind a, Kind b) {
+        if (a == b) {
+            return a;
+        }
+        return Kind.Illegal;
+    }
+
+    public static Kind joinKind(Stamp a, Stamp b) {
+        return joinKind(a.kind(), b.kind());
+    }
+
     public static Stamp negate(Stamp stamp) {
         Kind kind = stamp.kind();
         if (stamp instanceof IntegerStamp) {
@@ -74,7 +85,7 @@
         if (stamp1 instanceof IntegerStamp && stamp2 instanceof IntegerStamp) {
             return add((IntegerStamp) stamp1, (IntegerStamp) stamp2);
         }
-        return StampFactory.illegal();
+        return StampFactory.illegal(joinKind(stamp1, stamp2));
     }
 
     private static long carryBits(long x, long y) {
@@ -89,7 +100,7 @@
         if (stamp1 instanceof IntegerStamp && stamp2 instanceof IntegerStamp) {
             return div((IntegerStamp) stamp1, (IntegerStamp) stamp2);
         }
-        return StampFactory.illegal();
+        return StampFactory.illegal(joinKind(stamp1, stamp2));
     }
 
     public static Stamp div(IntegerStamp stamp1, IntegerStamp stamp2) {
@@ -177,7 +188,7 @@
         if (stamp1 instanceof IntegerStamp && stamp2 instanceof IntegerStamp) {
             return and((IntegerStamp) stamp1, (IntegerStamp) stamp2);
         }
-        return StampFactory.illegal();
+        return StampFactory.illegal(joinKind(stamp1, stamp2));
     }
 
     public static Stamp and(IntegerStamp stamp1, IntegerStamp stamp2) {
@@ -189,7 +200,7 @@
         if (stamp1 instanceof IntegerStamp && stamp2 instanceof IntegerStamp) {
             return or((IntegerStamp) stamp1, (IntegerStamp) stamp2);
         }
-        return StampFactory.illegal();
+        return StampFactory.illegal(joinKind(stamp1, stamp2));
     }
 
     public static Stamp or(IntegerStamp stamp1, IntegerStamp stamp2) {
@@ -201,7 +212,7 @@
         if (stamp1 instanceof IntegerStamp && stamp2 instanceof IntegerStamp) {
             return xor((IntegerStamp) stamp1, (IntegerStamp) stamp2);
         }
-        return StampFactory.illegal();
+        return StampFactory.illegal(joinKind(stamp1, stamp2));
     }
 
     public static Stamp xor(IntegerStamp stamp1, IntegerStamp stamp2) {
@@ -216,7 +227,7 @@
         if (value instanceof IntegerStamp && shift instanceof IntegerStamp) {
             return unsignedRightShift((IntegerStamp) value, (IntegerStamp) shift);
         }
-        return StampFactory.illegal();
+        return StampFactory.illegal(value.kind());
     }
 
     public static Stamp unsignedRightShift(IntegerStamp value, IntegerStamp shift) {
@@ -245,7 +256,7 @@
         if (value instanceof IntegerStamp && shift instanceof IntegerStamp) {
             return leftShift((IntegerStamp) value, (IntegerStamp) shift);
         }
-        return StampFactory.illegal();
+        return StampFactory.illegal(value.kind());
     }
 
     public static Stamp leftShift(IntegerStamp value, IntegerStamp shift) {