changeset 9896:5945a36ccba4

Merge
author Christos Kotselidis <christos.kotselidis@oracle.com>
date Wed, 05 Jun 2013 15:11:58 +0200
parents ab85c49630e2 (diff) 7779b1d5ba37 (current diff)
children 65e23a65de9d
files graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64LIRGenerator.java graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerator.java graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotRegisterConfig.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/NewObjectSnippets.java graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Move.java make/build-graal.xml
diffstat 16 files changed, 797 insertions(+), 117 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64LIRGenerator.java	Wed Jun 05 14:18:35 2013 +0200
+++ b/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64LIRGenerator.java	Wed Jun 05 15:11:58 2013 +0200
@@ -59,18 +59,13 @@
 import com.oracle.graal.lir.amd64.AMD64ControlFlow.SequentialSwitchOp;
 import com.oracle.graal.lir.amd64.AMD64ControlFlow.SwitchRangesOp;
 import com.oracle.graal.lir.amd64.AMD64ControlFlow.TableSwitchOp;
-import com.oracle.graal.lir.amd64.AMD64Move.CompareAndSwapOp;
 import com.oracle.graal.lir.amd64.AMD64Move.LeaOp;
-import com.oracle.graal.lir.amd64.AMD64Move.LoadOp;
 import com.oracle.graal.lir.amd64.AMD64Move.MembarOp;
 import com.oracle.graal.lir.amd64.AMD64Move.MoveFromRegOp;
 import com.oracle.graal.lir.amd64.AMD64Move.MoveToRegOp;
 import com.oracle.graal.lir.amd64.AMD64Move.StackLeaOp;
-import com.oracle.graal.lir.amd64.AMD64Move.StoreConstantOp;
-import com.oracle.graal.lir.amd64.AMD64Move.StoreOp;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.calc.*;
-import com.oracle.graal.nodes.java.*;
 import com.oracle.graal.phases.util.*;
 
 /**
@@ -215,31 +210,6 @@
     }
 
     @Override
-    public Variable emitLoad(Kind kind, Value address, DeoptimizingNode deopting) {
-        AMD64AddressValue loadAddress = asAddressValue(address);
-        Variable result = newVariable(kind);
-        append(new LoadOp(kind, result, loadAddress, deopting != null ? state(deopting) : null));
-        return result;
-    }
-
-    @Override
-    public void emitStore(Kind kind, Value address, Value inputVal, DeoptimizingNode deopting) {
-        AMD64AddressValue storeAddress = asAddressValue(address);
-        LIRFrameState state = deopting != null ? state(deopting) : null;
-
-        if (isConstant(inputVal)) {
-            Constant c = asConstant(inputVal);
-            if (canStoreConstant(c)) {
-                append(new StoreConstantOp(kind, storeAddress, c, state));
-                return;
-            }
-        }
-
-        Variable input = load(inputVal);
-        append(new StoreOp(kind, storeAddress, input, state));
-    }
-
-    @Override
     public Variable emitAddress(StackSlot address) {
         Variable result = newVariable(target().wordKind);
         append(new StackLeaOp(result, address));
@@ -882,34 +852,6 @@
     }
 
     @Override
-    public void visitCompareAndSwap(CompareAndSwapNode node) {
-        Kind kind = node.newValue().kind();
-        assert kind == node.expected().kind();
-
-        Value expected = loadNonConst(operand(node.expected()));
-        Variable newValue = load(operand(node.newValue()));
-
-        AMD64AddressValue address;
-        int displacement = node.displacement();
-        Value index = operand(node.offset());
-        if (isConstant(index) && NumUtil.isInt(asConstant(index).asLong() + displacement)) {
-            assert !runtime.needsDataPatch(asConstant(index));
-            displacement += (int) asConstant(index).asLong();
-            address = new AMD64AddressValue(kind, load(operand(node.object())), displacement);
-        } else {
-            address = new AMD64AddressValue(kind, load(operand(node.object())), load(index), Scale.Times1, displacement);
-        }
-
-        RegisterValue rax = AMD64.rax.asValue(kind);
-        emitMove(rax, expected);
-        append(new CompareAndSwapOp(rax, address, rax, newValue));
-
-        Variable result = newVariable(node.kind());
-        append(new CondMoveOp(result, Condition.EQ, load(Constant.TRUE), Constant.FALSE));
-        setResult(node, result);
-    }
-
-    @Override
     public void visitBreakpointNode(BreakpointNode node) {
         JavaType[] sig = new JavaType[node.arguments().size()];
         for (int i = 0; i < sig.length; i++) {
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerator.java	Wed Jun 05 14:18:35 2013 +0200
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerator.java	Wed Jun 05 15:11:58 2013 +0200
@@ -45,9 +45,18 @@
 import com.oracle.graal.lir.StandardOp.ParametersOp;
 import com.oracle.graal.lir.StandardOp.PlaceholderOp;
 import com.oracle.graal.lir.amd64.*;
+import com.oracle.graal.lir.amd64.AMD64ControlFlow.CondMoveOp;
+import com.oracle.graal.lir.amd64.AMD64Move.CompareAndSwapCompressedOp;
 import com.oracle.graal.lir.amd64.AMD64Move.CompareAndSwapOp;
+import com.oracle.graal.lir.amd64.AMD64Move.LoadCompressedOop;
+import com.oracle.graal.lir.amd64.AMD64Move.LoadOp;
 import com.oracle.graal.lir.amd64.AMD64Move.MoveFromRegOp;
+import com.oracle.graal.lir.amd64.AMD64Move.StoreCompressedOop;
+import com.oracle.graal.lir.amd64.AMD64Move.StoreConstantOp;
+import com.oracle.graal.lir.amd64.AMD64Move.StoreOp;
 import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.calc.*;
+import com.oracle.graal.nodes.java.*;
 import com.oracle.graal.nodes.java.MethodCallTargetNode.InvokeKind;
 
 /**
@@ -390,4 +399,78 @@
             op.savedRbp = savedRbp;
         }
     }
+
+    private static boolean isCompressCandidate(DeoptimizingNode access) {
+        return access != null && ((HeapAccess) access).compress();
+    }
+
+    @Override
+    public Variable emitLoad(Kind kind, Value address, DeoptimizingNode access) {
+        AMD64AddressValue loadAddress = asAddressValue(address);
+        Variable result = newVariable(kind);
+        assert access == null || access instanceof HeapAccess;
+        if (runtime().config.useCompressedOops && isCompressCandidate(access)) {
+            assert kind == Kind.Object;
+            Variable scratch = newVariable(Kind.Long);
+            append(new LoadCompressedOop(kind, result, scratch, loadAddress, access != null ? state(access) : null, runtime().config.narrowOopBase, runtime().config.narrowOopShift,
+                            runtime().config.logMinObjAlignment));
+        } else {
+            append(new LoadOp(kind, result, loadAddress, access != null ? state(access) : null));
+        }
+        return result;
+    }
+
+    @Override
+    public void emitStore(Kind kind, Value address, Value inputVal, DeoptimizingNode access) {
+        AMD64AddressValue storeAddress = asAddressValue(address);
+        LIRFrameState state = access != null ? state(access) : null;
+        if (isConstant(inputVal)) {
+            Constant c = asConstant(inputVal);
+            if (canStoreConstant(c)) {
+                append(new StoreConstantOp(kind, storeAddress, c, state, runtime().config.useCompressedOops && isCompressCandidate(access)));
+                return;
+            }
+        }
+        Variable input = load(inputVal);
+        if (runtime().config.useCompressedOops && isCompressCandidate(access)) {
+            assert kind == Kind.Object;
+            Variable scratch = newVariable(Kind.Long);
+            append(new StoreCompressedOop(kind, storeAddress, input, scratch, state, runtime().config.narrowOopBase, runtime().config.narrowOopShift, runtime().config.logMinObjAlignment));
+        } else {
+            append(new StoreOp(kind, storeAddress, input, state));
+        }
+    }
+
+    @Override
+    public void visitCompareAndSwap(CompareAndSwapNode node) {
+        Kind kind = node.newValue().kind();
+        assert kind == node.expected().kind();
+
+        Value expected = loadNonConst(operand(node.expected()));
+        Variable newValue = load(operand(node.newValue()));
+
+        AMD64AddressValue address;
+        int displacement = node.displacement();
+        Value index = operand(node.offset());
+        if (isConstant(index) && NumUtil.isInt(asConstant(index).asLong() + displacement)) {
+            assert !runtime.needsDataPatch(asConstant(index));
+            displacement += (int) asConstant(index).asLong();
+            address = new AMD64AddressValue(kind, load(operand(node.object())), displacement);
+        } else {
+            address = new AMD64AddressValue(kind, load(operand(node.object())), load(index), Scale.Times1, displacement);
+        }
+
+        RegisterValue raxRes = AMD64.rax.asValue(kind);
+        emitMove(raxRes, expected);
+        if (runtime().config.useCompressedOops && node.compress()) {
+            assert kind == Kind.Object;
+            Variable scratch = newVariable(Kind.Long);
+            append(new CompareAndSwapCompressedOp(raxRes, address, raxRes, newValue, scratch, runtime().config.narrowOopBase, runtime().config.narrowOopShift, runtime().config.logMinObjAlignment));
+        } else {
+            append(new CompareAndSwapOp(raxRes, address, raxRes, newValue));
+        }
+        Variable result = newVariable(node.kind());
+        append(new CondMoveOp(result, Condition.EQ, load(Constant.TRUE), Constant.FALSE));
+        setResult(node, result);
+    }
 }
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotRegisterConfig.java	Wed Jun 05 14:18:35 2013 +0200
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotRegisterConfig.java	Wed Jun 05 15:11:58 2013 +0200
@@ -38,7 +38,7 @@
 
     private final Architecture architecture;
 
-    private final Register[] allocatable = initAllocatable();
+    private final Register[] allocatable;
 
     private final HashMap<PlatformKind, Register[]> categorized = new HashMap<>();
 
@@ -86,25 +86,34 @@
         throw new IllegalArgumentException("register " + name + " is not allocatable");
     }
 
-    private static Register[] initAllocatable() {
+    private static Register[] initAllocatable(boolean reserveForHeapBase) {
+        Register[] registers = null;
         // @formatter:off
-        Register[] allocatable = {
+        if (reserveForHeapBase) {
+            registers = new Register[] {
+                        rax, rbx, rcx, rdx, /*rsp,*/ rbp, rsi, rdi, r8, r9,  r10, r11, /*r12,*/ r13, r14, /*r15, */
+                        xmm0, xmm1, xmm2,  xmm3,  xmm4,  xmm5,  xmm6,  xmm7,
+                        xmm8, xmm9, xmm10, xmm11, xmm12, xmm13, xmm14, xmm15
+                      };
+        } else {
+            registers = new Register[] {
                         rax, rbx, rcx, rdx, /*rsp,*/ rbp, rsi, rdi, r8, r9,  r10, r11, r12, r13, r14, /*r15, */
                         xmm0, xmm1, xmm2,  xmm3,  xmm4,  xmm5,  xmm6,  xmm7,
                         xmm8, xmm9, xmm10, xmm11, xmm12, xmm13, xmm14, xmm15
-                    };
-        // @formatter:on
+                      };
+        }
+       // @formatter:on
 
         if (RegisterPressure.getValue() != null) {
             String[] names = RegisterPressure.getValue().split(",");
             Register[] regs = new Register[names.length];
             for (int i = 0; i < names.length; i++) {
-                regs[i] = findRegister(names[i], allocatable);
+                regs[i] = findRegister(names[i], registers);
             }
             return regs;
         }
 
