changeset 14943:e5a55d280f24

Floating nodes for compressing and uncompressing pointers.
author Roland Schatz <roland.schatz@oracle.com>
date Tue, 01 Apr 2014 15:59:32 +0200
parents 13a8c3454e76
children 96f8e6b6a81a
files 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.ptx/src/com/oracle/graal/hotspot/ptx/PTXHotSpotLIRGenerator.java graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotLIRGenerator.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotLIRGenerator.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConfig.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/CompressionNode.java
diffstat 7 files changed, 240 insertions(+), 4 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerator.java	Tue Apr 01 15:50:15 2014 +0200
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerator.java	Tue Apr 01 15:59:32 2014 +0200
@@ -40,6 +40,7 @@
 import com.oracle.graal.hotspot.amd64.AMD64HotSpotMove.StoreCompressedConstantOp;
 import com.oracle.graal.hotspot.amd64.AMD64HotSpotMove.StoreCompressedPointer;
 import com.oracle.graal.hotspot.meta.*;
+import com.oracle.graal.hotspot.nodes.type.*;
 import com.oracle.graal.hotspot.stubs.*;
 import com.oracle.graal.lir.*;
 import com.oracle.graal.lir.StandardOp.NoOp;
@@ -419,4 +420,18 @@
         }
     }
 
+    @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;
+    }
+
+    @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;
+    }
+
 }
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotMove.java	Tue Apr 01 15:50:15 2014 +0200
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotMove.java	Tue Apr 01 15:59:32 2014 +0200
@@ -34,6 +34,7 @@
 import com.oracle.graal.graph.*;
 import com.oracle.graal.hotspot.HotSpotVMConfig.CompressEncoding;
 import com.oracle.graal.hotspot.data.*;
+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;
@@ -74,6 +75,58 @@
         }
     }
 
