# HG changeset patch # User Roland Schatz # Date 1396360772 -7200 # Node ID e5a55d280f24385e951b630b492527d199c12cb3 # Parent 13a8c3454e762eae021667bc0720c0e58b7e3e4c Floating nodes for compressing and uncompressing pointers. diff -r 13a8c3454e76 -r e5a55d280f24 graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerator.java --- 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; + } + } diff -r 13a8c3454e76 -r e5a55d280f24 graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotMove.java --- 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; diff -r 13a8c3454e76 -r e5a55d280f24 graal/com.oracle.graal.hotspot.ptx/src/com/oracle/graal/hotspot/ptx/PTXHotSpotLIRGenerator.java --- 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(); + } } diff -r 13a8c3454e76 -r e5a55d280f24 graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotLIRGenerator.java --- 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(); + } } diff -r 13a8c3454e76 -r e5a55d280f24 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotLIRGenerator.java --- 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); } diff -r 13a8c3454e76 -r e5a55d280f24 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConfig.java --- 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: - * + * *
      *     void* (const char *filename, char *ebuf, int ebuflen)
      * 
@@ -904,7 +904,7 @@ /** * Address of the library lookup routine. The C signature of this routine is: - * + * *
      *     void* (void* handle, const char* name)
      * 
@@ -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; + } + } } } diff -r 13a8c3454e76 -r e5a55d280f24 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/CompressionNode.java --- /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); + } +}