changeset 6998:49f0841607b7

Merge.
author Doug Simon <doug.simon@oracle.com>
date Tue, 20 Nov 2012 22:50:44 +0100
parents b3a647ae5032 (diff) 17fd2de85bf7 (current diff)
children 679e6584c177
files src/share/vm/runtime/arguments.cpp
diffstat 13 files changed, 464 insertions(+), 108 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/CodeCacheProvider.java	Tue Nov 20 14:03:57 2012 +0100
+++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/CodeCacheProvider.java	Tue Nov 20 22:50:44 2012 +0100
@@ -22,6 +22,7 @@
  */
 package com.oracle.graal.api.code;
 
+import com.oracle.graal.api.code.CompilationResult.DataPatch;
 import com.oracle.graal.api.code.RuntimeCall.Descriptor;
 import com.oracle.graal.api.meta.*;
 
@@ -93,4 +94,11 @@
      * @return the encoded value as an integer
      */
     int encodeDeoptActionAndReason(DeoptimizationAction action, DeoptimizationReason reason);
+
+    /**
+     * Determines if a {@link DataPatch} should be created for a given {@linkplain Constant#getPrimitiveAnnotation() annotated}
+     * primitive constant that part of a {@link CompilationResult}. A data patch is always
+     * created for an object constant.
+     */
+    boolean needsDataPatch(Constant constant);
 }
--- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/CompilationResult.java	Tue Nov 20 14:03:57 2012 +0100
+++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/CompilationResult.java	Tue Nov 20 22:50:44 2012 +0100
@@ -136,10 +136,16 @@
         public final Constant constant;
         public final int alignment;
 
