changeset 10738:88992c295d47

Merge
author Christos Kotselidis <christos.kotselidis@oracle.com>
date Fri, 12 Jul 2013 20:19:00 +0200
parents 060f9ed42e2f (diff) 2a4ad6ab345e (current diff)
children cdbfff4547be
files
diffstat 7 files changed, 190 insertions(+), 18 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotBackend.java	Fri Jul 12 19:09:52 2013 +0200
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotBackend.java	Fri Jul 12 20:19:00 2013 +0200
@@ -236,7 +236,15 @@
             Register receiver = asRegister(cc.getArgument(0));
             AMD64Address src = new AMD64Address(receiver, config.hubOffset);
 
-            asm.cmpq(inlineCacheKlass, src);
+            AMD64HotSpotLIRGenerator gen = (AMD64HotSpotLIRGenerator) lirGen;
+            HotSpotRuntime hr = ((HotSpotRuntime) gen.getRuntime());
+            if (hr.config.useCompressedKlassPointers) {
+                Register register = r10;
+                AMD64Move.decodeKlassPointer(asm, register, src, hr.config.narrowKlassBase, hr.config.narrowKlassShift, hr.config.logKlassAlignment);
+                asm.cmpq(inlineCacheKlass, register);
+            } else {
+                asm.cmpq(inlineCacheKlass, src);
+            }
             asm.jcc(ConditionFlag.NotEqual, unverifiedStub);
         }
 
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerator.java	Fri Jul 12 19:09:52 2013 +0200
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerator.java	Fri Jul 12 20:19:00 2013 +0200
@@ -413,9 +413,16 @@
         AMD64AddressValue loadAddress = asAddressValue(address);
         Variable result = newVariable(kind);
         assert access == null || access instanceof HeapAccess;
