Mercurial > hg > graal-jvmci-8
changeset 15910:79a0d9065849
Support direct comparison of compressed pointers.
author | Roland Schatz <roland.schatz@oracle.com> |
---|---|
date | Mon, 26 May 2014 16:13:58 +0200 |
parents | e43591136d9f |
children | 03e09ed7039d |
files | graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64LIRGenerator.java graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotCompare.java graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerator.java graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Compare.java |
diffstat | 4 files changed, 196 insertions(+), 39 deletions(-) [+] |
line wrap: on
line diff
--- a/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64LIRGenerator.java Mon May 26 16:09:53 2014 +0200 +++ b/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64LIRGenerator.java Mon May 26 16:13:58 2014 +0200 @@ -242,18 +242,10 @@ public void emitCompareBranch(PlatformKind cmpKind, Value left, Value right, Condition cond, boolean unorderedIsTrue, LabelRef trueLabel, LabelRef falseLabel, double trueLabelProbability) { boolean mirrored = emitCompare(cmpKind, left, right); Condition finalCondition = mirrored ? cond.mirror() : cond; - switch (left.getKind().getStackKind()) { - case Int: - case Long: - case Object: - append(new BranchOp(finalCondition, trueLabel, falseLabel, trueLabelProbability)); - break; - case Float: - case Double: - append(new FloatBranchOp(finalCondition, unorderedIsTrue, trueLabel, falseLabel, trueLabelProbability)); - break; - default: - throw GraalInternalError.shouldNotReachHere("" + left.getKind()); + if (cmpKind == Kind.Float || cmpKind == Kind.Double) { + append(new FloatBranchOp(finalCondition, unorderedIsTrue, trueLabel, falseLabel, trueLabelProbability)); + } else { + append(new BranchOp(finalCondition, trueLabel, falseLabel, trueLabelProbability)); } } @@ -261,18 +253,10 @@ double trueLabelProbability) { boolean mirrored = emitCompareMemory(cmpKind, left, right, state); Condition finalCondition = mirrored ? cond.mirror() : cond; - switch (left.getKind().getStackKind()) { - case Int: - case Long: - case Object: - append(new BranchOp(finalCondition, trueLabel, falseLabel, trueLabelProbability)); - break; - case Float: - case Double: - append(new FloatBranchOp(finalCondition, unorderedIsTrue, trueLabel, falseLabel, trueLabelProbability)); - break; - default: - throw GraalInternalError.shouldNotReachHere("" + left.getKind()); + if (cmpKind == Kind.Float || cmpKind == Kind.Double) { + append(new FloatBranchOp(finalCondition, unorderedIsTrue, trueLabel, falseLabel, trueLabelProbability)); + } else { + append(new BranchOp(finalCondition, trueLabel, falseLabel, trueLabelProbability)); } } @@ -293,18 +277,10 @@ Condition finalCondition = mirrored ? cond.mirror() : cond; Variable result = newVariable(trueValue.getKind()); - switch (left.getKind().getStackKind()) { - case Int: - case Long: - case Object: - append(new CondMoveOp(result, finalCondition, load(trueValue), loadNonConst(falseValue))); - break; - case Float: - case Double: - append(new FloatCondMoveOp(result, finalCondition, unorderedIsTrue, load(trueValue), load(falseValue))); - break; - default: - throw GraalInternalError.shouldNotReachHere("" + left.getKind()); + if (cmpKind == Kind.Float || cmpKind == Kind.Double) { + append(new FloatCondMoveOp(result, finalCondition, unorderedIsTrue, load(trueValue), load(falseValue))); + } else { + append(new CondMoveOp(result, finalCondition, load(trueValue), loadNonConst(falseValue))); } return result; } @@ -370,13 +346,13 @@ emitCompareRegMemoryOp(cmpKind, left, b, state); mirrored = false; } else { - emitCompareMemoryConOp(cmpKind, b, a, state); + emitCompareMemoryConOp(cmpKind, b, (Constant) a, state); mirrored = true; } return mirrored; } - protected void emitCompareMemoryConOp(Kind kind, AMD64AddressValue address, Value value, LIRFrameState state) { + protected void emitCompareMemoryConOp(Kind kind, AMD64AddressValue address, Constant value, LIRFrameState state) { assert kind.getStackKind() == value.getKind().getStackKind(); switch (kind) { case Byte: @@ -393,6 +369,10 @@ case Long: append(new CompareMemoryOp(LCMP, kind, address, value, state)); break; + case Object: + assert value.isNull(); + append(new CompareMemoryOp(ACMP, kind, address, value, state)); + break; default: throw GraalInternalError.shouldNotReachHere(); }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotCompare.java Mon May 26 16:13:58 2014 +0200 @@ -0,0 +1,150 @@ +/* + * 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.amd64; + +import static com.oracle.graal.api.code.ValueUtil.*; +import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*; + +import com.oracle.graal.api.meta.*; +import com.oracle.graal.asm.amd64.*; +import com.oracle.graal.compiler.common.*; +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.MemOp; +import com.oracle.graal.lir.asm.*; + +public class AMD64HotSpotCompare { + + @Opcode("NCMP") + public static class HotSpotCompareNarrowOp extends AMD64LIRInstruction { + + @Use({REG}) protected AllocatableValue x; + @Use({REG, STACK}) protected AllocatableValue y; + + public HotSpotCompareNarrowOp(AllocatableValue x, AllocatableValue y) { + this.x = x; + this.y = y; + } + + @Override + public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) { + if (isRegister(y)) { + masm.cmpl(asRegister(x), asRegister(y)); + } else { + assert isStackSlot(y); + masm.cmpl(asRegister(x), (AMD64Address) crb.asAddress(y)); + } + } + + @Override + protected void verify() { + assert x.getPlatformKind() == NarrowOopStamp.NarrowOop && y.getPlatformKind() == NarrowOopStamp.NarrowOop; + } + } + + @Opcode("CMP") + public static class HotSpotCompareConstantOp extends AMD64LIRInstruction { + + @Use({REG}) protected AllocatableValue x; + protected Constant y; + + public HotSpotCompareConstantOp(AllocatableValue x, Constant y) { + this.x = x; + this.y = y; + } + + @Override + public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) { + assert isRegister(x); + if (HotSpotCompressedNullConstant.COMPRESSED_NULL.equals(y)) { + // compressed null + masm.testl(asRegister(x), asRegister(x)); + } else if (y instanceof HotSpotObjectConstant) { + if (HotSpotObjectConstant.isCompressed(y)) { + // compressed oop + crb.recordInlineDataInCode(new OopData(0, HotSpotObjectConstant.asObject(y), true)); + masm.cmpl(asRegister(x), 0xDEADDEAD); + } else { + // uncompressed oop + AMD64Address patch = (AMD64Address) crb.recordDataReferenceInCode(new OopData(8, HotSpotObjectConstant.asObject(y), false)); + masm.cmpq(asRegister(x), patch); + } + } else if (y instanceof HotSpotMetaspaceConstant) { + if (y.getKind() == Kind.Int) { + // compressed metaspace pointer + crb.recordInlineDataInCode(new MetaspaceData(0, y.asInt(), HotSpotMetaspaceConstant.getMetaspaceObject(y), true)); + masm.cmpl(asRegister(x), y.asInt()); + } else { + // uncompressed metaspace pointer + AMD64Address patch = (AMD64Address) crb.recordDataReferenceInCode(new MetaspaceData(8, y.asLong(), HotSpotObjectConstant.asObject(y), false)); + masm.cmpq(asRegister(x), patch); + } + } else { + throw GraalInternalError.shouldNotReachHere(); + } + } + } + + @Opcode("CMP") + public static class HotSpotCompareMemoryConstantOp extends MemOp { + + protected Constant y; + + public HotSpotCompareMemoryConstantOp(Kind kind, AMD64AddressValue x, Constant y, LIRFrameState state) { + super(kind, x, state); + this.y = y; + } + + @Override + protected void emitMemAccess(CompilationResultBuilder crb, AMD64MacroAssembler masm) { + if (HotSpotCompressedNullConstant.COMPRESSED_NULL.equals(y)) { + // compressed null + masm.cmpl(address.toAddress(), 0); + } else if (y instanceof HotSpotObjectConstant) { + if (HotSpotObjectConstant.isCompressed(y) && crb.target.inlineObjects) { + // compressed oop + crb.recordInlineDataInCode(new OopData(0, HotSpotObjectConstant.asObject(y), true)); + masm.cmpl(address.toAddress(), 0xDEADDEAD); + } else { + // uncompressed oop + throw GraalInternalError.shouldNotReachHere(); + } + } else if (y instanceof HotSpotMetaspaceConstant) { + if (y.getKind() == Kind.Int) { + // compressed metaspace pointer + crb.recordInlineDataInCode(new MetaspaceData(0, y.asInt(), HotSpotMetaspaceConstant.getMetaspaceObject(y), true)); + masm.cmpl(address.toAddress(), y.asInt()); + } else { + // uncompressed metaspace pointer + throw GraalInternalError.shouldNotReachHere(); + } + } else { + throw GraalInternalError.shouldNotReachHere(); + } + } + } + +}
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerator.java Mon May 26 16:09:53 2014 +0200 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerator.java Mon May 26 16:13:58 2014 +0200 @@ -643,6 +643,26 @@ } @Override + protected void emitCompareOp(PlatformKind cmpKind, Variable left, Value right) { + if (right instanceof HotSpotConstant) { + append(new AMD64HotSpotCompare.HotSpotCompareConstantOp(left, (Constant) right)); + } else if (cmpKind == NarrowOopStamp.NarrowOop) { + append(new AMD64HotSpotCompare.HotSpotCompareNarrowOp(left, asAllocatable(right))); + } else { + super.emitCompareOp(cmpKind, left, right); + } + } + + @Override + protected void emitCompareMemoryConOp(Kind kind, AMD64AddressValue address, Constant value, LIRFrameState state) { + if (value instanceof HotSpotConstant) { + append(new AMD64HotSpotCompare.HotSpotCompareMemoryConstantOp(kind, address, value, state)); + } else { + super.emitCompareMemoryConOp(kind, address, value, state); + } + } + + @Override public boolean canInlineConstant(Constant c) { if (HotSpotCompressedNullConstant.COMPRESSED_NULL.equals(c)) { return true;
--- a/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Compare.java Mon May 26 16:09:53 2014 +0200 +++ b/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Compare.java Mon May 26 16:13:58 2014 +0200 @@ -84,7 +84,7 @@ } @Override - public void emitMemAccess(CompilationResultBuilder crb, AMD64MacroAssembler masm) { + protected void emitMemAccess(CompilationResultBuilder crb, AMD64MacroAssembler masm) { if (isRegister(y)) { switch (opcode) { case BCMP: @@ -129,6 +129,13 @@ throw GraalInternalError.shouldNotReachHere(); } break; + case ACMP: + if (asConstant(y).isNull()) { + masm.cmpq(address.toAddress(), 0); + } else { + throw GraalInternalError.shouldNotReachHere(); + } + break; default: throw GraalInternalError.shouldNotReachHere(); }