-        return allocatable;
+        return registers;
     }
 
     public AMD64HotSpotRegisterConfig(Architecture architecture, HotSpotVMConfig config) {
@@ -119,6 +128,7 @@
         }
 
         csl = null;
+        allocatable = initAllocatable(config.useCompressedOops);
         attributesMap = RegisterAttributes.createMap(this, AMD64.allRegisters);
     }
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/CompressedOopTest.java	Wed Jun 05 15:11:58 2013 +0200
@@ -0,0 +1,421 @@
+/*
+ * 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.hotspot.test;
+
+import java.lang.reflect.*;
+import java.util.*;
+import java.util.concurrent.atomic.*;
+
+import org.junit.*;
+
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.api.runtime.*;
+import com.oracle.graal.compiler.test.*;
+import com.oracle.graal.hotspot.meta.*;
+
+/**
+ * The following tests perform object/array equality and assignments in various ways. The selected
+ * cases have been the problematic ones while implementing the Compressed Oops support.
+ */
+
+public class CompressedOopTest extends GraalCompilerTest {
+
+    private final MetaAccessProvider metaAccessProvider;
+    Object[] argsToBind;
+
+    public CompressedOopTest() {
+        this.metaAccessProvider = Graal.getRequiredCapability(MetaAccessProvider.class);
+    }
+
+    @Test
+    public void test() throws NoSuchMethodException, SecurityException, InvalidInstalledCodeException {
+        final Method fooMethod = CompressedOopTest.class.getMethod("fieldTest", Object.class, Object.class, Object.class);
+        final HotSpotResolvedJavaMethod fooJavaMethod = (HotSpotResolvedJavaMethod) metaAccessProvider.lookupJavaMethod(fooMethod);
+        final HotSpotInstalledCode fooCode = (HotSpotInstalledCode) getCode(fooJavaMethod, parse(fooMethod));
+        argsToBind = new Object[]{fooCode};
+        final Method benchmarkMethod = CompressedOopTest.class.getMethod("benchmark", HotSpotInstalledCode.class, Object.class, Object.class, Object.class);
+        final ResolvedJavaMethod benchmarkJavaMethod = metaAccessProvider.lookupJavaMethod(benchmarkMethod);
+        final HotSpotInstalledCode installedBenchmarkCode = (HotSpotInstalledCode) getCode(benchmarkJavaMethod, parse(benchmarkMethod));
+        Container c1 = new Container();
+        Assert.assertEquals(c1.b, installedBenchmarkCode.executeVarargs(argsToBind[0], c1, c1, c1));
+    }
+
+    @Test
+    public void test1() throws NoSuchMethodException, SecurityException, InvalidInstalledCodeException {
+        final Method fooMethod = CompressedOopTest.class.getMethod("arrayTest", Object.class, Object.class, Object.class);
+        final HotSpotResolvedJavaMethod fooJavaMethod = (HotSpotResolvedJavaMethod) metaAccessProvider.lookupJavaMethod(fooMethod);
+        final HotSpotInstalledCode fooCode = (HotSpotInstalledCode) getCode(fooJavaMethod, parse(fooMethod));
+        argsToBind = new Object[]{fooCode};
+        final Method benchmarkMethod = CompressedOopTest.class.getMethod("benchmark", HotSpotInstalledCode.class, Object.class, Object.class, Object.class);
+        final ResolvedJavaMethod benchmarkJavaMethod = metaAccessProvider.lookupJavaMethod(benchmarkMethod);
+        final HotSpotInstalledCode installedBenchmarkCode = (HotSpotInstalledCode) getCode(benchmarkJavaMethod, parse(benchmarkMethod));
+        ArrayContainer ac = new ArrayContainer();
+        Assert.assertEquals(ac.a[9], installedBenchmarkCode.executeVarargs(argsToBind[0], ac.a, 0, 9));
+        Assert.assertEquals(ac.a[8], installedBenchmarkCode.executeVarargs(argsToBind[0], ac.a, 1, 8));
+        Assert.assertEquals(ac.a[7], installedBenchmarkCode.executeVarargs(argsToBind[0], ac.a, 2, 7));
+        Assert.assertEquals(ac.a[6], installedBenchmarkCode.executeVarargs(argsToBind[0], ac.a, 3, 6));
+        Assert.assertEquals(ac.a[5], installedBenchmarkCode.executeVarargs(argsToBind[0], ac.a, 4, 5));
+        Assert.assertEquals(ac.a[4], installedBenchmarkCode.executeVarargs(argsToBind[0], ac.a, 5, 4));
+        Assert.assertEquals(ac.a[3], installedBenchmarkCode.executeVarargs(argsToBind[0], ac.a, 6, 3));
+        Assert.assertEquals(ac.a[2], installedBenchmarkCode.executeVarargs(argsToBind[0], ac.a, 7, 2));
+        Assert.assertEquals(ac.a[1], installedBenchmarkCode.executeVarargs(argsToBind[0], ac.a, 8, 1));
+        Assert.assertEquals(ac.a[0], installedBenchmarkCode.executeVarargs(argsToBind[0], ac.a, 9, 0));
+    }
+
+    @Test
+    public void test2() throws NoSuchMethodException, SecurityException, InvalidInstalledCodeException {
+        final Method fooMethod = CompressedOopTest.class.getMethod("arrayCopyTest", Object.class, Object.class, Object.class);
+        final HotSpotResolvedJavaMethod fooJavaMethod = (HotSpotResolvedJavaMethod) metaAccessProvider.lookupJavaMethod(fooMethod);
+        final HotSpotInstalledCode fooCode = (HotSpotInstalledCode) getCode(fooJavaMethod, parse(fooMethod));
+        argsToBind = new Object[]{fooCode};
+        ArrayContainer source = new ArrayContainer();
+        ArrayContainer destination = new ArrayContainer();
+        Assert.assertEquals(source.a.length, destination.a.length);
+        Assert.assertFalse(Arrays.equals(source.a, destination.a));
+        fooCode.execute(source.a, destination.a, source.a);
+        Assert.assertArrayEquals(source.a, destination.a);
+    }
+
+    @Test
+    public void test3() throws NoSuchMethodException, SecurityException, InvalidInstalledCodeException {
+        final Method fooMethod = CompressedOopTest.class.getMethod("compareAndSwapTest", Object.class, Object.class, Object.class);
+        final HotSpotResolvedJavaMethod fooJavaMethod = (HotSpotResolvedJavaMethod) metaAccessProvider.lookupJavaMethod(fooMethod);
+        final HotSpotInstalledCode fooCode = (HotSpotInstalledCode) getCode(fooJavaMethod, parse(fooMethod));
+        argsToBind = new Object[]{fooCode};
+        Object initial = new Object();
+        Object replacement = new Object();
+        AtomicReference<Object> cas = new AtomicReference<>();
+        Assert.assertEquals(cas.get(), null);
+        fooCode.execute(cas, null, initial);
+        Assert.assertEquals(cas.get(), initial);
+        fooCode.execute(cas, initial, replacement);
+        Assert.assertEquals(cas.get(), replacement);
+    }
+
+    @Test
+    public void test4() throws NoSuchMethodException, SecurityException, InvalidInstalledCodeException {
+        final Method fooMethod = CompressedOopTest.class.getMethod("charArrayCopyTest", Object.class, Object.class, Object.class);
+        final HotSpotResolvedJavaMethod fooJavaMethod = (HotSpotResolvedJavaMethod) metaAccessProvider.lookupJavaMethod(fooMethod);
+        final HotSpotInstalledCode fooCode = (HotSpotInstalledCode) getCode(fooJavaMethod, parse(fooMethod));
+        argsToBind = new Object[]{fooCode};
+        StringContainer1 source1 = new StringContainer1();
+        StringContainer2 source2 = new StringContainer2();
+        char[] result = new char[source1.value.length + source2.value.length];
+        fooCode.execute(source1.value, source2.value, result);
+        Assert.assertArrayEquals(new char[]{'T', 'e', 's', 't', ' ', 'S', 't', 'r', 'i', 'n', 'g'}, result);
+    }
+
+    @Test
+    public void test5() throws NoSuchMethodException, SecurityException, InvalidInstalledCodeException {
+        final Method fooMethod = CompressedOopTest.class.getMethod("charContainerArrayCopyTest", Object.class, Object.class, Object.class);
+        final HotSpotResolvedJavaMethod fooJavaMethod = (HotSpotResolvedJavaMethod) metaAccessProvider.lookupJavaMethod(fooMethod);
+        final HotSpotInstalledCode fooCode = (HotSpotInstalledCode) getCode(fooJavaMethod, parse(fooMethod));
+        argsToBind = new Object[]{fooCode};
+        StringContainer1 source1 = new StringContainer1();
+        StringContainer2 source2 = new StringContainer2();
+        char[] result = new char[source1.value.length + source2.value.length];
+        fooCode.execute(source1, source2, result);
+        Assert.assertArrayEquals(new char[]{'T', 'e', 's', 't', ' ', 'S', 't', 'r', 'i', 'n', 'g'}, result);
+    }
+
+    @Test
+    public void test6() throws NoSuchMethodException, SecurityException, InvalidInstalledCodeException {
+        final Method fooMethod = CompressedOopTest.class.getMethod("stringCopyTest", Object.class, Object.class, Object.class);
+        final HotSpotResolvedJavaMethod fooJavaMethod = (HotSpotResolvedJavaMethod) metaAccessProvider.lookupJavaMethod(fooMethod);
+        final HotSpotInstalledCode fooCode = (HotSpotInstalledCode) getCode(fooJavaMethod, parse(fooMethod));
+        argsToBind = new Object[]{fooCode};
+        String a = new String("Test ");
+        String b = new String("String");
+        String c = (String) fooCode.execute(a, b, null);
+        Assert.assertTrue(c.equals("Test String"));
+    }
+
+    @Test
+    public void test7() throws NoSuchMethodException, SecurityException, InvalidInstalledCodeException {
+        final Method fooMethod = CompressedOopTest.class.getMethod("queueTest", Object.class, Object.class, Object.class);
+        final HotSpotResolvedJavaMethod fooJavaMethod = (HotSpotResolvedJavaMethod) metaAccessProvider.lookupJavaMethod(fooMethod);
+        final HotSpotInstalledCode fooCode = (HotSpotInstalledCode) getCode(fooJavaMethod, parse(fooMethod));
+        argsToBind = new Object[]{fooCode};
+        ArrayDeque<Object> q = new ArrayDeque<>();
+        Object[] objects = new Object[512];
+        for (int i = 0; i < objects.length; i++) {
+            objects[i] = new Object();
+        }
+
+        int j = 0;
+        while (j < objects.length) {
+            fooCode.execute(q, objects[j], null);
+            j++;
+        }
+
+        System.gc();
+        Assert.assertTrue(q.size() == objects.length);
+        Assert.assertTrue(!q.isEmpty());
+
+        j = 0;
+        while (j < objects.length) {
+            Assert.assertTrue(objects[j] == q.remove());
+            j++;
+        }
+
+        Assert.assertTrue(q.size() == 0);
+        Assert.assertTrue(q.isEmpty());
+    }
+
+    @Test
+    public void test8() throws NoSuchMethodException, SecurityException, InvalidInstalledCodeException {
+        final Method fooMethod = CompressedOopTest.class.getMethod("unmodListTest", Object.class, Object.class, Object.class);
+        final HotSpotResolvedJavaMethod fooJavaMethod = (HotSpotResolvedJavaMethod) metaAccessProvider.lookupJavaMethod(fooMethod);
+        final HotSpotInstalledCode fooCode = (HotSpotInstalledCode) getCode(fooJavaMethod, parse(fooMethod));
+        argsToBind = new Object[]{fooCode};
+        List<Object> list = new ArrayList<>();
+        for (int i = 0; i < 512; i++) {
+            list.add(new Object());
+        }
+
+        Object[] array = (Object[]) fooCode.execute(list, null, null);
+        Assert.assertTrue(list.size() == array.length);
+        int i = 0;
+        for (Object obj : list) {
+            Assert.assertTrue(obj == array[i]);
+            i++;
+        }
+    }
+
+    @Test
+    public void test9() throws NoSuchMethodException, SecurityException, InvalidInstalledCodeException {
+        final Method fooMethod = CompressedOopTest.class.getMethod("unmodListTest", Object.class, Object.class, Object.class);
+        final HotSpotResolvedJavaMethod fooJavaMethod = (HotSpotResolvedJavaMethod) metaAccessProvider.lookupJavaMethod(fooMethod);
+        final HotSpotInstalledCode fooCode = (HotSpotInstalledCode) getCode(fooJavaMethod, parse(fooMethod));
+        argsToBind = new Object[]{fooCode};
+        List<Object> list = new ArrayList<>();
+        Object[] array = (Object[]) fooCode.execute(list, null, null);
+        Assert.assertTrue(list.size() == array.length);
+    }
+
+    public void test10() throws NoSuchMethodException, SecurityException, InvalidInstalledCodeException {
+        final Method fooMethod = CompressedOopTest.class.getMethod("constantTest", Object.class, Object.class, Object.class);
+        final HotSpotResolvedJavaMethod fooJavaMethod = (HotSpotResolvedJavaMethod) metaAccessProvider.lookupJavaMethod(fooMethod);
+        final HotSpotInstalledCode fooCode = (HotSpotInstalledCode) getCode(fooJavaMethod, parse(fooMethod));
+        argsToBind = new Object[]{fooCode};
+        Container c = new Container();
+        Assert.assertFalse((boolean) fooCode.execute(c, null, null));
+    }
+
+    @Test
+    public void test11() throws NoSuchMethodException, SecurityException, InvalidInstalledCodeException {
+        final Method fooMethod = CompressedOopTest.class.getMethod("stringEqualsTest", String.class, String.class, Object.class);
+        final HotSpotResolvedJavaMethod fooJavaMethod = (HotSpotResolvedJavaMethod) metaAccessProvider.lookupJavaMethod(fooMethod);
+        final HotSpotInstalledCode fooCode = (HotSpotInstalledCode) getCode(fooJavaMethod, parse(fooMethod));
+        argsToBind = new Object[]{fooCode};
+        String s1 = new String("Test");
+        String s2 = new String("Test");
+        boolean result = ((Boolean) (fooCode.execute(s1, s2, null))).booleanValue();
+        Assert.assertTrue(result);
+    }
+
+    @Test
+    public void test12() throws NoSuchMethodException, SecurityException, InvalidInstalledCodeException {
+        final Method fooMethod = CompressedOopTest.class.getMethod("stringConstantEqualsTest", String.class, String.class, Object.class);
+        final HotSpotResolvedJavaMethod fooJavaMethod = (HotSpotResolvedJavaMethod) metaAccessProvider.lookupJavaMethod(fooMethod);
+        final HotSpotInstalledCode fooCode = (HotSpotInstalledCode) getCode(fooJavaMethod, parse(fooMethod));
+        argsToBind = new Object[]{fooCode};
+        String s1 = new String("Test");
+        boolean result = ((Boolean) (fooCode.execute(s1, null, null))).booleanValue();
+        Assert.assertTrue(result);
+    }
+
+    public static Object benchmark(HotSpotInstalledCode code, Object o1, Object o2, Object o3) throws InvalidInstalledCodeException {
+        return code.execute(o1, o2, o3);
+    }
+
+    public static Object fieldTest(Object c1, @SuppressWarnings("unused") Object c2, @SuppressWarnings("unused") Object c3) {
+        ((Container) c1).a = ((Container) c1).b;
+        return ((Container) c1).a;
+    }
+
+    public static Object arrayTest(Object c1, Object c2, Object c3) {
+        Object[] array = (Object[]) c1;
+        int initialIndex = ((Integer) c2).intValue();
+        int replacingIndex = ((Integer) c3).intValue();
+        array[initialIndex] = array[replacingIndex];
+        return array[initialIndex];
+    }
+
+    public static void arrayCopyTest(Object c1, Object c2, @SuppressWarnings("unused") Object c3) {
+        Object[] source = (Object[]) c1;
+        Object[] destination = (Object[]) c2;
+        System.arraycopy(source, 0, destination, 0, source.length);
+    }
+
+    public static String stringCopyTest(Object c1, Object c2, @SuppressWarnings("unused") Object c3) {
+        String source = (String) c1;
+        String destination = (String) c2;
+        return source + destination;
+    }
+
+    public static char[] charArrayCopyTest(Object c1, Object c2, Object c3) {
+        char[] source1 = (char[]) c1;
+        char[] source2 = (char[]) c2;
+        char[] result = (char[]) c3;
+
+        for (int i = 0; i < source1.length; i++) {
+            result[i] = source1[i];
+        }
+
+        for (int i = 0; i < source2.length; i++) {
+            result[source1.length + i] = source2[i];
+        }
+        return result;
+    }
+
+    public static char[] charContainerArrayCopyTest(Object c1, Object c2, Object c3) {
+        char[] source1 = ((StringContainer1) c1).value;
+        char[] source2 = ((StringContainer2) c2).value;
+        char[] result = (char[]) c3;
+
+        for (int i = 0; i < source1.length; i++) {
+            result[i] = source1[i];
+        }
+
+        for (int i = 0; i < source2.length; i++) {
+            result[source1.length + i] = source2[i];
+        }
+        return result;
+    }
+
+    public static void compareAndSwapTest(Object c1, Object c2, Object c3) {
+        @SuppressWarnings("unchecked")
+        AtomicReference<Object> cas = (AtomicReference<Object>) c1;
+        cas.compareAndSet(c2, c3);
+    }
+
+    @SuppressWarnings("unchecked")
+    public static HashMap<Object, Object> hashMapCloneTest(Object c1, @SuppressWarnings("unused") Object c2, @SuppressWarnings("unused") Object c3) {
+        HashMap<Object, Object> map = (HashMap<Object, Object>) c1;
+        return (HashMap<Object, Object>) map.clone();
+    }
+
+    @SuppressWarnings("unchecked")
+    public static void hashMapCopyTest(Object c1, Object c2, @SuppressWarnings("unused") Object c3) {
+        HashMap<Object, Object> map = (HashMap<Object, Object>) c1;
+        HashMap<Object, Object> map1 = (HashMap<Object, Object>) c2;
+        map.clear();
+        map.putAll(map1);
+    }
+
+    @SuppressWarnings("unchecked")
+    public static void queueTest(Object c1, Object c2, @SuppressWarnings("unused") Object c3) {
+        ArrayDeque<Object> queue = (ArrayDeque<Object>) c1;
+        queue.add(c2);
+    }
+
+    @SuppressWarnings("unchecked")
+    public static Object[] unmodListTest(Object c1, @SuppressWarnings("unused") Object c2, @SuppressWarnings("unused") Object c3) {
+        List<Object> queue = (ArrayList<Object>) c1;
+        Object[] result = Collections.unmodifiableCollection(queue).toArray(new Object[queue.size()]);
+        return result;
+    }
+
+    public static Boolean constantTest(Object c1, @SuppressWarnings("unused") Object c2, @SuppressWarnings("unused") Object c3) {
+        ConstantContainer container = (ConstantContainer) c1;
+        return container.a.equals(container.b);
+    }
+
+    public static Boolean stringEqualsTest(String c1, String c2, @SuppressWarnings("unused") Object c3) {
+        return c1.equals(c2);
+    }
+
+    public static Boolean stringConstantEqualsTest(String c1, @SuppressWarnings("unused") String c2, @SuppressWarnings("unused") Object c3) {
+        return "Test".equals(c1);
+    }
+
+}
+
+class Container {
+
+    public Object a = new Object();
+    public Object b = new Object();
+}
+
+class ArrayContainer {
+
+    public Object[] a = new Object[10];
+
+    public ArrayContainer() {
+        for (int i = 0; i < 10; i++) {
+            a[i] = new Object();
+        }
+    }
+}
+
+class HashMapContainer {
+
+    public HashMap<Object, Object> a = new HashMap<>();
+
+    public HashMapContainer() {
+        for (int i = 0; i < 10; i++) {
+            a.put(new Object(), new Object());
+        }
+    }
+}
+
+class StringContainer1 {
+
+    public char[] value = new char[5];
+
+    public StringContainer1() {
+        value[0] = 'T';
+        value[1] = 'e';
+        value[2] = 's';
+        value[3] = 't';
+        value[4] = ' ';
+
+    }
+}
+
+class StringContainer2 {
+
+    public char[] value = new char[6];
+
+    public StringContainer2() {
+        value[0] = 'S';
+        value[1] = 't';
+        value[2] = 'r';
+        value[3] = 'i';
+        value[4] = 'n';
+        value[5] = 'g';
+    }
+}
+
+class ConstantContainer {
+
+    public final Object a = new Object();
+    public final Object b = new Object();
+
+    public ConstantContainer() {
+
+    }
+}
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConfig.java	Wed Jun 05 14:18:35 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConfig.java	Wed Jun 05 15:11:58 2013 +0200
@@ -50,6 +50,13 @@
     public boolean useAESIntrinsics;
     public boolean useG1GC;
 