-        if (runtime().config.useCompressedOops && isCompressCandidate(access)) {
-            append(new LoadCompressedPointer(kind, result, loadAddress, access != null ? state(access) : null, runtime().config.narrowOopBase, runtime().config.narrowOopShift,
-                            runtime().config.logMinObjAlignment));
+        if (isCompressCandidate(access)) {
+            if (runtime().config.useCompressedOops && kind == Kind.Object) {
+                append(new LoadCompressedPointer(kind, result, loadAddress, access != null ? state(access) : null, runtime().config.narrowOopBase, runtime().config.narrowOopShift,
+                                runtime().config.logMinObjAlignment));
+            } else if (runtime().config.useCompressedKlassPointers && kind == Kind.Long) {
+                append(new LoadCompressedPointer(kind, result, loadAddress, access != null ? state(access) : null, runtime().config.narrowKlassBase, runtime().config.narrowKlassShift,
+                                runtime().config.logKlassAlignment));
+            } else {
+                append(new LoadOp(kind, result, loadAddress, access != null ? state(access) : null));
+            }
         } else {
             append(new LoadOp(kind, result, loadAddress, access != null ? state(access) : null));
         }
@@ -429,17 +436,26 @@
         if (isConstant(inputVal)) {
             Constant c = asConstant(inputVal);
             if (canStoreConstant(c)) {
-                append(new StoreConstantOp(kind, storeAddress, c, state, runtime().config.useCompressedOops && isCompressCandidate(access)));
+                if (inputVal.getKind() == Kind.Object) {
+                    append(new StoreConstantOp(kind, storeAddress, c, state, runtime().config.useCompressedOops && isCompressCandidate(access)));
+                } else if (inputVal.getKind() == Kind.Long) {
+                    append(new StoreConstantOp(kind, storeAddress, c, state, runtime().config.useCompressedKlassPointers && isCompressCandidate(access)));
+                } else {
+                    append(new StoreConstantOp(kind, storeAddress, c, state, false));
+                }
                 return;
             }
         }
         Variable input = load(inputVal);
-        if (runtime().config.useCompressedOops && isCompressCandidate(access)) {
-            if (input.getKind() == Kind.Object) {
+        if (isCompressCandidate(access)) {
+            if (runtime().config.useCompressedOops && kind == Kind.Object) {
                 Variable scratch = newVariable(Kind.Long);
                 append(new StoreCompressedPointer(kind, storeAddress, input, scratch, state, runtime().config.narrowOopBase, runtime().config.narrowOopShift, runtime().config.logMinObjAlignment));
+            } else if (runtime().config.useCompressedKlassPointers && kind == Kind.Long) {
+                Variable scratch = newVariable(Kind.Long);
+                append(new StoreCompressedPointer(kind, storeAddress, input, scratch, state, runtime().config.narrowKlassBase, runtime().config.narrowKlassShift, runtime().config.logKlassAlignment));
             } else {
-                append(new StoreOp(input.getKind(), storeAddress, input, state));
+                append(new StoreOp(kind, storeAddress, input, state));
             }
         } else {
             append(new StoreOp(kind, storeAddress, input, state));
--- a/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/CompressedOopTest.java	Fri Jul 12 19:09:52 2013 +0200
+++ b/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/CompressedOopTest.java	Fri Jul 12 20:19:00 2013 +0200
@@ -287,6 +287,103 @@
         return "Test".equals(c1);
     }
 
+    @SuppressWarnings("unchecked")
+    public static Object[] unmodListTestByte(Object c1, @SuppressWarnings("unused") Object c2, @SuppressWarnings("unused") Object c3) {
+        List<Byte> queue = (ArrayList<Byte>) c1;
+        Byte[] result = Collections.unmodifiableCollection(queue).toArray(new Byte[queue.size()]);
+        return result;
+    }
+
+    @Test
+    public void test13() throws Exception {
+        HotSpotInstalledCode installedBenchmarkCode = getInstalledCode("unmodListTestByte");
+        List<Byte> list = new ArrayList<>();
+        Byte[] array = (Byte[]) installedBenchmarkCode.execute(list, null, null);
+        Assert.assertTrue(list.size() == array.length);
+    }
+
+    @Test
+    public void test14() throws Exception {
+        HotSpotInstalledCode installedBenchmarkCode = getInstalledCode("stringBufferTest");
+        StringBuffer buffer = new StringBuffer("TestTestTestTestTestTestTest");
+        Assert.assertTrue(buffer.length() == 28);
+        String a = new String("TestTestTestTestTestTestTest");
+        installedBenchmarkCode.execute(buffer, a.toCharArray(), null);
+        Assert.assertTrue(buffer.length() == 56);
+        Assert.assertTrue(buffer.toString().equals("TestTestTestTestTestTestTestTestTestTestTestTestTestTest"));
+    }
+
+    public static void stringBufferTest(Object c1, Object c2, @SuppressWarnings("unused") Object c3) {
+        StringBuffer source = (StringBuffer) c1;
+        char[] add = (char[]) c2;
+        for (int i = 0; i < add.length; i++) {
+            source.append(add[i]);
+        }
+    }
+
+    @Test
+    public void test15() throws Exception {
+        HotSpotInstalledCode installedBenchmarkCode = getInstalledCode("stringBufferTestIn");
+        installedBenchmarkCode.execute(null, null, null);
+    }
+
+    @SuppressWarnings("unused")
+    public static void stringBufferTestIn(Object c1, Object c2, Object c3) {
+        StringBuffer buffer = new StringBuffer("TestTestTestTestTestTestTest");
+        Assert.assertTrue(buffer.length() == 28);
+        String a = new String("TestTestTestTestTestTestTest");
+        char[] add = a.toCharArray();
+        for (int i = 0; i < add.length; i++) {
+            buffer.append(add[i]);
+        }
+        Assert.assertTrue(buffer.length() == 56);
+        Assert.assertTrue(buffer.toString().equals("TestTestTestTestTestTestTestTestTestTestTestTestTestTest"));
+    }
+
+    @Test
+    public void test16() throws Exception {
+        HotSpotInstalledCode installedBenchmarkCode = getInstalledCode("stringBufferArrayCopy");
+        installedBenchmarkCode.execute(null, null, null);
+    }
+
+    @SuppressWarnings("unused")
+    public static void stringBufferArrayCopy(Object c1, Object c2, Object c3) {
+        StringBuffer buffer = new StringBuffer("TestTestTestTestTestTestTest");
+        Assert.assertTrue(buffer.length() == 28);
+        String a = new String("TestTestTestTestTestTestTest");
+        char[] dst = new char[buffer.length() * 2];
+        System.arraycopy(buffer.toString().toCharArray(), 0, dst, 0, buffer.length());
+        System.arraycopy(a.toCharArray(), 0, dst, buffer.length(), buffer.length());
+        Assert.assertTrue(dst.length == 56);
+        Assert.assertTrue(new String(dst).equals("TestTestTestTestTestTestTestTestTestTestTestTestTestTest"));
+    }
+
+    @Test
+    public void test17() throws Exception {
+        HotSpotInstalledCode installedBenchmarkCode = getInstalledCode("stringFormat");
+        installedBenchmarkCode.execute(null, null, null);
+    }
+
+    @SuppressWarnings("unused")
+    public static void stringFormat(Object c1, Object c2, Object c3) {
+        String.format("Hello %d", 0);
+        String.format("Hello %d", -11);
+        String.format("Hello %d", -2147483648);
+    }
+
+    @Test
+    public void test18() throws Exception {
+        HotSpotInstalledCode installedBenchmarkCode = getInstalledCode("stringBuilder");
+        StringBuilder b = (StringBuilder) installedBenchmarkCode.execute(null, null, null);
+        Assert.assertTrue(b.capacity() == 16);
+        Assert.assertTrue(b.length() == 0);
+    }
+
+    @SuppressWarnings("unused")
+    public static Object stringBuilder(Object c1, Object c2, Object c3) {
+        return new StringBuilder();
+    }
+
     static class Container {
 
         public Object a = new Object();
@@ -352,5 +449,4 @@
 
         }
     }
-
 }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java	Fri Jul 12 19:09:52 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java	Fri Jul 12 20:19:00 2013 +0200
@@ -649,6 +649,10 @@
             ResolvedJavaMethod method = loadMethodNode.getMethod();
             ReadNode metaspaceMethod = createReadVirtualMethod(graph, wordKind, loadMethodNode.getHub(), method);
             graph.replaceFixed(loadMethodNode, metaspaceMethod);
+        } else if (n instanceof StoreHubNode) {
+            StoreHubNode storeHub = (StoreHubNode) n;
+            WriteNode hub = createWriteHub(graph, wordKind, storeHub.getObject(), storeHub.getValue());
+            graph.replaceFixed(storeHub, hub);
         } else if (n instanceof FixedGuardNode) {
             FixedGuardNode node = (FixedGuardNode) n;
             GuardingNode guard = tool.createGuard(node.condition(), node.getReason(), node.getAction(), node.isNegated());
@@ -836,7 +840,13 @@
     private ReadNode createReadHub(StructuredGraph graph, Kind wordKind, ValueNode object) {
         LocationNode location = ConstantLocationNode.create(FINAL_LOCATION, wordKind, config.hubOffset, graph);
         assert !object.isConstant() || object.asConstant().isNull();
-        return graph.add(new ReadNode(object, location, StampFactory.forKind(wordKind()), WriteBarrierType.NONE, false));
+        return graph.add(new ReadNode(object, location, StampFactory.forKind(wordKind()), WriteBarrierType.NONE, config.useCompressedKlassPointers));
+    }
+
+    private WriteNode createWriteHub(StructuredGraph graph, Kind wordKind, ValueNode object, ValueNode value) {
+        LocationNode location = ConstantLocationNode.create(ANY_LOCATION, wordKind, config.hubOffset, graph);
+        assert !object.isConstant() || object.asConstant().isNull();
+        return graph.add(new WriteNode(object, value, location, WriteBarrierType.NONE, config.useCompressedKlassPointers));
     }
 
     public static long referentOffset() {
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HotSpotReplacementsUtil.java	Fri Jul 12 19:09:52 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HotSpotReplacementsUtil.java	Fri Jul 12 20:19:00 2013 +0200
@@ -277,7 +277,7 @@
 
     public static void initializeObjectHeader(Word memory, Word markWord, Word hub) {
         memory.writeWord(markOffset(), markWord, MARK_WORD_LOCATION);
-        memory.writeWord(hubOffset(), hub, HUB_LOCATION);
+        StoreHubNode.write(memory.toObject(), hub);
     }
 
     @Fold
@@ -473,6 +473,7 @@
     }
 
     public static Word loadWordFromObject(Object object, int offset) {
+        assert offset != hubOffset() : "Use loadHubIntrinsic instead";
         return loadWordFromObjectIntrinsic(object, 0, offset, getWordKind());
     }
 
@@ -488,7 +489,10 @@
     @SuppressWarnings("unused")
     @NodeIntrinsic(value = LoadHubNode.class, setStampFromReturnType = true)
     static Word loadHubIntrinsic(Object object, @ConstantNodeParameter Kind word) {
-        return Word.box(unsafeReadWord(object, hubOffset()));
+        if (wordKind() == Kind.Int) {
+            return Word.box((int) unsafeReadKlassPointer(object));
+        }
+        return Word.box(unsafeReadKlassPointer(object));
     }
 
     @Fold
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/StubUtil.java	Fri Jul 12 19:09:52 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/StubUtil.java	Fri Jul 12 20:19:00 2013 +0200
@@ -213,7 +213,7 @@
                     fatal("oop not in heap: %p", oop.rawValue());
                 }
 
