changeset 15023:652564fe42d5

Use CompressionNode for accessing compressed Klass pointers.
author Roland Schatz <roland.schatz@oracle.com>
date Tue, 08 Apr 2014 15:55:18 +0200
parents bceb077143ae
children 2ee777221036
files graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ConstantReflectionProvider.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/AMD64HotSpotMove.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConfig.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotConstantReflectionProvider.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotLoweringProvider.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaField.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ReadNode.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/CustomizedUnsafeLoadFinalNode.java
diffstat 9 files changed, 176 insertions(+), 43 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ConstantReflectionProvider.java	Tue Apr 08 15:44:41 2014 +0200
+++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ConstantReflectionProvider.java	Tue Apr 08 15:55:18 2014 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2014, 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
@@ -59,11 +59,21 @@
      *
      * @param base the base address from which the value is read.
      * @param displacement the displacement within the object in bytes
-     * @param compressible whether this is a read of a compressed or an uncompressed pointer
      * @return the read value encapsulated in a {@link Constant} object, or {@code null} if the
      *         value cannot be read.
      */
-    Constant readUnsafeConstant(Kind kind, Constant base, long displacement, boolean compressible);
+    Constant readUnsafeConstant(Kind kind, Constant base, long displacement);
+
+    /**
+     * Reads a primitive value using a base address and a displacement.
+     *
+     * @param kind the {@link Kind} of the returned {@link Constant} object
+     * @param base the base address from which the value is read
+     * @param displacement the displacement within the object in bytes
+     * @param bits the number of bits to read from memory
+     * @return the read value encapsulated in a {@link Constant} object of {@link Kind} kind
+     */
+    Constant readRawConstant(Kind kind, Constant base, long displacement, int bits);
 
     /**
      * Converts the given {@link Kind#isPrimitive() primitive} constant to a boxed
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerator.java	Tue Apr 08 15:44:41 2014 +0200
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerator.java	Tue Apr 08 15:55:18 2014 +0200
@@ -455,16 +455,40 @@
 
     @Override
     public Value emitCompress(Value pointer, CompressEncoding encoding) {
-        Variable result = newVariable(NarrowOopStamp.NarrowOop);
-        append(new AMD64HotSpotMove.CompressPointer(result, asAllocatable(pointer), getProviders().getRegisters().getHeapBaseRegister().asValue(), encoding));
-        return result;
+        if (pointer.getPlatformKind() == Kind.Object) {
+            Variable result = newVariable(NarrowOopStamp.NarrowOop);
+            append(new AMD64HotSpotMove.CompressPointer(result, asAllocatable(pointer), getProviders().getRegisters().getHeapBaseRegister().asValue(), encoding));
+            return result;
+        } else {
+            assert pointer.getPlatformKind() == Kind.Long;
+            Variable result = newVariable(Kind.Int);
+            AllocatableValue base = Value.ILLEGAL;
+            if (encoding.base != 0) {
+                base = newVariable(Kind.Long);
+                append(new AMD64Move.MoveToRegOp(Kind.Long, base, Constant.forLong(encoding.base)));
+            }
+            append(new AMD64HotSpotMove.CompressPointer(result, asAllocatable(pointer), base, encoding));
+            return result;
+        }
     }
 
     @Override
     public Value emitUncompress(Value pointer, CompressEncoding encoding) {
-        Variable result = newVariable(Kind.Object);
-        append(new AMD64HotSpotMove.UncompressPointer(result, asAllocatable(pointer), getProviders().getRegisters().getHeapBaseRegister().asValue(), encoding));
-        return result;
+        if (pointer.getPlatformKind() == NarrowOopStamp.NarrowOop) {
+            Variable result = newVariable(Kind.Object);
+            append(new AMD64HotSpotMove.UncompressPointer(result, asAllocatable(pointer), getProviders().getRegisters().getHeapBaseRegister().asValue(), encoding));
+            return result;
+        } else {
+            assert pointer.getPlatformKind() == Kind.Int;
+            Variable result = newVariable(Kind.Long);
+            AllocatableValue base = Value.ILLEGAL;
+            if (encoding.base != 0) {
+                base = newVariable(Kind.Long);
+                append(new AMD64Move.MoveToRegOp(Kind.Long, base, Constant.forLong(encoding.base)));
+            }
+            append(new AMD64HotSpotMove.UncompressPointer(result, asAllocatable(pointer), base, encoding));
+            return result;
+        }
     }
 
     @Override
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotMove.java	Tue Apr 08 15:44:41 2014 +0200
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotMove.java	Tue Apr 08 15:55:18 2014 +0200
@@ -35,7 +35,6 @@
 import com.oracle.graal.hotspot.HotSpotVMConfig.CompressEncoding;
 import com.oracle.graal.hotspot.data.*;
 import com.oracle.graal.hotspot.meta.*;
-import com.oracle.graal.hotspot.nodes.type.*;
 import com.oracle.graal.lir.*;
 import com.oracle.graal.lir.amd64.*;
 import com.oracle.graal.lir.amd64.AMD64Move.LoadOp;
@@ -82,7 +81,7 @@
 
         @Def({REG, HINT}) protected AllocatableValue result;
         @Use({REG}) protected AllocatableValue input;
-        @Temp({REG, ILLEGAL}) protected AllocatableValue baseRegister;
+        @Use({REG, ILLEGAL}) protected AllocatableValue baseRegister;
 
         public CompressPointer(AllocatableValue result, AllocatableValue input, AllocatableValue baseRegister, CompressEncoding encoding) {
             this.result = result;
@@ -93,12 +92,9 @@
 
         @Override
         public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) {
-            if (result.getPlatformKind() == NarrowOopStamp.NarrowOop) {
-                AMD64Move.move(Kind.Long, crb, masm, result, input);
-                encodePointer(masm, asRegister(result), asRegister(baseRegister), encoding);
-            } else {
-                throw GraalInternalError.unimplemented();
-            }
+            AMD64Move.move(Kind.Long, crb, masm, result, input);
+            Register base = encoding.base != 0 ? asRegister(baseRegister) : null;
+            encodePointer(masm, asRegister(result), base, encoding);
         }
     }
 
@@ -108,7 +104,7 @@
 
         @Def({REG, HINT}) protected AllocatableValue result;
         @Use({REG}) protected AllocatableValue input;
-        @Temp({REG, ILLEGAL}) protected AllocatableValue baseRegister;
+        @Use({REG, ILLEGAL}) protected AllocatableValue baseRegister;
 
         public UncompressPointer(AllocatableValue result, AllocatableValue input, AllocatableValue baseRegister, CompressEncoding encoding) {
             this.result = result;
@@ -119,12 +115,9 @@
 
         @Override
         public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) {
-            if (result.getKind() == Kind.Object) {
-                AMD64Move.move(Kind.Int, crb, masm, result, input);
-                decodePointer(masm, asRegister(result), asRegister(baseRegister), encoding);
-            } else {
-                throw GraalInternalError.unimplemented();
-            }
+            AMD64Move.move(Kind.Int, crb, masm, result, input);
+            Register base = encoding.base != 0 ? asRegister(baseRegister) : null;
+            decodePointer(masm, asRegister(result), base, encoding);
         }
     }
 
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConfig.java	Tue Apr 08 15:44:41 2014 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConfig.java	Tue Apr 08 15:55:18 2014 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2014, 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
@@ -1499,6 +1499,22 @@
             this.alignment = alignment;
         }
 
+        public int compress(long ptr) {
+            if (ptr == 0L) {
+                return 0;
+            } else {
+                return (int) ((ptr - base) >>> shift);
+            }
+        }
+
+        public long uncompress(int ptr) {
+            if (ptr == 0) {
+                return 0L;
+            } else {
+                return (ptr & 0xFFFFFFFFL) << shift + base;
+            }
+        }
+
         @Override
         public String toString() {
             return "base: " + base + " shift: " + shift + " alignment: " + alignment;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotConstantReflectionProvider.java	Tue Apr 08 15:44:41 2014 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotConstantReflectionProvider.java	Tue Apr 08 15:55:18 2014 +0200
@@ -56,7 +56,7 @@
     }
 
     @Override
-    public Constant readUnsafeConstant(Kind kind, Constant baseConstant, long initialDisplacement, boolean compressible) {
+    public Constant readUnsafeConstant(Kind kind, Constant baseConstant, long initialDisplacement) {
         Object base;
         long displacement;
         if (baseConstant.getKind() == Kind.Object) {
@@ -103,7 +103,7 @@
                 return Constant.forDouble(base == null ? unsafe.getDouble(displacement) : unsafe.getDouble(base, displacement));
             case Object: {
                 Object o = null;
-                if (compressible) {
+                if (baseConstant.getKind() == Kind.Object) {
                     o = unsafe.getObject(base, displacement);
                 } else {
                     o = runtime.getCompilerToVM().readUnsafeUncompressedPointer(base, displacement);
@@ -116,6 +116,71 @@
     }
 
     @Override
+    public Constant readRawConstant(Kind kind, Constant baseConstant, long initialDisplacement, int bits) {
+        Object base;
+        long displacement;
+        if (baseConstant.getKind() == Kind.Object) {
+            base = HotSpotObjectConstant.asObject(baseConstant);
+            displacement = initialDisplacement;
+            if (base == null) {
+                return null;
+            }
+        } else if (baseConstant.getKind().isNumericInteger()) {
+            long baseLong = baseConstant.asLong();
+            if (baseLong == 0L) {
+                return null;
+            }
+            displacement = initialDisplacement + baseLong;
+            base = null;
+        } else {
+            throw GraalInternalError.shouldNotReachHere();
+        }
+
+        long rawValue;
+        switch (bits) {
+            case 8:
+                rawValue = base == null ? unsafe.getByte(displacement) : unsafe.getByte(base, displacement);
+                break;
+            case 16:
+                rawValue = base == null ? unsafe.getShort(displacement) : unsafe.getShort(base, displacement);
+                break;
+            case 32:
+                rawValue = base == null ? unsafe.getInt(displacement) : unsafe.getInt(base, displacement);
+                break;
+            case 64:
+                rawValue = base == null ? unsafe.getLong(displacement) : unsafe.getLong(base, displacement);
+                break;
+            default:
+                throw GraalInternalError.shouldNotReachHere();
+        }
+
+        if (base != null && displacement == config().hubOffset) {
+            if (config().useCompressedClassPointers) {
+                assert bits == 32 && kind == Kind.Int;
+                long klassPointer = config().getKlassEncoding().uncompress((int) rawValue);
+                assert klassPointer == runtime.getCompilerToVM().readUnsafeKlassPointer(base);
+                return HotSpotMetaspaceConstant.forMetaspaceObject(kind, rawValue, HotSpotResolvedObjectType.fromMetaspaceKlass(klassPointer));
+            } else {
+                assert bits == 64 && kind == Kind.Long;
+                return HotSpotMetaspaceConstant.forMetaspaceObject(kind, rawValue, HotSpotResolvedObjectType.fromMetaspaceKlass(rawValue));
+            }
+        } else {
+            switch (kind) {
+                case Int:
+                    return Constant.forInt((int) rawValue);
+                case Long:
+                    return Constant.forLong(rawValue);
+                case Float:
+                    return Constant.forFloat(Float.intBitsToFloat((int) rawValue));
+                case Double:
+                    return Constant.forDouble(Double.longBitsToDouble(rawValue));
+                default:
+                    throw GraalInternalError.shouldNotReachHere();
+            }
+        }
+    }
+
+    @Override
     public Constant readArrayElement(Constant array, int index) {
         if (array.getKind() != Kind.Object || array.isNull()) {
             return null;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotLoweringProvider.java	Tue Apr 08 15:44:41 2014 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotLoweringProvider.java	Tue Apr 08 15:55:18 2014 +0200
@@ -234,7 +234,7 @@
                         int vtableEntryOffset = hsMethod.vtableEntryOffset();
                         assert vtableEntryOffset > 0;
                         Kind wordKind = runtime.getTarget().wordKind;
-                        FloatingReadNode hub = createReadHub(graph, wordKind, receiver, receiverNullCheck);
+                        ValueNode hub = createReadHub(graph, wordKind, receiver, receiverNullCheck);
 
                         ReadNode metaspaceMethod = createReadVirtualMethod(graph, wordKind, hub, hsMethod);
                         // We use LocationNode.ANY_LOCATION for the reads that access the
@@ -418,7 +418,7 @@
                 }
             } else {
                 Kind wordKind = runtime.getTarget().wordKind;
-                FloatingReadNode arrayClass = createReadHub(graph, wordKind, array, boundsCheck);
+                ValueNode arrayClass = createReadHub(graph, wordKind, array, boundsCheck);
                 LocationNode location = ConstantLocationNode.create(FINAL_LOCATION, wordKind, runtime.getConfig().arrayClassElementOffset, graph);
                 /*
                  * Anchor the read of the element klass to the cfg, because it is only valid when
@@ -524,7 +524,7 @@
             assert loadHub.getKind() == wordKind;
             ValueNode object = loadHub.object();
             GuardingNode guard = loadHub.getGuard();
-            FloatingReadNode hub = createReadHub(graph, wordKind, object, guard);
+            ValueNode hub = createReadHub(graph, wordKind, object, guard);
             graph.replaceFloating(loadHub, hub);
         }
     }
@@ -795,18 +795,37 @@
         return metaspaceMethod;
     }
 
-    private FloatingReadNode createReadHub(StructuredGraph graph, Kind wordKind, ValueNode object, GuardingNode guard) {
+    private ValueNode createReadHub(StructuredGraph graph, Kind wordKind, ValueNode object, GuardingNode guard) {
         HotSpotVMConfig config = runtime.getConfig();
         LocationNode location = ConstantLocationNode.create(FINAL_LOCATION, wordKind, config.hubOffset, graph);
         assert !object.isConstant() || object.asConstant().isNull();
-        return graph.unique(new FloatingReadNode(object, location, null, StampFactory.forKind(wordKind), guard, BarrierType.NONE, config.useCompressedClassPointers));
+
+        Stamp hubStamp;
+        if (config.useCompressedClassPointers) {
+            hubStamp = StampFactory.forInteger(32, false);
+        } else {
+            hubStamp = StampFactory.forKind(wordKind);
+        }
+
+        FloatingReadNode memoryRead = graph.unique(new FloatingReadNode(object, location, null, hubStamp, guard, BarrierType.NONE, false));
+        if (config.useCompressedClassPointers) {
+            return CompressionNode.uncompress(memoryRead, config.getKlassEncoding());
+        } else {
+            return memoryRead;
+        }
     }
 
     private WriteNode createWriteHub(StructuredGraph graph, Kind wordKind, ValueNode object, ValueNode value) {
         HotSpotVMConfig config = runtime.getConfig();
         LocationNode location = ConstantLocationNode.create(HUB_LOCATION, wordKind, config.hubOffset, graph);
         assert !object.isConstant() || object.asConstant().isNull();
-        return graph.add(new WriteNode(object, value, location, BarrierType.NONE, config.useCompressedClassPointers));
+
+        ValueNode writeValue = value;
+        if (config.useCompressedClassPointers) {
+            writeValue = CompressionNode.compress(value, config.getKlassEncoding());
+        }
+
+        return graph.add(new WriteNode(object, writeValue, location, BarrierType.NONE, false));
     }
 
     private static BarrierType getFieldLoadBarrierType(HotSpotResolvedJavaField loadField) {
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaField.java	Tue Apr 08 15:44:41 2014 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaField.java	Tue Apr 08 15:55:18 2014 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2014, 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
@@ -244,7 +244,7 @@
 
     /**
      * Determines if a given object contains this field.
-     * 
+     *
      * @return true iff this is a non-static field and its declaring class is assignable from
      *         {@code object}'s class
      */