+    // Compressed Oops related values.
+    public boolean useCompressedOops;
+    public boolean useCompressedKlassPointers;
+    public long narrowOopBase;
+    public int narrowOopShift;
+    public int logMinObjAlignment;
+
     // CPU capabilities
     public int useSSE;
     public int useAVX;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java	Wed Jun 05 14:18:35 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java	Wed Jun 05 15:11:58 2013 +0200
@@ -529,7 +529,8 @@
             HotSpotResolvedJavaField field = (HotSpotResolvedJavaField) loadField.field();
             ValueNode object = loadField.isStatic() ? ConstantNode.forObject(field.getDeclaringClass().mirror(), this, graph) : loadField.object();
             assert loadField.kind() != Kind.Illegal;
-            ReadNode memoryRead = graph.add(new ReadNode(object, createFieldLocation(graph, field), loadField.stamp(), WriteBarrierType.NONE, false));
+            ReadNode memoryRead = graph.add(new ReadNode(object, createFieldLocation(graph, field), loadField.stamp(), WriteBarrierType.NONE,
+                            (loadField.kind() == Kind.Object && !field.getName().equals("classMirrorOffset"))));
             tool.createNullCheckGuard(memoryRead, object);
 
             graph.replaceFixedWithFixed(loadField, memoryRead);