-                Word klass = oop.readWord(hubOffset());
+                Word klass = loadHub(object);
                 if (klass.equal(Word.zero())) {
                     fatal("klass for oop %p is null", oop.rawValue());
                 }
--- a/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Move.java	Fri Jul 12 19:09:52 2013 +0200
+++ b/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Move.java	Fri Jul 12 20:19:00 2013 +0200
@@ -129,14 +129,18 @@
             this.base = base;
             this.shift = shift;
             this.alignment = alignment;
-            assert kind == Kind.Object;
+            assert kind == Kind.Object || kind == Kind.Long;
         }
 
         @Override
         public void emitMemAccess(AMD64MacroAssembler masm) {
             Register resRegister = asRegister(result);
             masm.movl(resRegister, address.toAddress());
-            decodePointer(masm, resRegister, base, shift, alignment);
+            if (kind == Kind.Object) {
+                decodePointer(masm, resRegister, base, shift, alignment);
+            } else {
+                decodeKlassPointer(masm, resRegister, base, shift, alignment);
+            }
         }
     }
 
@@ -203,13 +207,17 @@
             this.address = address;
             this.state = state;
             this.input = input;
-            assert kind == Kind.Object;
+            assert kind == Kind.Object || kind == Kind.Long;
         }
 
         @Override
         public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
             masm.movq(asRegister(scratch), asRegister(input));