+    public static class CompressPointer extends AMD64LIRInstruction {
+
+        private final CompressEncoding encoding;
+
+        @Def({REG, HINT}) protected AllocatableValue result;
+        @Use({REG}) protected AllocatableValue input;
+        @Temp({REG, ILLEGAL}) protected AllocatableValue baseRegister;
+
+        public CompressPointer(AllocatableValue result, AllocatableValue input, AllocatableValue baseRegister, CompressEncoding encoding) {
+            this.result = result;
+            this.input = input;
+            this.baseRegister = baseRegister;
+            this.encoding = encoding;
+        }
+
+        @Override
+        public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) {
+            AMD64Move.move(crb, masm, result, input);
+            if (result.getPlatformKind() == NarrowOopStamp.NarrowOop) {
+                encodePointer(masm, asRegister(result), asRegister(baseRegister), encoding);
+            } else {
+                throw GraalInternalError.unimplemented();
+            }
+        }
+    }
+
+    public static class UncompressPointer extends AMD64LIRInstruction {
+
+        private final CompressEncoding encoding;
+
+        @Def({REG, HINT}) protected AllocatableValue result;
+        @Use({REG}) protected AllocatableValue input;
+        @Temp({REG, ILLEGAL}) protected AllocatableValue baseRegister;
+
+        public UncompressPointer(AllocatableValue result, AllocatableValue input, AllocatableValue baseRegister, CompressEncoding encoding) {
+            this.result = result;
+            this.input = input;
+            this.baseRegister = baseRegister;
+            this.encoding = encoding;
+        }
+
+        @Override
+        public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) {
+            AMD64Move.move(crb, masm, result, input);
+            if (result.getKind() == Kind.Object) {
+                decodePointer(masm, asRegister(result), asRegister(baseRegister), encoding);
+            } else {
+                throw GraalInternalError.unimplemented();
+            }
+        }
+    }
+
     public static class LoadCompressedPointer extends LoadOp {
 
         private final CompressEncoding encoding;
--- a/graal/com.oracle.graal.hotspot.ptx/src/com/oracle/graal/hotspot/ptx/PTXHotSpotLIRGenerator.java	Tue Apr 01 15:50:15 2014 +0200
+++ b/graal/com.oracle.graal.hotspot.ptx/src/com/oracle/graal/hotspot/ptx/PTXHotSpotLIRGenerator.java	Tue Apr 01 15:59:32 2014 +0200
@@ -29,6 +29,7 @@
 import com.oracle.graal.compiler.ptx.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.hotspot.*;
+import com.oracle.graal.hotspot.HotSpotVMConfig.CompressEncoding;
 import com.oracle.graal.hotspot.meta.*;
 
 /**
@@ -57,4 +58,14 @@
     public HotSpotProviders getProviders() {
         throw GraalInternalError.unimplemented();
     }
+
+    public Value emitCompress(Value pointer, CompressEncoding encoding) {
+        // TODO
+        throw GraalInternalError.unimplemented();
+    }
+
+    public Value emitUncompress(Value pointer, CompressEncoding encoding) {
+        // TODO
+        throw GraalInternalError.unimplemented();
+    }
 }
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotLIRGenerator.java	Tue Apr 01 15:50:15 2014 +0200
+++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotLIRGenerator.java	Tue Apr 01 15:59:32 2014 +0200
@@ -31,6 +31,7 @@
 import com.oracle.graal.compiler.sparc.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.hotspot.*;
+import com.oracle.graal.hotspot.HotSpotVMConfig.*;
 import com.oracle.graal.hotspot.meta.*;
 import com.oracle.graal.hotspot.stubs.*;
 import com.oracle.graal.lir.*;
@@ -231,4 +232,14 @@
     public StackSlot getDeoptimizationRescueSlot() {
         return deoptimizationRescueSlot;
     }
+
+    public Value emitCompress(Value pointer, CompressEncoding encoding) {
+        // TODO
+        throw GraalInternalError.unimplemented();
+    }
+
+    public Value emitUncompress(Value pointer, CompressEncoding encoding) {
+        // TODO
+        throw GraalInternalError.unimplemented();
+    }
 }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotLIRGenerator.java	Tue Apr 01 15:50:15 2014 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotLIRGenerator.java	Tue Apr 01 15:59:32 2014 +0200
@@ -25,6 +25,7 @@
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.compiler.gen.*;
+import com.oracle.graal.hotspot.HotSpotVMConfig.*;
 import com.oracle.graal.hotspot.meta.*;
 import com.oracle.graal.nodes.spi.*;
 
@@ -50,4 +51,8 @@
     StackSlot getLockSlot(int lockDepth);
 
     HotSpotProviders getProviders();
+
+    Value emitCompress(Value pointer, CompressEncoding encoding);
+
+    Value emitUncompress(Value pointer, CompressEncoding encoding);
 }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConfig.java	Tue Apr 01 15:50:15 2014 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConfig.java	Tue Apr 01 15:59:32 2014 +0200
@@ -33,7 +33,7 @@
 
 /**
  * Used to access native configuration details.
- * 
+ *
  * All non-static, public fields in this class are so that they can be compiled as constants.
  */
 public class HotSpotVMConfig extends CompilerObject {
@@ -42,7 +42,7 @@
 
     /**
      * Determines if the current architecture is included in a given architecture set specification.
-     * 
+     *
      * @param currentArch
      * @param archsSpecification specifies a set of architectures. A zero length value implies all
      *            architectures.
@@ -895,7 +895,7 @@
 
     /**
      * Address of the library lookup routine. The C signature of this routine is:
-     * 
+     *
      * <pre>
      *     void* (const char *filename, char *ebuf, int ebuflen)
      * </pre>
@@ -904,7 +904,7 @@
 
     /**
      * Address of the library lookup routine. The C signature of this routine is:
-     * 
+     *
      * <pre>
      *     void* (void* handle, const char* name)
      * </pre>
@@ -1496,5 +1496,25 @@
         public String toString() {
             return "base: " + base + " shift: " + shift + " alignment: " + alignment;
         }
+
+        @Override
+        public int hashCode() {
+            final int prime = 31;
+            int result = 1;
+            result = prime * result + alignment;
+            result = prime * result + (int) (base ^ (base >>> 32));
+            result = prime * result + shift;
+            return result;
+        }
+
+        @Override
+        public boolean equals(Object obj) {
+            if (obj instanceof CompressEncoding) {
+                CompressEncoding other = (CompressEncoding) obj;
+                return alignment == other.alignment && base == other.base && shift == other.shift;
+            } else {
+                return false;
+            }
+        }
     }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/CompressionNode.java	Tue Apr 01 15:59:32 2014 +0200
@@ -0,0 +1,121 @@
+/*
+ * Copyright (c) 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
+ * 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.nodes;
+
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.graph.*;
+import com.oracle.graal.graph.spi.*;
+import com.oracle.graal.hotspot.*;
+import com.oracle.graal.hotspot.HotSpotVMConfig.CompressEncoding;
+import com.oracle.graal.hotspot.nodes.type.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.calc.*;
+import com.oracle.graal.nodes.spi.*;
+import com.oracle.graal.nodes.type.*;
+
+/**
+ * Compress or uncompress an oop or metaspace pointer.
+ */
+@NodeInfo(nameTemplate = "{p#op/s}")
+public final class CompressionNode extends FloatingNode implements LIRLowerable, Canonicalizable {
+
+    private enum CompressionOp {
+        Compress,
+        Uncompress
+    }
+
+    private final CompressionOp op;
+    private final CompressEncoding encoding;
+
+    @Input private ValueNode input;
+
+    private CompressionNode(CompressionOp op, ValueNode input, CompressEncoding encoding) {
+        super(mkStamp(op, input.stamp(), encoding));
+        this.op = op;
+        this.encoding = encoding;
+        this.input = input;
+    }
+
+    public static CompressionNode compress(ValueNode input, CompressEncoding encoding) {
+        return input.graph().unique(new CompressionNode(CompressionOp.Compress, input, encoding));
+    }
+
+    public static CompressionNode uncompress(ValueNode input, CompressEncoding encoding) {
+        return input.graph().unique(new CompressionNode(CompressionOp.Uncompress, input, encoding));
+    }
+
+    private static Stamp mkStamp(CompressionOp op, Stamp input, CompressEncoding encoding) {
+        switch (op) {
+            case Compress:
+                if (input instanceof ObjectStamp) {
+                    // compressed oop
+                    return new NarrowOopStamp((ObjectStamp) input, encoding);
+                } else if (input instanceof IntegerStamp) {
+                    // compressed metaspace pointer
+                    assert PrimitiveStamp.getBits(input) == 64;
+                    return StampFactory.forInteger(32, false);
+                }
+                break;
+            case Uncompress:
+                if (input instanceof NarrowOopStamp) {
+                    // oop
+                    assert encoding.equals(((NarrowOopStamp) input).getEncoding());
+                    return ((NarrowOopStamp) input).uncompressed();
+                } else if (input instanceof IntegerStamp) {
+                    // metaspace pointer
+                    assert PrimitiveStamp.getBits(input) == 32;
+                    return StampFactory.forInteger(64, false);
+                }
+                break;
+        }
+        throw GraalInternalError.shouldNotReachHere();
+    }
+
+    @Override
+    public Node canonical(CanonicalizerTool tool) {
+        if (input instanceof CompressionNode) {
+            CompressionNode other = (CompressionNode) input;
+            if (op != other.op && encoding.equals(other.encoding)) {
+                return other.input;
+            }
+        }
+        return this;
+    }
+
+    @Override
+    public void generate(NodeLIRBuiderTool gen) {
+        HotSpotLIRGenerator hsGen = (HotSpotLIRGenerator) gen.getLIRGeneratorTool();
+        Value result;
+        switch (op) {
+            case Compress:
+                result = hsGen.emitCompress(gen.operand(input), encoding);
+                break;
+            case Uncompress:
+                result = hsGen.emitUncompress(gen.operand(input), encoding);
+                break;
+            default:
+                throw GraalInternalError.shouldNotReachHere();
+        }
+        gen.setResult(this, result);
+    }
+}