@@ -545,7 +546,7 @@
             HotSpotResolvedJavaField field = (HotSpotResolvedJavaField) storeField.field();
             ValueNode object = storeField.isStatic() ? ConstantNode.forObject(field.getDeclaringClass().mirror(), this, graph) : storeField.object();
             WriteBarrierType barrierType = getFieldStoreBarrierType(storeField);
-            WriteNode memoryWrite = graph.add(new WriteNode(object, storeField.value(), createFieldLocation(graph, field), barrierType, false));
+            WriteNode memoryWrite = graph.add(new WriteNode(object, storeField.value(), createFieldLocation(graph, field), barrierType, storeField.field().getKind() == Kind.Object));
             tool.createNullCheckGuard(memoryWrite, object);
             memoryWrite.setStateAfter(storeField.stateAfter());
             graph.replaceFixedWithFixed(storeField, memoryWrite);
@@ -564,12 +565,15 @@
             LocationNode location = IndexedLocationNode.create(ANY_LOCATION, cas.expected().kind(), cas.displacement(), cas.offset(), graph, 1);
             cas.setLocation(location);
             cas.setWriteBarrierType(getCompareAndSwapBarrier(cas));
+            if (cas.expected().kind() == Kind.Object) {
+                cas.setCompress();
+            }
         } else if (n instanceof LoadIndexedNode) {
             LoadIndexedNode loadIndexed = (LoadIndexedNode) n;
             GuardingNode boundsCheck = createBoundsCheck(loadIndexed, tool);
             Kind elementKind = loadIndexed.elementKind();
             LocationNode arrayLocation = createArrayLocation(graph, elementKind, loadIndexed.index());
-            ReadNode memoryRead = graph.add(new ReadNode(loadIndexed.array(), arrayLocation, loadIndexed.stamp(), WriteBarrierType.NONE, false));
+            ReadNode memoryRead = graph.add(new ReadNode(loadIndexed.array(), arrayLocation, loadIndexed.stamp(), WriteBarrierType.NONE, elementKind == Kind.Object));
             memoryRead.setGuard(boundsCheck);
             graph.replaceFixedWithFixed(loadIndexed, memoryRead);
         } else if (n instanceof StoreIndexedNode) {
@@ -600,7 +604,7 @@
                 }
             }
             WriteBarrierType barrierType = getArrayStoreBarrierType(storeIndexed);