-            encodePointer(masm, asRegister(scratch), base, shift, alignment);
+            if (kind == Kind.Object) {
+                encodePointer(masm, asRegister(scratch), base, shift, alignment);
+            } else {
+                encodeKlassPointer(masm, asRegister(scratch), base, shift, alignment);
+            }
             if (state != null) {
                 tasm.recordImplicitException(masm.codeBuffer.position(), state);
             }
@@ -286,7 +294,11 @@
                     break;
                 case Long:
                     if (NumUtil.isInt(input.asLong())) {
-                        masm.movslq(address.toAddress(), (int) input.asLong());
+                        if (compress) {
+                            masm.movl(address.toAddress(), (int) input.asLong());
+                        } else {
+                            masm.movslq(address.toAddress(), (int) input.asLong());
+                        }
                     } else {
                         throw GraalInternalError.shouldNotReachHere("Cannot store 64-bit constants to memory");
                     }
@@ -691,4 +703,30 @@
         }
     }
 
+    private static void encodeKlassPointer(AMD64MacroAssembler masm, Register scratchRegister, long base, int shift, int alignment) {
+        if (base != 0) {
+            masm.subq(scratchRegister, AMD64.r12);
+        }
+        if (shift != 0) {
+            assert alignment == shift : "Encode algorithm is wrong";
+            masm.shrq(scratchRegister, alignment);
+        }
+    }
+
+    private static void decodeKlassPointer(AMD64MacroAssembler masm, Register resRegister, long base, int shift, int alignment) {
+        if (shift != 0) {
+            assert alignment == shift : "Decode algorighm is wrong";
+            masm.shlq(resRegister, alignment);
+            if (base != 0) {
+                masm.addq(resRegister, AMD64.r12);
+            }
+        } else {
+            assert base == 0 : "Sanity";
+        }
+    }
+
+    public static void decodeKlassPointer(AMD64MacroAssembler masm, Register register, AMD64Address address, long narrowKlassBase, int narrowKlassShift, int logKlassAlignment) {
+        masm.movl(register, address);
+        decodeKlassPointer(masm, register, narrowKlassBase, narrowKlassShift, logKlassAlignment);
+    }
 }