@@ -260,13 +260,13 @@
         if (receiver == null) {
             assert isStatic(modifiers);
             if (holder.isInitialized()) {
-                return runtime().getHostProviders().getConstantReflection().readUnsafeConstant(getKind(), HotSpotObjectConstant.forObject(holder.mirror()), offset, getKind() == Kind.Object);
+                return runtime().getHostProviders().getConstantReflection().readUnsafeConstant(getKind(), HotSpotObjectConstant.forObject(holder.mirror()), offset);
             }
             return null;
         } else {
             assert !isStatic(modifiers);
             assert receiver.isNonNull() && isInObject(HotSpotObjectConstant.asObject(receiver));
-            return runtime().getHostProviders().getConstantReflection().readUnsafeConstant(getKind(), receiver, offset, getKind() == Kind.Object);
+            return runtime().getHostProviders().getConstantReflection().readUnsafeConstant(getKind(), receiver, offset);
         }
     }
 
@@ -331,7 +331,7 @@
 
     /**
      * Checks if this field has the {@link Stable} annotation.
-     * 
+     *
      * @return true if field has {@link Stable} annotation, false otherwise
      */
     public boolean isStable() {
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ReadNode.java	Tue Apr 08 15:44:41 2014 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ReadNode.java	Tue Apr 08 15:55:18 2014 +0200
@@ -90,16 +90,22 @@
             }
         }
         if (tool.canonicalizeReads()) {
-            if (metaAccess != null && object != null && object.isConstant()) {
+            if (metaAccess != null && object != null && object.isConstant() && !compressible) {
                 if ((location.getLocationIdentity() == LocationIdentity.FINAL_LOCATION || location.getLocationIdentity() == LocationIdentity.ARRAY_LENGTH_LOCATION) &&
                                 location instanceof ConstantLocationNode) {
                     long displacement = ((ConstantLocationNode) location).getDisplacement();
-                    Kind kind = location.getValueKind();
                     Constant base = object.asConstant();
                     if (base != null) {
-                        Constant constant = tool.getConstantReflection().readUnsafeConstant(kind, base, displacement, compressible);
+                        Constant constant;
+                        if (read.stamp() instanceof PrimitiveStamp) {
+                            PrimitiveStamp stamp = (PrimitiveStamp) read.stamp();
+                            constant = tool.getConstantReflection().readRawConstant(stamp.getStackKind(), base, displacement, stamp.getBits());
+                        } else {
+                            assert read.stamp() instanceof ObjectStamp;
+                            constant = tool.getConstantReflection().readUnsafeConstant(Kind.Object, base, displacement);
+                        }
                         if (constant != null) {
-                            return ConstantNode.forConstant(constant, metaAccess, read.graph());
+                            return ConstantNode.forConstant(read.stamp(), constant, metaAccess, read.graph());
                         }
                     }
                 }
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/CustomizedUnsafeLoadFinalNode.java	Tue Apr 08 15:44:41 2014 +0200
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/CustomizedUnsafeLoadFinalNode.java	Tue Apr 08 15:55:18 2014 +0200
@@ -57,7 +57,7 @@
     @Override
     public Node canonical(CanonicalizerTool tool) {
         if (object.isConstant() && !object.isNullConstant() && offset.isConstant()) {
-            Constant constant = tool.getConstantReflection().readUnsafeConstant(accessKind, object.asConstant(), offset.asConstant().asLong(), accessKind == Kind.Object);
+            Constant constant = tool.getConstantReflection().readUnsafeConstant(accessKind, object.asConstant(), offset.asConstant().asLong());
             return ConstantNode.forConstant(constant, tool.getMetaAccess(), graph());
         }
         return this;