-            WriteNode memoryWrite = graph.add(new WriteNode(array, value, arrayLocation, barrierType, false));
+            WriteNode memoryWrite = graph.add(new WriteNode(array, value, arrayLocation, barrierType, elementKind == Kind.Object));
             memoryWrite.setGuard(boundsCheck);
             memoryWrite.setStateAfter(storeIndexed.stateAfter());
             graph.replaceFixedWithFixed(storeIndexed, memoryWrite);
@@ -609,7 +613,7 @@
             UnsafeLoadNode load = (UnsafeLoadNode) n;
             assert load.kind() != Kind.Illegal;
             IndexedLocationNode location = IndexedLocationNode.create(ANY_LOCATION, load.accessKind(), load.displacement(), load.offset(), graph, 1);
-            ReadNode memoryRead = graph.add(new ReadNode(load.object(), location, load.stamp(), WriteBarrierType.NONE, false));
+            ReadNode memoryRead = graph.add(new ReadNode(load.object(), location, load.stamp(), WriteBarrierType.NONE, (!load.object().isNullConstant() && load.accessKind() == Kind.Object)));
             // An unsafe read must not floating outside its block as may float above an explicit
             // null check on its object.
             memoryRead.setGuard(AbstractBeginNode.prevBegin(load));
@@ -619,7 +623,7 @@
             IndexedLocationNode location = IndexedLocationNode.create(ANY_LOCATION, store.accessKind(), store.displacement(), store.offset(), graph, 1);
             ValueNode object = store.object();
             WriteBarrierType barrierType = getUnsafeStoreBarrierType(store);
-            WriteNode write = graph.add(new WriteNode(object, store.value(), location, barrierType, false));
+            WriteNode write = graph.add(new WriteNode(object, store.value(), location, barrierType, store.value().kind() == Kind.Object));
             write.setStateAfter(store.stateAfter());
             graph.replaceFixedWithFixed(store, write);
         } else if (n instanceof LoadHubNode) {
@@ -672,10 +676,13 @@
                                 value = allocations[commit.getVirtualObjects().indexOf(value)];
                             }
                             if (!(value.isConstant() && value.asConstant().isDefaultForKind())) {
-                                graph.addBeforeFixed(commit,
-                                                graph.add(new WriteNode(newObject, value, createFieldLocation(graph, (HotSpotResolvedJavaField) instance.field(i)), WriteBarrierType.NONE, false)));
+                                WriteNode write = new WriteNode(newObject, value, createFieldLocation(graph, (HotSpotResolvedJavaField) instance.field(i)), WriteBarrierType.NONE,
+                                                instance.field(i).getKind() == Kind.Object);
+
+                                graph.addBeforeFixed(commit, graph.add(write));
                             }
                         }
+
                     } else {
                         VirtualArrayNode array = (VirtualArrayNode) virtual;
                         ResolvedJavaType element = array.componentType();
@@ -687,8 +694,9 @@
                                 value = allocations[indexOf];
                             }
                             if (!(value.isConstant() && value.asConstant().isDefaultForKind())) {
-                                graph.addBeforeFixed(commit,
-                                                graph.add(new WriteNode(newObject, value, createArrayLocation(graph, element.getKind(), ConstantNode.forInt(i, graph)), WriteBarrierType.NONE, false)));
+                                WriteNode write = new WriteNode(newObject, value, createArrayLocation(graph, element.getKind(), ConstantNode.forInt(i, graph)), WriteBarrierType.NONE,
+                                                value.kind() == Kind.Object);
+                                graph.addBeforeFixed(commit, graph.add(write));
                             }
                         }
                     }
@@ -732,7 +740,8 @@
                 for (OSRLocalNode osrLocal : graph.getNodes(OSRLocalNode.class)) {
                     int size = FrameStateBuilder.stackSlots(osrLocal.kind());
                     int offset = localsOffset - (osrLocal.index() + size - 1) * 8;
-                    UnsafeLoadNode load = graph.add(new UnsafeLoadNode(buffer, offset, ConstantNode.forInt(0, graph), osrLocal.kind()));
+                    IndexedLocationNode location = IndexedLocationNode.create(ANY_LOCATION, osrLocal.kind(), offset, ConstantNode.forLong(0, graph), graph, 1);
+                    ReadNode load = graph.add(new ReadNode(buffer, location, osrLocal.stamp(), WriteBarrierType.NONE, false));
                     osrLocal.replaceAndDelete(load);
                     graph.addBeforeFixed(migrationEnd, load);
                 }
@@ -854,8 +863,16 @@
         return ConstantLocationNode.create(field, field.getKind(), field.offset(), graph);
     }
 
+    public int getScalingFactor(Kind kind) {
+        if (config.useCompressedOops && kind == Kind.Object) {
+            return this.graalRuntime.getTarget().arch.getSizeInBytes(Kind.Int);
+        } else {
+            return this.graalRuntime.getTarget().arch.getSizeInBytes(kind);
+        }
+    }
+
     protected IndexedLocationNode createArrayLocation(Graph graph, Kind elementKind, ValueNode index) {
-        int scale = this.graalRuntime.getTarget().arch.getSizeInBytes(elementKind);
+        int scale = getScalingFactor(elementKind);
         return IndexedLocationNode.create(NamedLocationIdentity.getArrayLocation(elementKind), elementKind, getArrayBaseOffset(elementKind), index, graph, scale);
     }
 
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/AESCryptSubstitutions.java	Wed Jun 05 14:18:35 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/AESCryptSubstitutions.java	Wed Jun 05 15:11:58 2013 +0200
@@ -22,7 +22,6 @@
  */
 package com.oracle.graal.hotspot.replacements;
 
