# HG changeset patch # User Roland Schatz # Date 1397141522 -7200 # Node ID 895e9ecedfe8507c134855483f0e2ab22f04bf3d # Parent ed1cfed14afaa8540873067ce870d74a698983a7 Fix code generation for compressed metaspace pointers. diff -r ed1cfed14afa -r 895e9ecedfe8 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 Thu Apr 10 12:49:19 2014 +0200 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerator.java Thu Apr 10 16:52:02 2014 +0200 @@ -457,10 +457,10 @@ } @Override - public Value emitCompress(Value pointer, CompressEncoding encoding) { + public Value emitCompress(Value pointer, CompressEncoding encoding, boolean nonNull) { if (pointer.getPlatformKind() == Kind.Object) { Variable result = newVariable(NarrowOopStamp.NarrowOop); - append(new AMD64HotSpotMove.CompressPointer(result, asAllocatable(pointer), getProviders().getRegisters().getHeapBaseRegister().asValue(), encoding)); + append(new AMD64HotSpotMove.CompressPointer(result, asAllocatable(pointer), getProviders().getRegisters().getHeapBaseRegister().asValue(), encoding, nonNull)); return result; } else { assert pointer.getPlatformKind() == Kind.Long; @@ -470,16 +470,16 @@ base = newVariable(Kind.Long); append(new AMD64Move.MoveToRegOp(Kind.Long, base, Constant.forLong(encoding.base))); } - append(new AMD64HotSpotMove.CompressPointer(result, asAllocatable(pointer), base, encoding)); + append(new AMD64HotSpotMove.CompressPointer(result, asAllocatable(pointer), base, encoding, nonNull)); return result; } } @Override - public Value emitUncompress(Value pointer, CompressEncoding encoding) { + public Value emitUncompress(Value pointer, CompressEncoding encoding, boolean nonNull) { if (pointer.getPlatformKind() == NarrowOopStamp.NarrowOop) { Variable result = newVariable(Kind.Object); - append(new AMD64HotSpotMove.UncompressPointer(result, asAllocatable(pointer), getProviders().getRegisters().getHeapBaseRegister().asValue(), encoding)); + append(new AMD64HotSpotMove.UncompressPointer(result, asAllocatable(pointer), getProviders().getRegisters().getHeapBaseRegister().asValue(), encoding, nonNull)); return result; } else { assert pointer.getPlatformKind() == Kind.Int; @@ -489,7 +489,7 @@ base = newVariable(Kind.Long); append(new AMD64Move.MoveToRegOp(Kind.Long, base, Constant.forLong(encoding.base))); } - append(new AMD64HotSpotMove.UncompressPointer(result, asAllocatable(pointer), base, encoding)); + append(new AMD64HotSpotMove.UncompressPointer(result, asAllocatable(pointer), base, encoding, nonNull)); return result; } } diff -r ed1cfed14afa -r 895e9ecedfe8 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 Thu Apr 10 12:49:19 2014 +0200 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotMove.java Thu Apr 10 16:52:02 2014 +0200 @@ -78,46 +78,81 @@ public static class CompressPointer extends AMD64LIRInstruction { private final CompressEncoding encoding; + private final boolean nonNull; @Def({REG, HINT}) protected AllocatableValue result; @Use({REG}) protected AllocatableValue input; @Use({REG, ILLEGAL}) protected AllocatableValue baseRegister; - public CompressPointer(AllocatableValue result, AllocatableValue input, AllocatableValue baseRegister, CompressEncoding encoding) { + public CompressPointer(AllocatableValue result, AllocatableValue input, AllocatableValue baseRegister, CompressEncoding encoding, boolean nonNull) { this.result = result; this.input = input; this.baseRegister = baseRegister; this.encoding = encoding; + this.nonNull = nonNull; } @Override public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) { AMD64Move.move(Kind.Long, crb, masm, result, input); - Register base = encoding.base != 0 ? asRegister(baseRegister) : null; - encodePointer(masm, asRegister(result), base, encoding); + + Register resReg = asRegister(result); + if (encoding.base != 0) { + Register baseReg = asRegister(baseRegister); + if (!nonNull) { + masm.testq(resReg, resReg); + masm.cmovq(ConditionFlag.Equal, resReg, baseReg); + } + masm.subq(resReg, baseReg); + } + + if (encoding.shift != 0) { + masm.shrq(resReg, encoding.shift); + } } } public static class UncompressPointer extends AMD64LIRInstruction { private final CompressEncoding encoding; + private final boolean nonNull; @Def({REG, HINT}) protected AllocatableValue result; @Use({REG}) protected AllocatableValue input; @Use({REG, ILLEGAL}) protected AllocatableValue baseRegister; - public UncompressPointer(AllocatableValue result, AllocatableValue input, AllocatableValue baseRegister, CompressEncoding encoding) { + public UncompressPointer(AllocatableValue result, AllocatableValue input, AllocatableValue baseRegister, CompressEncoding encoding, boolean nonNull) { this.result = result; this.input = input; this.baseRegister = baseRegister; this.encoding = encoding; + this.nonNull = nonNull; } @Override public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) { AMD64Move.move(Kind.Int, crb, masm, result, input); - Register base = encoding.base != 0 ? asRegister(baseRegister) : null; - decodePointer(masm, asRegister(result), base, encoding); + + Register resReg = asRegister(result); + if (encoding.shift != 0) { + masm.shlq(resReg, encoding.shift); + } + + if (encoding.base != 0) { + if (nonNull) { + masm.addq(resReg, asRegister(baseRegister)); + } else { + if (encoding.shift == 0) { + // if encoding.shift != 0, the flags are already set by the shlq + masm.testq(resReg, resReg); + } + + Label done = new Label(); + masm.jccb(ConditionFlag.Equal, done); + masm.addq(resReg, asRegister(baseRegister)); + masm.bind(done); + } + } } } diff -r ed1cfed14afa -r 895e9ecedfe8 graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotLIRGenerator.java --- a/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotLIRGenerator.java Thu Apr 10 12:49:19 2014 +0200 +++ b/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotLIRGenerator.java Thu Apr 10 16:52:02 2014 +0200 @@ -294,15 +294,17 @@ throw GraalInternalError.shouldNotReachHere("NYI"); } - public Value emitCompress(Value pointer, CompressEncoding encoding) { + @Override + public Value emitCompress(Value pointer, CompressEncoding encoding, boolean nonNull) { Variable result = newVariable(NarrowOopStamp.NarrowOop); - append(new HSAILMove.CompressPointer(result, newVariable(pointer.getPlatformKind()), asAllocatable(pointer), encoding.base, encoding.shift, encoding.alignment)); + append(new HSAILMove.CompressPointer(result, newVariable(pointer.getPlatformKind()), asAllocatable(pointer), encoding.base, encoding.shift, encoding.alignment, nonNull)); return result; } - public Value emitUncompress(Value pointer, CompressEncoding encoding) { + @Override + public Value emitUncompress(Value pointer, CompressEncoding encoding, boolean nonNull) { Variable result = newVariable(Kind.Object); - append(new HSAILMove.UncompressPointer(result, asAllocatable(pointer), encoding.base, encoding.shift, encoding.alignment)); + append(new HSAILMove.UncompressPointer(result, asAllocatable(pointer), encoding.base, encoding.shift, encoding.alignment, nonNull)); return result; } } diff -r ed1cfed14afa -r 895e9ecedfe8 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 Thu Apr 10 12:49:19 2014 +0200 +++ b/graal/com.oracle.graal.hotspot.ptx/src/com/oracle/graal/hotspot/ptx/PTXHotSpotLIRGenerator.java Thu Apr 10 16:52:02 2014 +0200 @@ -59,12 +59,14 @@ throw GraalInternalError.unimplemented(); } - public Value emitCompress(Value pointer, CompressEncoding encoding) { + @Override + public Value emitCompress(Value pointer, CompressEncoding encoding, boolean nonNull) { // TODO throw GraalInternalError.unimplemented(); } - public Value emitUncompress(Value pointer, CompressEncoding encoding) { + @Override + public Value emitUncompress(Value pointer, CompressEncoding encoding, boolean nonNull) { // TODO throw GraalInternalError.unimplemented(); } diff -r ed1cfed14afa -r 895e9ecedfe8 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 Thu Apr 10 12:49:19 2014 +0200 +++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotLIRGenerator.java Thu Apr 10 16:52:02 2014 +0200 @@ -247,12 +247,14 @@ return deoptimizationRescueSlot; } - public Value emitCompress(Value pointer, CompressEncoding encoding) { + @Override + public Value emitCompress(Value pointer, CompressEncoding encoding, boolean nonNull) { // TODO throw GraalInternalError.unimplemented(); } - public Value emitUncompress(Value pointer, CompressEncoding encoding) { + @Override + public Value emitUncompress(Value pointer, CompressEncoding encoding, boolean nonNull) { // TODO throw GraalInternalError.unimplemented(); } diff -r ed1cfed14afa -r 895e9ecedfe8 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 Thu Apr 10 12:49:19 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotLIRGenerator.java Thu Apr 10 16:52:02 2014 +0200 @@ -37,7 +37,7 @@ /** * Emits an operation to make a tail call. - * + * * @param args the arguments of the call * @param address the target address of the call */ @@ -52,7 +52,7 @@ HotSpotProviders getProviders(); - Value emitCompress(Value pointer, CompressEncoding encoding); + Value emitCompress(Value pointer, CompressEncoding encoding, boolean nonNull); - Value emitUncompress(Value pointer, CompressEncoding encoding); + Value emitUncompress(Value pointer, CompressEncoding encoding, boolean nonNull); } diff -r ed1cfed14afa -r 895e9ecedfe8 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/CompressionNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/CompressionNode.java Thu Apr 10 12:49:19 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/CompressionNode.java Thu Apr 10 16:52:02 2014 +0200 @@ -105,13 +105,21 @@ @Override public void generate(NodeLIRBuilderTool gen) { HotSpotLIRGenerator hsGen = (HotSpotLIRGenerator) gen.getLIRGeneratorTool(); + boolean nonNull; + if (input.stamp() instanceof ObjectStamp) { + nonNull = ObjectStamp.isObjectNonNull(input.stamp()); + } else { + // metaspace pointers are never null + nonNull = true; + } + Value result; switch (op) { case Compress: - result = hsGen.emitCompress(gen.operand(input), encoding); + result = hsGen.emitCompress(gen.operand(input), encoding, nonNull); break; case Uncompress: - result = hsGen.emitUncompress(gen.operand(input), encoding); + result = hsGen.emitUncompress(gen.operand(input), encoding, nonNull); break; default: throw GraalInternalError.shouldNotReachHere(); diff -r ed1cfed14afa -r 895e9ecedfe8 graal/com.oracle.graal.lir.hsail/src/com/oracle/graal/lir/hsail/HSAILMove.java --- a/graal/com.oracle.graal.lir.hsail/src/com/oracle/graal/lir/hsail/HSAILMove.java Thu Apr 10 12:49:19 2014 +0200 +++ b/graal/com.oracle.graal.lir.hsail/src/com/oracle/graal/lir/hsail/HSAILMove.java Thu Apr 10 16:52:02 2014 +0200 @@ -311,24 +311,26 @@ private final long base; private final int shift; private final int alignment; + private final boolean nonNull; @Def({REG}) protected AllocatableValue result; @Temp({REG, HINT}) protected AllocatableValue scratch; @Use({REG}) protected AllocatableValue input; - public CompressPointer(AllocatableValue result, AllocatableValue scratch, AllocatableValue input, long base, int shift, int alignment) { + public CompressPointer(AllocatableValue result, AllocatableValue scratch, AllocatableValue input, long base, int shift, int alignment, boolean nonNull) { this.result = result; this.scratch = scratch; this.input = input; this.base = base; this.shift = shift; this.alignment = alignment; + this.nonNull = nonNull; } @Override public void emitCode(CompilationResultBuilder crb, HSAILAssembler masm) { masm.emitMov(Kind.Long, scratch, input); - boolean testForNull = (input.getKind() == Kind.Object); + boolean testForNull = !nonNull; encodePointer(masm, scratch, base, shift, alignment, testForNull); masm.emitConvert(result, scratch, "u32", "u64"); } @@ -339,22 +341,24 @@ private final long base; private final int shift; private final int alignment; + private final boolean nonNull; @Def({REG, HINT}) protected AllocatableValue result; @Use({REG}) protected AllocatableValue input; - public UncompressPointer(AllocatableValue result, AllocatableValue input, long base, int shift, int alignment) { + public UncompressPointer(AllocatableValue result, AllocatableValue input, long base, int shift, int alignment, boolean nonNull) { this.result = result; this.input = input; this.base = base; this.shift = shift; this.alignment = alignment; + this.nonNull = nonNull; } @Override public void emitCode(CompilationResultBuilder crb, HSAILAssembler masm) { masm.emitConvert(result, input, "u64", "u32"); - boolean testForNull = (result.getKind() == Kind.Object); + boolean testForNull = !nonNull; decodePointer(masm, result, base, shift, alignment, testForNull); } }