-        DataPatch(int pcOffset, Constant data, int alignment) {
+        /**
+         * Determines if the data is encoded inline or is loaded from a separate data area.
+         */
+        public final boolean inlined;
+
+        DataPatch(int pcOffset, Constant data, int alignment, boolean inlined) {
             super(pcOffset);
             this.constant = data;
             this.alignment = alignment;
+            this.inlined = inlined;
         }
 
         @Override
@@ -387,10 +393,11 @@
      * @param codePos the position in the code where the data reference occurs
      * @param data the data that is referenced
      * @param alignment the alignment requirement of the data or 0 if there is no alignment requirement
+     * @param inlined specifies if the data is encoded inline or is loaded from a separate data area
      */
-    public void recordDataReference(int codePos, Constant data, int alignment) {
+    public void recordDataReference(int codePos, Constant data, int alignment, boolean inlined) {
         assert codePos >= 0 && data != null;
-        getDataReferences().add(new DataPatch(codePos, data, alignment));
+        getDataReferences().add(new DataPatch(codePos, data, alignment, inlined));
     }
 
     /**
--- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/Constant.java	Tue Nov 20 14:03:57 2012 +0100
+++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/Constant.java	Tue Nov 20 22:50:44 2012 +0100
@@ -38,7 +38,7 @@
         }
     }
 
-    public static final Constant NULL_OBJECT = new Constant(Kind.Object, null);
+    public static final Constant NULL_OBJECT = new Constant(null);
     public static final Constant INT_MINUS_1 = new Constant(Kind.Int, -1);
     public static final Constant INT_0 = forInt(0);
     public static final Constant INT_1 = forInt(1);
@@ -63,7 +63,8 @@
     }
 
     /**
-     * The boxed object value. This is ignored iff {@code !kind.isObject()}.
+     * The boxed object value if {@code !kind.isObject()} otherwise the (possibly null)
+     * {@link #getPrimitiveAnnotation() annotation} for a primitive value.
      */
     private final Object object;
 
@@ -75,32 +76,48 @@
     private final long primitive;
 
     /**
-     * Create a new constant represented by the specified object reference.
-     * 
-     * @param kind the type of this constant
+     * Creates a constant represented by the specified object reference.
      * @param object the value of this constant
      */
-    private Constant(Kind kind, Object object) {
-        super(kind);
+    private Constant(Object object) {
+        super(Kind.Object);
         this.object = object;
         this.primitive = 0L;
     }
 
     /**
-     * Create a new constant represented by the specified primitive.
-     * 
+     * Creates a constant represented by the specified primitive.
+     *
      * @param kind the type of this constant
      * @param primitive the value of this constant
      */
     public Constant(Kind kind, long primitive) {
         super(kind);
+        assert !kind.isObject();
         this.object = null;
         this.primitive = primitive;
     }
 
     /**
+     * Creates an annotated primitive constant. An annotation enables a {@linkplain MetaAccessProvider provider} to
+     * associate some extra semantic or debugging information with a primitive. An annotated primitive constant
+     * is never {@linkplain #equals(Object) equal} to a non-annotated constant.
+     *
+     * @param kind the type of this constant
+     * @param primitive the value of this constant
+     * @param annotation an arbitrary non-null object
+     */
+    public Constant(Kind kind, long primitive, Object annotation) {
+        super(kind);
+        assert !kind.isObject();
+        assert annotation != null;
+        this.object = annotation;
+        this.primitive = primitive;
+    }
+
+    /**
      * Checks whether this constant is non-null.
-     * 
+     *
      * @return {@code true} if this constant is a primitive, or an object constant that is not null
      */
     public boolean isNonNull() {
@@ -109,7 +126,7 @@
 
     /**
      * Checks whether this constant is null.
-     * 
+     *
      * @return {@code true} if this constant is the null constant
      */
     public boolean isNull() {
@@ -127,12 +144,16 @@
 
     @Override
     public String toString() {
-        return getKind().getJavaName() + "[" + getKind().format(asBoxedValue()) + (getKind() != Kind.Object ? "|0x" + Long.toHexString(primitive) : "") + "]";
+        String annotationSuffix = "";
+        if (!getKind().isObject() && getPrimitiveAnnotation() != null) {
+            annotationSuffix = "{" + getPrimitiveAnnotation() + "}";
+        }
+        return getKind().getJavaName() + "[" + getKind().format(asBoxedValue()) + (getKind() != Kind.Object ? "|0x" + Long.toHexString(primitive) : "") + "]" + annotationSuffix;
     }
 
     /**
      * Returns the value of this constant as a boxed Java value.
-     * 
+     *
      * @return the value of this constant
      */
     public Object asBoxedValue() {
@@ -142,15 +163,15 @@
             case Boolean:
                 return asInt() == 0 ? Boolean.FALSE : Boolean.TRUE;
             case Short:
-                return (short) asInt();
+                return (short) primitive;
             case Char:
-                return (char) asInt();
+                return (char) primitive;
             case Jsr:
                 return (int) primitive;
             case Int:
-                return asInt();
+                return (int) primitive;
             case Long:
-                return asLong();
+                return primitive;
             case Float:
                 return asFloat();
             case Double:
@@ -169,12 +190,12 @@
         if (getKind().isObject()) {
             return object == other.object;
         }
-        return primitive == other.primitive;
+        return primitive == other.primitive && getPrimitiveAnnotation() == other.getPrimitiveAnnotation();
     }
 
     /**
      * Converts this constant to a primitive int.
-     * 
+     *
      * @return the int value of this constant
      */
     public int asInt() {
@@ -186,7 +207,7 @@
 
     /**
      * Converts this constant to a primitive boolean.
-     * 
+     *
      * @return the boolean value of this constant
      */
     public boolean asBoolean() {
@@ -198,7 +219,7 @@
 
     /**
      * Converts this constant to a primitive long.
-     * 
+     *
      * @return the long value of this constant
      */
     public long asLong() {
@@ -218,7 +239,7 @@
 
     /**
      * Converts this constant to a primitive float.
-     * 
+     *
      * @return the float value of this constant
      */
     public float asFloat() {
@@ -230,7 +251,7 @@
 
     /**
      * Converts this constant to a primitive double.
-     * 
+     *
      * @return the double value of this constant
      */
     public double asDouble() {
@@ -245,7 +266,7 @@
 
     /**
      * Converts this constant to the object reference it represents.
-     * 
+     *
      * @return the object which this constant represents
      */
     public Object asObject() {
@@ -257,7 +278,7 @@
 
     /**
      * Converts this constant to the jsr reference it represents.
-     * 
+     *
      * @return the object which this constant represents
      */
     public int asJsr() {
@@ -278,8 +299,17 @@
     }
 
     /**
+     * Gets the annotation (if any) associated with this constant.
+     *
+     * @return null if this constant is not primitive or has no annotation
+     */
+    public Object getPrimitiveAnnotation() {
+        return getKind().isObject() ? null : object;
+    }
+
+    /**
      * Computes the hashcode of this constant.
-     * 
+     *
      * @return a suitable hashcode for this constant
      */
     @Override
@@ -291,9 +321,9 @@
     }
 
     /**
-     * Checks whether this constant equals another object. This is only true if the other object is a constant and has
-     * the same value.
-     * 
+     * Checks whether this constant equals another object. This is only true if the other object is a constant that has
+     * the same {@linkplain #getKind() kind}, value and {@link #getPrimitiveAnnotation() annotation}.
+     *
      * @param o the object to compare equality
      * @return {@code true} if this constant is equivalent to the specified object
      */
@@ -304,7 +334,7 @@
 
     /**
      * Creates a boxed double constant.
-     * 
+     *
      * @param d the double value to box
      * @return a boxed copy of {@code value}
      */
@@ -320,7 +350,7 @@
 
     /**
      * Creates a boxed float constant.
-     * 
+     *
      * @param f the float value to box
      * @return a boxed copy of {@code value}
      */
@@ -339,7 +369,7 @@
 
     /**
      * Creates a boxed long constant.
-     * 
+     *
      * @param i the long value to box
      * @return a boxed copy of {@code value}
      */
@@ -349,7 +379,7 @@
 
     /**
      * Creates a boxed integer constant.
-     * 
+     *
      * @param i the integer value to box
      * @return a boxed copy of {@code value}
      */
@@ -365,7 +395,7 @@
 
     /**
      * Creates a boxed byte constant.
-     * 
+     *
      * @param i the byte value to box
      * @return a boxed copy of {@code value}
      */
@@ -375,7 +405,7 @@
 
     /**
      * Creates a boxed boolean constant.
-     * 
+     *
      * @param i the boolean value to box
      * @return a boxed copy of {@code value}
      */
@@ -385,7 +415,7 @@
 
     /**
      * Creates a boxed char constant.
-     * 
+     *
      * @param i the char value to box
      * @return a boxed copy of {@code value}
      */
@@ -395,7 +425,7 @@
 
     /**
      * Creates a boxed short constant.
-     * 
+     *
      * @param i the short value to box
      * @return a boxed copy of {@code value}
      */
@@ -405,7 +435,7 @@
 
     /**
      * Creates a boxed address (jsr/ret address) constant.
-     * 
+     *
      * @param i the address value to box
      * @return a boxed copy of {@code value}
      */
@@ -415,7 +445,7 @@
 
     /**
      * Creates a boxed object constant.
-     * 
+     *
      * @param o the object value to box
      * @return a boxed copy of {@code value}
      */
@@ -423,13 +453,13 @@
         if (o == null) {
             return NULL_OBJECT;
         }
-        return new Constant(Kind.Object, o);
+        return new Constant(o);
     }
 
     /**
      * Creates a boxed constant for the given kind from an Object. The object needs to be of the Java boxed type
      * corresponding to the kind.
-     * 
+     *
      * @param kind the kind of the constant to create
      * @param value the Java boxed value: a {@link Byte} instance for {@link Kind#Byte}, etc.
      * @return the boxed copy of {@code value}
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaType.java	Tue Nov 20 14:03:57 2012 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaType.java	Tue Nov 20 22:50:44 2012 +0100
@@ -403,8 +403,7 @@
 
     @Override
     public Constant klass() {
-        Kind wordKind = HotSpotGraalRuntime.getInstance().getTarget().wordKind;
-        return wordKind.isLong() ? Constant.forLong(metaspaceKlass) : Constant.forInt((int) metaspaceKlass);
+        return new Constant(HotSpotGraalRuntime.getInstance().getTarget().wordKind, metaspaceKlass, this);
     }
 
     public boolean isPrimaryType() {
@@ -419,12 +418,4 @@
     public long prototypeMarkWord() {
         return HotSpotGraalRuntime.getInstance().getCompilerToVM().getPrototypeMarkWord(this);
     }
-
-    public long address() {
-        return metaspaceKlass;
-    }
-
-    public String symbol() {
-        return javaMirror.getName();
-    }
 }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java	Tue Nov 20 14:03:57 2012 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java	Tue Nov 20 22:50:44 2012 +0100
@@ -733,4 +733,8 @@
             default: throw GraalInternalError.shouldNotReachHere();
         }
     }
+
+    public boolean needsDataPatch(Constant constant) {
+        return constant.getPrimitiveAnnotation() instanceof HotSpotResolvedJavaType;
+    }
 }
--- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java	Tue Nov 20 14:03:57 2012 +0100
+++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java	Tue Nov 20 22:50:44 2012 +0100
@@ -79,7 +79,6 @@
     private ProfilingInfo profilingInfo;
 
     private BytecodeStream stream;           // the bytecode stream
-    private final LogStream log;
 
     private FrameStateBuilder frameState;          // the current execution state
     private Block currentBlock;
@@ -113,7 +112,6 @@
         this.graphBuilderConfig = graphBuilderConfig;
         this.optimisticOpts = optimisticOpts;
         this.runtime = runtime;
-        this.log = GraalOptions.TraceBytecodeParserLevel > 0 ? new LogStream(TTY.out()) : null;
         assert runtime != null;
     }
 
@@ -131,7 +129,12 @@
         methodSynchronizedObject = null;
         this.currentGraph = graph;
         this.frameState = new FrameStateBuilder(method, graph, graphBuilderConfig.eagerResolving());
-        build();
+        TTY.Filter filter = new TTY.Filter(GraalOptions.PrintFilter, method);
+        try {
+            build();
+        } finally {
+            filter.remove();
+        }
     }
 
     @Override
@@ -148,11 +151,6 @@
     }
 
     private void build() {
-        if (log != null) {
-            log.println();
-            log.println("Compiling " + method);
-        }
-
         if (GraalOptions.PrintProfilingInformation) {
             TTY.println("Profiling info for " + method);
             TTY.println(MetaUtil.indent(MetaUtil.profileToString(profilingInfo, method, CodeUtil.NEW_LINE), "  "));
@@ -1533,14 +1531,14 @@
 
     private void traceState() {
         if (GraalOptions.TraceBytecodeParserLevel >= TRACELEVEL_STATE && !TTY.isSuppressed()) {
-            log.println(String.format("|   state [nr locals = %d, stack depth = %d, method = %s]", frameState.localsSize(), frameState.stackSize(), method));
+            TTY.println(String.format("|   state [nr locals = %d, stack depth = %d, method = %s]", frameState.localsSize(), frameState.stackSize(), method));
             for (int i = 0; i < frameState.localsSize(); ++i) {
                 ValueNode value = frameState.localAt(i);
-                log.println(String.format("|   local[%d] = %-8s : %s", i, value == null ? "bogus" : value.kind().getJavaName(), value));
+                TTY.println(String.format("|   local[%d] = %-8s : %s", i, value == null ? "bogus" : value.kind().getJavaName(), value));
             }
             for (int i = 0; i < frameState.stackSize(); ++i) {
                 ValueNode value = frameState.stackAt(i);
-                log.println(String.format("|   stack[%d] = %-8s : %s", i, value == null ? "bogus" : value.kind().getJavaName(), value));
+                TTY.println(String.format("|   stack[%d] = %-8s : %s", i, value == null ? "bogus" : value.kind().getJavaName(), value));
             }
         }
     }
@@ -1774,7 +1772,7 @@
             if (!currentBlock.jsrScope.isEmpty()) {
                 sb.append(' ').append(currentBlock.jsrScope);
             }
-            log.println(sb.toString());
+            TTY.println(sb.toString());
         }
     }
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/hotspot/Test6823354.java	Tue Nov 20 22:50:44 2012 +0100
@@ -0,0 +1,268 @@
+/*
+ * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.jtt.hotspot;
+
+/**
+ * @test
+ * @bug 6823354
+ * @summary These methods can be instrinsified by using bit scan, bit test, and population count instructions.
+ *
+ * @run main/othervm -Xcomp -XX:CompileOnly=Test6823354.lzcomp,Test6823354.tzcomp,.dolzcomp,.dotzcomp Test6823354
+ */
+
+import java.net.*;
+
+// Checkstyle: stop
+public class Test6823354 {
+    // Arrays of corner case values.
+    static final int[]  ia = new int[]  { 0,  1,  -1,  Integer.MIN_VALUE, Integer.MAX_VALUE };
+    static final long[] la = new long[] { 0L, 1L, -1L, Long.MIN_VALUE,    Long.MAX_VALUE    };
+
+    public static void main(String[] args) throws Exception {
+        // Load the classes and the methods.
+        Integer.numberOfLeadingZeros(0);
+        Integer.numberOfTrailingZeros(0);
+        Long.numberOfLeadingZeros(0);
+        Long.numberOfTrailingZeros(0);
+
+        lz();
+        tz();
+    }
+
+    static void lz() throws Exception {
+        // int
+
+        // Test corner cases.
+        for (int i = 0; i < ia.length; i++) {
+            int x = ia[i];
+            check(x, lzcomp(x), lzint(x));
+        }
+
+        // Test all possible return values.
+        for (int i = 0; i < Integer.SIZE; i++) {
+            int x = 1 << i;
+            check(x, lzcomp(x), lzint(x));
+        }
+
+        String classname = Test6823354.class.getName() + "$lzconI";
+
+        // Test Ideal optimizations (constant values).
+        for (int i = 0; i < ia.length; i++) {
+            testclass(classname, ia[i]);
+        }
+
+        // Test Ideal optimizations (constant values).
+        for (int i = 0; i < Integer.SIZE; i++) {
+            int x = 1 << i;
+            testclass(classname, x);
+        }
+
+
+        // long
+
+        // Test corner cases.
+        for (int i = 0; i < ia.length; i++) {
+            long x = la[i];
+            check(x, lzcomp(x), lzint(x));
+        }
+
+        // Test all possible return values.
+        for (int i = 0; i < Long.SIZE; i++) {
+            long x = 1L << i;
+            check(x, lzcomp(x), lzint(x));
+        }
+
+        classname = Test6823354.class.getName() + "$lzconL";
+
+        // Test Ideal optimizations (constant values).
+        for (int i = 0; i < la.length; i++) {
+            testclass(classname, la[i]);
+        }
+
+        // Test Ideal optimizations (constant values).
+        for (int i = 0; i < Long.SIZE; i++) {
+            long x = 1L << i;
+            testclass(classname, x);
+        }
+    }
+
+    static void tz() throws Exception {
+        // int
+
+        // Test corner cases.
+        for (int i = 0; i < ia.length; i++) {
+            int x = ia[i];
+            check(x, tzcomp(x), tzint(x));
+        }
+
+        // Test all possible return values.
+        for (int i = 0; i < Integer.SIZE; i++) {
+            int x = 1 << i;
+            check(x, tzcomp(x), tzint(x));
+        }
+
+        String classname = Test6823354.class.getName() + "$tzconI";
+
+        // Test Ideal optimizations (constant values).
+        for (int i = 0; i < ia.length; i++) {
+            testclass(classname, ia[i]);
+        }
+
+        // Test Ideal optimizations (constant values).
+        for (int i = 0; i < Integer.SIZE; i++) {
+            int x = 1 << i;
+            testclass(classname, x);
+        }
+
+
+        // long
+
+        // Test corner cases.
+        for (int i = 0; i < la.length; i++) {
+            long x = la[i];
+            check(x, tzcomp(x), tzint(x));
+        }
+
+        // Test all possible return values.
+        for (int i = 0; i < Long.SIZE; i++) {
+            long x = 1L << i;
+            check(x, tzcomp(x), tzint(x));
+        }
+
+        classname = Test6823354.class.getName() + "$tzconL";
+
+        // Test Ideal optimizations (constant values).
+        for (int i = 0; i < la.length; i++) {
+            testclass(classname, la[i]);
+        }
+
+        // Test Ideal optimizations (constant values).
+        for (int i = 0; i < Long.SIZE; i++) {
+            long x = 1L << i;
+            testclass(classname, x);
+        }
+    }
+
+    static void check(int value, int result, int expected) {
+        //System.out.println(value + ": " + result + ", " + expected);
+        if (result != expected)
+            throw new InternalError(value + " failed: " + result + " != " + expected);
+    }
+
+    static void check(long value, long result, long expected) {
+        //System.out.println(value + ": " + result + ", " + expected);
+        if (result != expected)
+            throw new InternalError(value + " failed: " + result + " != " + expected);
+    }
+
+    static int lzint( int i)  { return Integer.numberOfLeadingZeros(i); }
+    static int lzcomp(int i)  { return Integer.numberOfLeadingZeros(i); }
+
+    static int lzint( long l) { return Long.numberOfLeadingZeros(l); }
+    static int lzcomp(long l) { return Long.numberOfLeadingZeros(l); }
+
+    static int tzint( int i)  { return Integer.numberOfTrailingZeros(i); }
+    static int tzcomp(int i)  { return Integer.numberOfTrailingZeros(i); }
+
+    static int tzint( long l) { return Long.numberOfTrailingZeros(l); }
+    static int tzcomp(long l) { return Long.numberOfTrailingZeros(l); }
+
+    static void testclass(String classname, int x) throws Exception {
+        System.setProperty("value", "" + x);
+        loadandrunclass(classname);
+    }
+
+    static void testclass(String classname, long x) throws Exception {
+        System.setProperty("value", "" + x);
+        loadandrunclass(classname);
+    }
+
+    static void loadandrunclass(String classname) throws Exception {
+        Class cl = Class.forName(classname);
+        URLClassLoader apploader = (URLClassLoader) cl.getClassLoader();
+        ClassLoader loader = new URLClassLoader(apploader.getURLs(), apploader.getParent());
+        Class c = loader.loadClass(classname);
+        Runnable r = (Runnable) c.newInstance();
+        r.run();
+    }
+
+    public static class lzconI implements Runnable {
+        static final int VALUE;
+
+        static {
+            int value = 0;
+            try {
+                value = Integer.decode(System.getProperty("value"));
+            } catch (Throwable e) {}
+            VALUE = value;
+        }
+
+        public void run() { check(VALUE, lzint(VALUE), dolzcomp()); }
+        static int dolzcomp() { return lzcomp(VALUE); }
+    }
+
+    public static class lzconL implements Runnable {
+        static final long VALUE;
+
+        static {
+            long value = 0;
+            try {
+                value = Long.decode(System.getProperty("value"));
+            } catch (Throwable e) {}
+            VALUE = value;
+        }
+
+        public void run() { check(VALUE, lzint(VALUE), dolzcomp()); }
+        static int dolzcomp() { return lzcomp(VALUE); }
+    }
+
+    public static class tzconI implements Runnable {
+        static final int VALUE;
+
+        static {
+            int value = 0;
+            try {
+                value = Integer.decode(System.getProperty("value"));
+            } catch (Throwable e) {}
+            VALUE = value;
+        }
+
+        public void run() { check(VALUE, tzint(VALUE), dotzcomp()); }
+        static int dotzcomp() { return tzcomp(VALUE); }
+    }
+
+    public static class tzconL implements Runnable {
+        static final long VALUE;
+
+        static {
+            long value = 0;
+            try {
+                value = Long.decode(System.getProperty("value"));
+            } catch (Throwable e) {}
+            VALUE = value;
+        }
+
+        public void run() { check(VALUE, tzint(VALUE), dotzcomp()); }
+        static int dotzcomp() { return tzcomp(VALUE); }
+    }
+}
--- a/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64ControlFlow.java	Tue Nov 20 14:03:57 2012 +0100
+++ b/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64ControlFlow.java	Tue Nov 20 22:50:44 2012 +0100
@@ -155,7 +155,12 @@
             if (key.getKind() == Kind.Int) {
                 Register intKey = asIntReg(key);
                 for (int i = 0; i < keyConstants.length; i++) {
-                    masm.cmpl(intKey, tasm.asIntConst(keyConstants[i]));
+                    if (tasm.runtime.needsDataPatch(keyConstants[i])) {
+                        tasm.recordDataReferenceInCode(keyConstants[i], 0, true);
+                    }
+                    long lc = keyConstants[i].asLong();
+                    assert NumUtil.isInt(lc);
+                    masm.cmpl(intKey, (int) lc);
                     masm.jcc(ConditionFlag.equal, keyTargets[i].label());
                 }
             } else if (key.getKind() == Kind.Long) {
--- a/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Move.java	Tue Nov 20 14:03:57 2012 +0100
+++ b/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Move.java	Tue Nov 20 22:50:44 2012 +0100
@@ -296,12 +296,19 @@
         switch (input.getKind().getStackKind()) {
             case Jsr:
             case Int:
+                if (tasm.runtime.needsDataPatch(input)) {
+                    tasm.recordDataReferenceInCode(input, 0, true);
+                }
                 // Do not optimize with an XOR as this instruction may be between
                 // a CMP and a Jcc in which case the XOR will modify the condition
                 // flags and interfere with the Jcc.
-                masm.movl(asRegister(result), tasm.asIntConst(input));
+                masm.movl(asRegister(result), input.asInt());
+
                 break;
             case Long:
+                if (tasm.runtime.needsDataPatch(input)) {
+                    tasm.recordDataReferenceInCode(input, 0, true);
+                }
                 // Do not optimize with an XOR as this instruction may be between
                 // a CMP and a Jcc in which case the XOR will modify the condition
                 // flags and interfere with the Jcc.
@@ -310,6 +317,7 @@
             case Float:
                 // This is *not* the same as 'constant == 0.0f' in the case where constant is -0.0f
                 if (Float.floatToRawIntBits(input.asFloat()) == Float.floatToRawIntBits(0.0f)) {
+                    assert !tasm.runtime.needsDataPatch(input);
                     masm.xorps(asFloatReg(result), asFloatReg(result));
                 } else {
                     masm.movflt(asFloatReg(result), tasm.asFloatConstRef(input));
@@ -318,6 +326,7 @@
             case Double:
                 // This is *not* the same as 'constant == 0.0d' in the case where constant is -0.0d
                 if (Double.doubleToRawLongBits(input.asDouble()) == Double.doubleToRawLongBits(0.0d)) {
+                    assert !tasm.runtime.needsDataPatch(input);
                     masm.xorpd(asDoubleReg(result), asDoubleReg(result));
                 } else {
                     masm.movdbl(asDoubleReg(result), tasm.asDoubleConstRef(input));
@@ -330,10 +339,10 @@
                 if (input.isNull()) {
                     masm.movq(asRegister(result), 0x0L);
                 } else if (tasm.target.inlineObjects) {
-                    tasm.recordDataReferenceInCode(input, 0);
+                    tasm.recordDataReferenceInCode(input, 0, true);
                     masm.movq(asRegister(result), 0xDEADDEADDEADDEADL);
                 } else {
-                    masm.movq(asRegister(result), tasm.recordDataReferenceInCode(input, 0));
+                    masm.movq(asRegister(result), tasm.recordDataReferenceInCode(input, 0, false));
                 }
                 break;
             default:
@@ -342,6 +351,7 @@
     }
 
     private static void const2stack(TargetMethodAssembler tasm, AMD64MacroAssembler masm, Value result, Constant input) {
+        assert !tasm.runtime.needsDataPatch(input);
         switch (input.getKind().getStackKind()) {
             case Jsr:
             case Int:    masm.movl(tasm.asAddress(result), input.asInt()); break;
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/asm/TargetMethodAssembler.java	Tue Nov 20 14:03:57 2012 +0100
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/asm/TargetMethodAssembler.java	Tue Nov 20 22:50:44 2012 +0100
@@ -163,11 +163,11 @@
         targetMethod.recordSafepoint(pos, debugInfo);
     }
 
-    public Address recordDataReferenceInCode(Constant data, int alignment) {
+    public Address recordDataReferenceInCode(Constant data, int alignment, boolean inlined) {
         assert data != null;
         int pos = asm.codeBuffer.position();
         Debug.log("Data reference in code: pos = %d, data = %s", pos, data.toString());
-        targetMethod.recordDataReference(pos, data, alignment);
+        targetMethod.recordDataReference(pos, data, alignment, inlined);
         return Address.Placeholder;
     }
 
@@ -175,15 +175,16 @@
         return lastSafepointPos;
     }
 
-
     /**
-     * Returns the integer value of any constants that can be represented by a 32-bit integer value,
+     * Returns the integer value of any constant that can be represented by a 32-bit integer value,
      * including long constants that fit into the 32-bit range.
      */
     public int asIntConst(Value value) {
         assert (value.getKind().getStackKind() == Kind.Int || value.getKind() == Kind.Jsr || value.getKind() == Kind.Long) && isConstant(value);
-        long c = ((Constant) value).asLong();
-        if (!(NumUtil.isInt(c))) {
+        Constant constant = (Constant) value;
+        assert !runtime.needsDataPatch(constant) : constant + " should be in a DataPatch";
+        long c = constant.asLong();
+        if (!NumUtil.isInt(c)) {
             throw GraalInternalError.shouldNotReachHere();
         }
         return (int) c;
@@ -198,7 +199,7 @@
 
     public Address asFloatConstRef(Value value, int alignment) {
         assert value.getKind() == Kind.Float && isConstant(value);
-        return recordDataReferenceInCode((Constant) value, alignment);
+        return recordDataReferenceInCode((Constant) value, alignment, false);
     }
 
     /**
@@ -210,7 +211,7 @@
 
     public Address asDoubleConstRef(Value value, int alignment) {
         assert value.getKind() == Kind.Double && isConstant(value);
-        return recordDataReferenceInCode((Constant) value, alignment);
+        return recordDataReferenceInCode((Constant) value, alignment, false);
     }
 
     /**
@@ -218,7 +219,7 @@
      */
     public Address asLongConstRef(Value value) {
         assert value.getKind() == Kind.Long && isConstant(value);
-        return recordDataReferenceInCode((Constant) value, 8);
+        return recordDataReferenceInCode((Constant) value, 8, false);
     }
 
     public Address asIntAddr(Value value) {
--- a/src/share/vm/graal/graalCodeInstaller.cpp	Tue Nov 20 14:03:57 2012 +0100
+++ b/src/share/vm/graal/graalCodeInstaller.cpp	Tue Nov 20 22:50:44 2012 +0100
@@ -102,7 +102,28 @@
   return map;
 }
 
-static ScopeValue* get_hotspot_value(oop value, int total_frame_size, GrowableArray<ScopeValue*>* objects, ScopeValue* &second) {
+// Records any Metadata values embedded in a Constant (e.g., the value returned by HotSpotResolvedJavaType.klass()).
+static void record_metadata_in_constant(oop constant, OopRecorder* oop_recorder) {
+  char kind = Kind::typeChar(Constant::kind(constant));
+  char wordKind = 'j';
+  if (kind == wordKind) {
+    oop obj = Constant::object(constant);
+    jlong prim = Constant::primitive(constant);
+    if (obj != NULL) {
+      if (obj->is_a(HotSpotResolvedJavaType::klass())) {
+        Klass* klass = (Klass*) (address) HotSpotResolvedJavaType::metaspaceKlass(obj);
+        assert((Klass*) prim == klass, err_msg("%s @ %p != %p", klass->name()->as_C_string(), klass, prim));
+        int index = oop_recorder->find_index(klass);
+        TRACE_graal_3("metadata[%d of %d] = %s", index, oop_recorder->metadata_count(), klass->name()->as_C_string());
+      } else {
+        assert(java_lang_String::is_instance(obj),
+            err_msg("unexpected annotation type (%s) for constant %ld (%p) of kind %c", obj->klass()->name()->as_C_string(), prim, prim, kind));
+      }
+    }
+  }
+}
+
+static ScopeValue* get_hotspot_value(oop value, int total_frame_size, GrowableArray<ScopeValue*>* objects, ScopeValue* &second, OopRecorder* oop_recorder) {
   second = NULL;
   if (value == Value::ILLEGAL()) {
     return new LocationValue(Location::new_stk_loc(Location::invalid, 0));
@@ -157,7 +178,7 @@
     }
     return value;
   } else if (value->is_a(Constant::klass())){
-    oop obj = Constant::object(value);
+    record_metadata_in_constant(value, oop_recorder);
     jlong prim = Constant::primitive(value);
     if (type == T_INT || type == T_FLOAT || type == T_SHORT || type == T_CHAR || type == T_BOOLEAN || type == T_BYTE) {
       return new ConstantIntValue(*(jint*)&prim);
@@ -195,7 +216,7 @@
     arrayOop values = (arrayOop) VirtualObject::values(value);
     for (jint i = 0; i < values->length(); i++) {
       ScopeValue* cur_second = NULL;
-      ScopeValue* value = get_hotspot_value(((oop*) values->base(T_OBJECT))[i], total_frame_size, objects, cur_second);
+      ScopeValue* value = get_hotspot_value(((oop*) values->base(T_OBJECT))[i], total_frame_size, objects, cur_second, oop_recorder);
       
       if (isLongArray && cur_second == NULL) {
         // we're trying to put ints into a long array... this isn't really valid, but it's used for some optimizations.
@@ -222,14 +243,14 @@
   return NULL;
 }
 
-static MonitorValue* get_monitor_value(oop value, int total_frame_size, GrowableArray<ScopeValue*>* objects) {
+static MonitorValue* get_monitor_value(oop value, int total_frame_size, GrowableArray<ScopeValue*>* objects, OopRecorder* oop_recorder) {
   guarantee(value->is_a(code_MonitorValue::klass()), "Monitors must be of type MonitorValue");
 
   ScopeValue* second = NULL;
-  ScopeValue* owner_value = get_hotspot_value(code_MonitorValue::owner(value), total_frame_size, objects, second);
+  ScopeValue* owner_value = get_hotspot_value(code_MonitorValue::owner(value), total_frame_size, objects, second, oop_recorder);
   assert(second == NULL, "monitor cannot occupy two stack slots");
 
-  ScopeValue* lock_data_value = get_hotspot_value(code_MonitorValue::lockData(value), total_frame_size, objects, second);
+  ScopeValue* lock_data_value = get_hotspot_value(code_MonitorValue::lockData(value), total_frame_size, objects, second, oop_recorder);
   assert(second == lock_data_value, "monitor is LONG value that occupies two stack slots");
   assert(lock_data_value->is_location(), "invalid monitor location");
   Location lock_data_loc = ((LocationValue*)lock_data_value)->location();
@@ -482,19 +503,19 @@
     oop value = ((oop*) values->base(T_OBJECT))[i];
 
     if (i < local_count) {
-      ScopeValue* first = get_hotspot_value(value, _total_frame_size, objects, second);
+      ScopeValue* first = get_hotspot_value(value, _total_frame_size, objects, second, _oop_recorder);
       if (second != NULL) {
         locals->append(second);
       }
       locals->append(first);
     } else if (i < local_count + expression_count) {
-      ScopeValue* first = get_hotspot_value(value, _total_frame_size, objects, second);
+      ScopeValue* first = get_hotspot_value(value, _total_frame_size, objects, second, _oop_recorder);
       if (second != NULL) {
         expressions->append(second);
       }
       expressions->append(first);
     } else {
-      monitors->append(get_monitor_value(value, _total_frame_size, objects));
+      monitors->append(get_monitor_value(value, _total_frame_size, objects, _oop_recorder));
     }
     if (second != NULL) {
       i++;
@@ -601,7 +622,7 @@
       jump->set_jump_destination(VmIds::getStub(global_stub));
       _instructions->relocate((address)inst, runtime_call_Relocation::spec(), Assembler::call32_operand);
     }
-    TRACE_graal_3("relocating (stub)  at %016x", inst);
+    TRACE_graal_3("relocating (stub)  at %p", inst);
   } else { // method != NULL
     assert(hotspot_method != NULL, "unexpected JavaMethod");
     assert(debug_info != NULL, "debug info expected");
@@ -659,6 +680,7 @@
 void CodeInstaller::site_DataPatch(CodeBuffer& buffer, jint pc_offset, oop site) {
   oop constant = CompilationResult_DataPatch::constant(site);
   int alignment = CompilationResult_DataPatch::alignment(site);
+  bool inlined = CompilationResult_DataPatch::inlined(site);
   oop kind = Constant::kind(constant);
 
   address instruction = _instructions->start() + pc_offset;
@@ -675,24 +697,30 @@
     case 'f':
     case 'j':
     case 'd': {
-      address operand = Assembler::locate_operand(instruction, Assembler::disp32_operand);
-      address next_instruction = Assembler::locate_next_instruction(instruction);
-      int size = _constants->size();
-      if (alignment > 0) {
-        guarantee(alignment <= _constants->alignment(), "Alignment inside constants section is restricted by alignment of section begin");
-        size = align_size_up(size, alignment);
+      record_metadata_in_constant(constant, _oop_recorder);
+      if (inlined) {
+        address operand = Assembler::locate_operand(instruction, Assembler::imm_operand);
+        *((jlong*) operand) = Constant::primitive(constant);
+      } else {
+        address operand = Assembler::locate_operand(instruction, Assembler::disp32_operand);
+        address next_instruction = Assembler::locate_next_instruction(instruction);
+        int size = _constants->size();
+        if (alignment > 0) {
+          guarantee(alignment <= _constants->alignment(), "Alignment inside constants section is restricted by alignment of section begin");
+          size = align_size_up(size, alignment);
+        }
+        // we don't care if this is a long/double/etc., the primitive field contains the right bits
+        address dest = _constants->start() + size;
+        _constants->set_end(dest + BytesPerLong);
+        *(jlong*) dest = Constant::primitive(constant);
+
+        long disp = dest - next_instruction;
+        assert(disp == (jint) disp, "disp doesn't fit in 32 bits");
+        *((jint*) operand) = (jint) disp;
+
+        _instructions->relocate(instruction, section_word_Relocation::spec((address) dest, CodeBuffer::SECT_CONSTS), Assembler::disp32_operand);
+        TRACE_graal_3("relocating (%c) at %p/%p with destination at %p (%d)", typeChar, instruction, operand, dest, size);
       }
-      // we don't care if this is a long/double/etc., the primitive field contains the right bits
-      address dest = _constants->start() + size;
-      _constants->set_end(dest + BytesPerLong);
-      *(jlong*) dest = Constant::primitive(constant);
-
-      long disp = dest - next_instruction;
-      assert(disp == (jint) disp, "disp doesn't fit in 32 bits");
-      *((jint*) operand) = (jint) disp;
-
-      _instructions->relocate(instruction, section_word_Relocation::spec((address) dest, CodeBuffer::SECT_CONSTS), Assembler::disp32_operand);
-      TRACE_graal_3("relocating (%c) at %016x/%016x with destination at %016x (%d)", typeChar, instruction, operand, dest, size);
       break;
     }
     case 'a': {
@@ -702,11 +730,11 @@
       jobject value = JNIHandles::make_local(obj());
       *((jobject*) operand) = value;
       _instructions->relocate(instruction, oop_Relocation::spec_for_immediate(), Assembler::imm_operand);
-      TRACE_graal_3("relocating (oop constant) at %016x/%016x", instruction, operand);
+      TRACE_graal_3("relocating (oop constant) at %p/%p", instruction, operand);
       break;
     }
     default:
-      fatal("unexpected Kind in DataPatch");
+      fatal(err_msg("unexpected Kind (%d) in DataPatch", typeChar));
       break;
   }
 }
--- a/src/share/vm/graal/graalJavaAccess.hpp	Tue Nov 20 14:03:57 2012 +0100
+++ b/src/share/vm/graal/graalJavaAccess.hpp	Tue Nov 20 22:50:44 2012 +0100
@@ -127,6 +127,7 @@
   start_class(CompilationResult_DataPatch)                                                                                                                     \
     oop_field(CompilationResult_DataPatch, constant, "Lcom/oracle/graal/api/meta/Constant;")                                                                   \
     int_field(CompilationResult_DataPatch, alignment)                                                                                                          \
+    boolean_field(CompilationResult_DataPatch, inlined)                                                                                                           \
   end_class                                                                                                                                                    \
   start_class(CompilationResult_Safepoint)                                                                                                                     \
     oop_field(CompilationResult_Safepoint, debugInfo, "Lcom/oracle/graal/api/code/DebugInfo;")                                                                 \
--- a/src/share/vm/runtime/arguments.cpp	Tue Nov 20 14:03:57 2012 +0100
+++ b/src/share/vm/runtime/arguments.cpp	Tue Nov 20 22:50:44 2012 +0100
@@ -2035,6 +2035,11 @@
                     "CompressedOops are not supported in Graal at the moment\n");
         status = false;
   }
+  if (UseCompressedKlassPointers) {
+    jio_fprintf(defaultStream::error_stream(),
+                    "UseCompressedKlassPointers are not supported in Graal at the moment\n");
+        status = false;
+  }
   if (UseG1GC) {
     jio_fprintf(defaultStream::error_stream(),
                         "G1 is not supported in Graal at the moment\n");