-import static com.oracle.graal.api.meta.LocationIdentity.*;
 import static com.oracle.graal.hotspot.replacements.HotSpotReplacementsUtil.*;
 import sun.misc.*;
 
@@ -67,7 +66,8 @@
     }
 
     private static void crypt(Object rcvr, byte[] in, int inOffset, byte[] out, int outOffset, boolean encrypt) {
-        Word kAddr = Word.fromObject(rcvr).readWord(Word.unsigned(kOffset), ANY_LOCATION).add(arrayBaseOffset(Kind.Byte));
+        Object kObject = UnsafeLoadNode.load(rcvr, 0, kOffset, Kind.Object);
+        Word kAddr = (Word) Word.fromObject(kObject).add(arrayBaseOffset(Kind.Byte));
         Word inAddr = Word.unsigned(GetObjectAddressNode.get(in) + arrayBaseOffset(Kind.Byte) + inOffset);
         Word outAddr = Word.unsigned(GetObjectAddressNode.get(out) + arrayBaseOffset(Kind.Byte) + outOffset);
         if (encrypt) {
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/CipherBlockChainingSubstitutions.java	Wed Jun 05 14:18:35 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/CipherBlockChainingSubstitutions.java	Wed Jun 05 15:11:58 2013 +0200
@@ -22,7 +22,6 @@
  */
 package com.oracle.graal.hotspot.replacements;
 
-import static com.oracle.graal.api.meta.LocationIdentity.*;
 import static com.oracle.graal.hotspot.replacements.HotSpotReplacementsUtil.*;
 import sun.misc.*;
 
@@ -63,7 +62,7 @@
 
     @MethodSubstitution(isStatic = false)
     static void encrypt(Object rcvr, byte[] in, int inOffset, int inLength, byte[] out, int outOffset) {
-        Object embeddedCipher = Word.fromObject(rcvr).readObject(Word.unsigned(embeddedCipherOffset), ANY_LOCATION);
+        Object embeddedCipher = UnsafeLoadNode.load(rcvr, 0, embeddedCipherOffset, Kind.Object);
         if (getAESCryptClass().isInstance(embeddedCipher)) {
             crypt(rcvr, in, inOffset, inLength, out, outOffset, embeddedCipher, true);
         } else {
@@ -73,7 +72,7 @@
 
     @MethodSubstitution(isStatic = false)
     static void decrypt(Object rcvr, byte[] in, int inOffset, int inLength, byte[] out, int outOffset) {
-        Object embeddedCipher = Word.fromObject(rcvr).readObject(Word.unsigned(embeddedCipherOffset), ANY_LOCATION);
+        Object embeddedCipher = UnsafeLoadNode.load(rcvr, 0, embeddedCipherOffset, Kind.Object);
         if (in != out && getAESCryptClass().isInstance(embeddedCipher)) {
             crypt(rcvr, in, inOffset, inLength, out, outOffset, embeddedCipher, false);
         } else {
@@ -82,8 +81,10 @@
     }
 
     private static void crypt(Object rcvr, byte[] in, int inOffset, int inLength, byte[] out, int outOffset, Object embeddedCipher, boolean encrypt) {
-        Word kAddr = Word.fromObject(embeddedCipher).readWord(Word.unsigned(AESCryptSubstitutions.kOffset), ANY_LOCATION).add(arrayBaseOffset(Kind.Byte));
-        Word rAddr = Word.unsigned(GetObjectAddressNode.get(rcvr)).readWord(Word.unsigned(rOffset), ANY_LOCATION).add(arrayBaseOffset(Kind.Byte));
+        Object kObject = UnsafeLoadNode.load(embeddedCipher, 0, AESCryptSubstitutions.kOffset, Kind.Object);
+        Object rObject = UnsafeLoadNode.load(rcvr, 0, rOffset, Kind.Object);
+        Word kAddr = (Word) Word.fromObject(kObject).add(arrayBaseOffset(Kind.Byte));
+        Word rAddr = (Word) Word.fromObject(rObject).add(arrayBaseOffset(Kind.Byte));
         Word inAddr = Word.unsigned(GetObjectAddressNode.get(in) + arrayBaseOffset(Kind.Byte) + inOffset);
         Word outAddr = Word.unsigned(GetObjectAddressNode.get(out) + arrayBaseOffset(Kind.Byte) + outOffset);
         if (encrypt) {
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/NewObjectSnippets.java	Wed Jun 05 14:18:35 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/NewObjectSnippets.java	Wed Jun 05 15:11:58 2013 +0200
@@ -238,7 +238,7 @@
             Kind elementKind = elementType.getKind();
             ConstantNode hub = ConstantNode.forConstant(arrayType.klass(), runtime, graph);
             final int headerSize = HotSpotRuntime.getArrayBaseOffset(elementKind);
-            int log2ElementSize = CodeUtil.log2(target.arch.getSizeInBytes(elementKind));
+            int log2ElementSize = CodeUtil.log2(((HotSpotRuntime) runtime).getScalingFactor(elementKind));
 
             Arguments args = new Arguments(allocateArray);
             args.add("hub", hub);
--- a/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Move.java	Wed Jun 05 14:18:35 2013 +0200
+++ b/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Move.java	Wed Jun 05 15:11:58 2013 +0200
@@ -117,6 +117,36 @@
         }
     }
 
+    public static class LoadCompressedOop extends LoadOp {
+
+        private long narrowOopBase;
+        private int narrowOopShift;
+        private int logMinObjAlignment;
+        @Temp({REG}) private AllocatableValue scratch;
+
+        public LoadCompressedOop(Kind kind, AllocatableValue result, AllocatableValue scratch, AMD64AddressValue address, LIRFrameState state, long narrowOopBase, int narrowOopShift,
+                        int logMinObjAlignment) {
+            super(kind, result, address, state);
+            this.narrowOopBase = narrowOopBase;
+            this.narrowOopShift = narrowOopShift;
+            this.logMinObjAlignment = logMinObjAlignment;
+            this.scratch = scratch;
+        }
+
+        @Override
+        public void emitMemAccess(AMD64MacroAssembler masm) {
+            switch (kind) {
+                case Object:
+                    Register resRegister = asRegister(result);
+                    masm.movl(resRegister, address.toAddress());
+                    decodeOop(masm, resRegister, narrowOopBase, narrowOopShift, logMinObjAlignment);
+                    break;
+                default:
+                    throw GraalInternalError.shouldNotReachHere();
+            }
+        }
+    }
+
     public static class LoadOp extends MemOp {
 
         @Def({REG}) protected AllocatableValue result;
@@ -160,6 +190,51 @@
         }
     }
 
+    public static class StoreCompressedOop extends AMD64LIRInstruction {
+
+        protected final Kind kind;
+        private long narrowOopBase;
+        private int narrowOopShift;
+        private int logMinObjAlignment;
+        @Temp({REG}) private AllocatableValue scratch;
+        @Alive({REG}) protected AllocatableValue input;
+        @Alive({COMPOSITE}) protected AMD64AddressValue address;
+        @State protected LIRFrameState state;
+
+        public StoreCompressedOop(Kind kind, AMD64AddressValue address, AllocatableValue input, AllocatableValue scratch, LIRFrameState state, long narrowOopBase, int narrowOopShift,
+                        int logMinObjAlignment) {
+            this.narrowOopBase = narrowOopBase;
+            this.narrowOopShift = narrowOopShift;
+            this.logMinObjAlignment = logMinObjAlignment;
+            this.scratch = scratch;
+            this.kind = kind;
+            this.address = address;
+            this.state = state;
+            this.input = input;
+        }
+
+        @Override
+        public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
+            emitMemAccess(tasm, masm);
+        }
+
+        public void emitMemAccess(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
+            switch (kind) {
+                case Object:
+                    masm.movq(asRegister(scratch), asRegister(input));
+                    encodeOop(masm, asRegister(scratch), narrowOopBase, narrowOopShift, logMinObjAlignment);
+                    if (state != null) {
+                        tasm.recordImplicitException(masm.codeBuffer.position(), state);
+                    }
+                    masm.movl(address.toAddress(), asRegister(scratch));
+                    // masm.movq(asRegister(scratch), 0xDEADBEEF);
+                    break;
+                default:
+                    throw GraalInternalError.shouldNotReachHere();
+            }
+        }
+    }
+
     public static class StoreOp extends MemOp {
 
         @Use({REG}) protected AllocatableValue input;
@@ -205,10 +280,12 @@
     public static class StoreConstantOp extends MemOp {
 
         protected final Constant input;
+        private final boolean compress;
 
-        public StoreConstantOp(Kind kind, AMD64AddressValue address, Constant input, LIRFrameState state) {
+        public StoreConstantOp(Kind kind, AMD64AddressValue address, Constant input, LIRFrameState state, boolean compress) {
             super(kind, address, state);
             this.input = input;
+            this.compress = compress;
         }
 
         @Override
@@ -239,7 +316,11 @@
                     throw GraalInternalError.shouldNotReachHere("Cannot store 64-bit constants to memory");
                 case Object:
                     if (input.isNull()) {
-                        masm.movptr(address.toAddress(), 0);
+                        if (compress) {
+                            masm.movl(address.toAddress(), 0);
+                        } else {
+                            masm.movptr(address.toAddress(), 0);
+                        }
                     } else {
                         throw GraalInternalError.shouldNotReachHere("Cannot store 64-bit constants to memory");
                     }
@@ -334,6 +415,37 @@
         }
     }
 
+    @Opcode("CAS")
+    public static class CompareAndSwapCompressedOp extends AMD64LIRInstruction {
+
+        @Def protected AllocatableValue result;
+        @Alive({COMPOSITE}) protected AMD64AddressValue address;
+        @Alive protected AllocatableValue cmpValue;
+        @Alive protected AllocatableValue newValue;
+        @Temp({REG}) protected AllocatableValue scratch;
+
+        private long narrowOopBase;
+        private int narrowOopShift;
+        private int logMinObjAlignment;
+
+        public CompareAndSwapCompressedOp(AllocatableValue result, AMD64AddressValue address, AllocatableValue cmpValue, AllocatableValue newValue, AllocatableValue scratch, long narrowOopBase,
+                        int narrowOopShift, int logMinObjAlignment) {
+            this.narrowOopBase = narrowOopBase;
+            this.narrowOopShift = narrowOopShift;
+            this.logMinObjAlignment = logMinObjAlignment;
+            this.scratch = scratch;
+            this.result = result;
+            this.address = address;
+            this.cmpValue = cmpValue;
+            this.newValue = newValue;
+        }
+
+        @Override
+        public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
+            compareAndSwapCompressed(tasm, masm, result, address, cmpValue, newValue, scratch, narrowOopBase, narrowOopShift, logMinObjAlignment);
+        }
+    }
+
     public static void move(TargetMethodAssembler tasm, AMD64MacroAssembler masm, Value result, Value input) {
         if (isRegister(input)) {
             if (isRegister(result)) {
@@ -542,4 +654,51 @@
                 throw GraalInternalError.shouldNotReachHere();
         }
     }
+
+    protected static void compareAndSwapCompressed(TargetMethodAssembler tasm, AMD64MacroAssembler masm, AllocatableValue result, AMD64AddressValue address, AllocatableValue cmpValue,
+                    AllocatableValue newValue, AllocatableValue scratch, long narrowOopBase, int narrowOopShift, int logMinObjAlignment) {
+        assert asRegister(cmpValue) == AMD64.rax && asRegister(result) == AMD64.rax;
+
+        switch (cmpValue.getKind()) {
+            case Object:
+                final Register scratchRegister = asRegister(scratch);
+                final Register cmpRegister = asRegister(cmpValue);
+                final Register newRegister = asRegister(newValue);
+                encodeOop(masm, cmpRegister, narrowOopBase, narrowOopShift, logMinObjAlignment);
+                masm.movq(scratchRegister, newRegister);
+                encodeOop(masm, scratchRegister, narrowOopBase, narrowOopShift, logMinObjAlignment);
+                if (tasm.target.isMP) {
+                    masm.lock();
+                }
+                masm.cmpxchgl(scratchRegister, address.toAddress());
+                break;
+            default:
+                throw GraalInternalError.shouldNotReachHere();
+        }
+    }
+
+    private static void encodeOop(AMD64MacroAssembler masm, Register scratchRegister, long narrowOopBase, int narrowOopShift, int logMinObjAlignment) {
+        if (narrowOopBase == 0) {
+            if (narrowOopShift != 0) {
+                assert logMinObjAlignment == narrowOopShift : "Encode algorithm is wrong";
+                masm.shrq(scratchRegister, logMinObjAlignment);
+            }
+        } else {
+            masm.subq(scratchRegister, AMD64.r12);
+            masm.shrq(scratchRegister, logMinObjAlignment);
+        }
+    }
+
+    private static void decodeOop(AMD64MacroAssembler masm, Register resRegister, long narrowOopBase, int narrowOopShift, int logMinObjAlignment) {
+        if (narrowOopBase == 0) {
+            if (narrowOopShift != 0) {
+                assert logMinObjAlignment == narrowOopShift : "Decode algorithm is wrong";
+                masm.shlq(resRegister, logMinObjAlignment);
+            }
+        } else {
+            masm.shlq(resRegister, logMinObjAlignment);
+            masm.addq(resRegister, AMD64.r12);
+        }
+    }
+
 }
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/DirectObjectStoreNode.java	Wed Jun 05 14:18:35 2013 +0200
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/DirectObjectStoreNode.java	Wed Jun 05 15:11:58 2013 +0200
@@ -24,6 +24,7 @@
 
 import static com.oracle.graal.api.meta.LocationIdentity.*;
 
+import com.oracle.graal.api.meta.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.HeapAccess.WriteBarrierType;
 import com.oracle.graal.nodes.extended.*;
@@ -65,7 +66,7 @@
     @Override
     public void lower(LoweringTool tool, LoweringType loweringType) {
         IndexedLocationNode location = IndexedLocationNode.create(ANY_LOCATION, value.kind(), displacement, offset, graph(), 1);
-        WriteNode write = graph().add(new WriteNode(object, value, location, WriteBarrierType.NONE, false));
+        WriteNode write = graph().add(new WriteNode(object, value, location, WriteBarrierType.NONE, value.kind() == Kind.Object));
         graph().replaceFixedWithFixed(this, write);
     }
 }
--- a/src/share/vm/graal/graalCodeInstaller.cpp	Wed Jun 05 14:18:35 2013 +0200
+++ b/src/share/vm/graal/graalCodeInstaller.cpp	Wed Jun 05 15:11:58 2013 +0200
@@ -256,7 +256,13 @@
     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, oop_recorder);
+      oop object;
+      if(UseCompressedOops) {
+        object=oopDesc::decode_heap_oop(((narrowOop*) values->base(T_OBJECT))[i]);
+      } else {
+        object=((oop*) (values->base(T_OBJECT)))[i];
+      }
+      ScopeValue* value = get_hotspot_value(object, 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.
@@ -437,9 +443,13 @@
   memcpy(_instructions->start(), _code->base(T_BYTE), _code_size);
   _instructions->set_end(_instructions->start() + _code_size);
 
-  oop* sites = (oop*) _sites->base(T_OBJECT);
+  oop site;
   for (int i = 0; i < _sites->length(); i++) {
-    oop site = sites[i];
+    if(UseCompressedOops) {
+      site=oopDesc::decode_heap_oop(((narrowOop*) _sites->base(T_OBJECT))[i]);
+    } else {
+      site=((oop*) (_sites->base(T_OBJECT)))[i];
+    }
     jint pc_offset = CompilationResult_Site::pcOffset(site);
 
     if (site->is_a(CompilationResult_Call::klass())) {
@@ -469,9 +479,13 @@
 
 #ifndef PRODUCT
   if (_comments != NULL) {
-    oop* comments = (oop*) _comments->base(T_OBJECT);
+    oop comment;
     for (int i = 0; i < _comments->length(); i++) {
-      oop comment = comments[i];
+      if(UseCompressedOops) {
+        comment=oopDesc::decode_heap_oop(((narrowOop*) _comments->base(T_OBJECT))[i]);
+      } else {
+        comment=((oop*) (_comments->base(T_OBJECT)))[i];
+      }
       assert(comment->is_a(HotSpotCompiledCode_Comment::klass()), "cce");
       jint offset = HotSpotCompiledCode_Comment::pcOffset(comment);
       char* text = java_lang_String::as_utf8_string(HotSpotCompiledCode_Comment::text(comment));
@@ -533,7 +547,12 @@
   if (_exception_handlers != NULL) {
     oop* exception_handlers = (oop*) _exception_handlers->base(T_OBJECT);
     for (int i = 0; i < _exception_handlers->length(); i++) {
-      oop exc = exception_handlers[i];
+      oop exc;
+      if(UseCompressedOops) {
+        exc=oopDesc::decode_heap_oop(((narrowOop*) _exception_handlers->base(T_OBJECT))[i]);
+      } else {
+        exc=((oop*) (_exception_handlers->base(T_OBJECT)))[i];
+      }
       jint pc_offset = CompilationResult_Site::pcOffset(exc);
       jint handler_offset = CompilationResult_ExceptionHandler::handlerPos(exc);
 
@@ -605,8 +624,12 @@
 
   for (jint i = 0; i < values->length(); i++) {
     ScopeValue* second = NULL;
-    oop value = ((oop*) values->base(T_OBJECT))[i];
-
+    oop value;
+    if(UseCompressedOops) {
+      value=oopDesc::decode_heap_oop(((narrowOop*) values->base(T_OBJECT))[i]);
+    } else {
+      value = ((oop*) values->base(T_OBJECT))[i];
+    }
     if (i < local_count) {
       ScopeValue* first = get_hotspot_value(value, _total_frame_size, objects, second, _oop_recorder);
       if (second != NULL) {
@@ -625,10 +648,15 @@
     if (second != NULL) {
       i++;
       assert(i < values->length(), "double-slot value not followed by Value.ILLEGAL");
-      assert(((oop*) values->base(T_OBJECT))[i] == Value::ILLEGAL(), "double-slot value not followed by Value.ILLEGAL");
+      if(UseCompressedOops) {
+        assert(oopDesc::decode_heap_oop(((narrowOop*) values->base(T_OBJECT))[i]) == Value::ILLEGAL(), "double-slot value not followed by Value.ILLEGAL");
+      } else {
+        assert(((oop*) values->base(T_OBJECT))[i] == Value::ILLEGAL(), "double-slot value not followed by Value.ILLEGAL");
+      }
     }
   }
 
+
   _debug_recorder->dump_object_pool(objects);
 
   DebugToken* locals_token = _debug_recorder->create_scope_values(locals);
--- a/src/share/vm/graal/graalCompilerToVM.cpp	Wed Jun 05 14:18:35 2013 +0200
+++ b/src/share/vm/graal/graalCompilerToVM.cpp	Wed Jun 05 15:11:58 2013 +0200
@@ -831,6 +831,12 @@
   set_int("vmIntrinsicLinkToSpecial", vmIntrinsics::_linkToSpecial);
   set_int("vmIntrinsicLinkToInterface", vmIntrinsics::_linkToInterface);
 
+  set_boolean("useCompressedOops", UseCompressedOops);
+  set_boolean("useCompressedKlassPointers", UseCompressedKlassPointers);
+  set_address("narrowOopBase", Universe::narrow_oop_base());
+  set_int("narrowOopShift", Universe::narrow_oop_shift());
+  set_int("logMinObjAlignment", LogMinObjAlignmentInBytes);
+
   set_int("g1CardQueueIndexOffset", in_bytes(JavaThread::dirty_card_queue_offset() + PtrQueue::byte_offset_of_index()));
   set_int("g1CardQueueBufferOffset", in_bytes(JavaThread::dirty_card_queue_offset() + PtrQueue::byte_offset_of_buf()));
   set_int("logOfHRGrainBytes", HeapRegion::LogOfHRGrainBytes);
--- a/src/share/vm/graal/graalCompilerToVM.hpp	Wed Jun 05 14:18:35 2013 +0200
+++ b/src/share/vm/graal/graalCompilerToVM.hpp	Wed Jun 05 15:11:58 2013 +0200
@@ -54,7 +54,12 @@
 
   oop next_arg(BasicType expectedType) {
     assert(_index < _args->length(), "out of bounds");
-    oop arg = ((oop*) _args->base(T_OBJECT))[_index++];
+    oop arg;
+    if(UseCompressedOops) {
+      arg = oopDesc::decode_heap_oop(((narrowOop*) _args->base(T_OBJECT))[_index++]);
+    } else {
+      arg = ((oop*) _args->base(T_OBJECT))[_index++];
+    }
     assert(expectedType == T_OBJECT || java_lang_boxing_object::is_instance(arg, expectedType), "arg type mismatch");
     return arg;
   }
--- a/src/share/vm/oops/klass.hpp	Wed Jun 05 14:18:35 2013 +0200
+++ b/src/share/vm/oops/klass.hpp	Wed Jun 05 15:11:58 2013 +0200
@@ -148,10 +148,7 @@
   Klass*      _primary_supers[_primary_super_limit];
   // java/lang/Class instance mirroring this class
   oop       _java_mirror;
-#ifdef GRAAL
-  // com/oracle/graal/hotspot/HotSpotResolvedObjectType mirroring this class
-  oop       _graal_mirror;
-#endif
+
   // Superclass
   Klass*      _super;
   // First subclass (NULL if none); _subklass->next_sibling() is next one
@@ -252,12 +249,6 @@
   oop java_mirror() const              { return _java_mirror; }
   void set_java_mirror(oop m) { klass_oop_store(&_java_mirror, m); }
 
-#ifdef GRAAL
-  // Graal mirror
-  oop graal_mirror() const               { return _graal_mirror; }
-  void set_graal_mirror(oop m)           { oop_store((oop*) &_graal_mirror, m); }
-#endif
-
   // modifier flags
   jint modifier_flags() const          { return _modifier_flags; }
   void set_modifier_flags(jint flags)  { _modifier_flags = flags; }
@@ -317,7 +308,6 @@
   static ByteSize layout_helper_offset()         { return in_ByteSize(offset_of(Klass, _layout_helper)); }
   static ByteSize access_flags_offset()          { return in_ByteSize(offset_of(Klass, _access_flags)); }
 #ifdef GRAAL
-  static ByteSize graal_mirror_offset()          { return in_ByteSize(offset_of(Klass, _graal_mirror)); }
   static ByteSize next_sibling_offset()          { return in_ByteSize(offset_of(Klass, _next_sibling)); }
   static ByteSize subklass_offset()              { return in_ByteSize(offset_of(Klass, _subklass)); }
 #endif
--- a/src/share/vm/prims/unsafe.cpp	Wed Jun 05 14:18:35 2013 +0200
+++ b/src/share/vm/prims/unsafe.cpp	Wed Jun 05 15:11:58 2013 +0200
@@ -174,17 +174,27 @@
   OrderAccess::release_store_fence((volatile type_name*)index_oop_from_field_offset_long(p, offset), x);
 
 // Macros for oops that check UseCompressedOops
-
+#ifndef GRAAL
 #define GET_OOP_FIELD(obj, offset, v) \
-  oop p = JNIHandles::resolve(obj);   \
-  oop v;                              \
-  if (UseCompressedOops) {            \
+  oop p = JNIHandles::resolve(obj); \
+  oop v; \
+  if (UseCompressedOops) { \
     narrowOop n = *(narrowOop*)index_oop_from_field_offset_long(p, offset); \
-    v = oopDesc::decode_heap_oop(n);                                \
-  } else {                            \
-    v = *(oop*)index_oop_from_field_offset_long(p, offset);                 \
+    v = oopDesc::decode_heap_oop(n); \
+  } else { \
+    v = *(oop*)index_oop_from_field_offset_long(p, offset); \
   }
-
+#else
+#define GET_OOP_FIELD(obj, offset, v) \
+   oop p = JNIHandles::resolve(obj); \
+   oop v; \
+   if (UseCompressedOops && p!=NULL && offset>=oopDesc::header_size()) { \
+     narrowOop n = *(narrowOop*)index_oop_from_field_offset_long(p, offset); \
+     v = oopDesc::decode_heap_oop(n); \
+   } else { \
+     v = *(oop*)index_oop_from_field_offset_long(p, offset); \
+   }
+#endif
 
 // Get/SetObject must be special-cased, since it works with handles.