# HG changeset patch # User Doug Simon # Date 1401123321 -7200 # Node ID 7c84f0ce7cae9a60200d764a38da4675764df735 # Parent 6aa352b260f4873e9f5b3dcc3e6339f74e4a291a# Parent 67e0015b21d681b9f6e2d09bf76e082377ad9134 Merge. diff -r 6aa352b260f4 -r 7c84f0ce7cae graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/Constant.java --- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/Constant.java Mon May 26 18:55:06 2014 +0200 +++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/Constant.java Mon May 26 18:55:21 2014 +0200 @@ -63,7 +63,7 @@ assert NULL_OBJECT.isNull(); } - protected Constant(Kind kind) { + protected Constant(PlatformKind kind) { super(kind); } diff -r 6aa352b260f4 -r 7c84f0ce7cae graal/com.oracle.graal.asm/src/com/oracle/graal/asm/Buffer.java --- a/graal/com.oracle.graal.asm/src/com/oracle/graal/asm/Buffer.java Mon May 26 18:55:06 2014 +0200 +++ b/graal/com.oracle.graal.asm/src/com/oracle/graal/asm/Buffer.java Mon May 26 18:55:21 2014 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 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 @@ -48,7 +48,7 @@ /** * Closes this buffer. No extra data can be written to this buffer after this call. - * + * * @param trimmedCopy if {@code true}, then a copy of the underlying byte array up to (but not * including) {@code position()} is returned * @return the data in this buffer or a trimmed copy if {@code trimmedCopy} is {@code true} @@ -68,7 +68,7 @@ /** * Copies the data from this buffer into a given array. - * + * * @param dst the destination array * @param off starting position in {@code dst} * @param len number of bytes to copy @@ -114,7 +114,7 @@ } public int emitByte(int b, int pos) { - assert NumUtil.isUByte(b); + assert NumUtil.isUByte(b) || NumUtil.isByte(b); int newPos = pos + 1; ensureSize(newPos); data[pos] = (byte) (b & 0xFF); @@ -139,7 +139,7 @@ @Override public int emitShort(int b, int pos) { - assert NumUtil.isUShort(b); + assert NumUtil.isUShort(b) || NumUtil.isShort(b); int newPos = pos + 2; ensureSize(pos + 2); data[pos] = (byte) ((b >> 8) & 0xFF); @@ -188,7 +188,7 @@ @Override public int emitShort(int b, int pos) { - assert NumUtil.isUShort(b); + assert NumUtil.isUShort(b) || NumUtil.isShort(b); int newPos = pos + 2; ensureSize(newPos); data[pos] = (byte) (b & 0xFF); diff -r 6aa352b260f4 -r 7c84f0ce7cae graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64LIRGenerator.java --- a/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64LIRGenerator.java Mon May 26 18:55:06 2014 +0200 +++ b/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64LIRGenerator.java Mon May 26 18:55:21 2014 +0200 @@ -131,13 +131,7 @@ @Override public Variable emitMove(Value input) { - PlatformKind kind; - if (input instanceof Constant) { - kind = input.getKind().getStackKind(); - } else { - kind = input.getPlatformKind(); - } - Variable result = newVariable(kind); + Variable result = newVariable(input.getPlatformKind()); emitMove(result, input); return result; } @@ -248,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)); } } @@ -267,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)); } } @@ -299,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; } @@ -376,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: @@ -399,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(); } diff -r 6aa352b260f4 -r 7c84f0ce7cae graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/AbstractObjectStamp.java --- a/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/AbstractObjectStamp.java Mon May 26 18:55:06 2014 +0200 +++ b/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/AbstractObjectStamp.java Mon May 26 18:55:21 2014 +0200 @@ -53,6 +53,12 @@ } @Override + public Stamp constant(Constant c, MetaAccessProvider meta) { + ResolvedJavaType constType = c.isNull() ? null : meta.lookupJavaType(c); + return copyWith(constType, c.isNonNull(), c.isNonNull(), c.isNull()); + } + + @Override public boolean isLegal() { return !exactType || (type != null && (isConcreteType(type))); } diff -r 6aa352b260f4 -r 7c84f0ce7cae graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/FloatStamp.java --- a/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/FloatStamp.java Mon May 26 18:55:06 2014 +0200 +++ b/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/FloatStamp.java Mon May 26 18:55:21 2014 +0200 @@ -54,6 +54,12 @@ } @Override + public Stamp constant(Constant c, MetaAccessProvider meta) { + assert c.getKind().isNumericFloat() && c.getKind().getBitCount() == getBits(); + return StampFactory.forConstant(c); + } + + @Override public boolean isLegal() { return lowerBound <= upperBound || !nonNaN; } diff -r 6aa352b260f4 -r 7c84f0ce7cae graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/IllegalStamp.java --- a/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/IllegalStamp.java Mon May 26 18:55:06 2014 +0200 +++ b/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/IllegalStamp.java Mon May 26 18:55:21 2014 +0200 @@ -55,6 +55,11 @@ } @Override + public Stamp constant(Constant c, MetaAccessProvider meta) { + throw GraalInternalError.shouldNotReachHere("illegal stamp has no value"); + } + + @Override public ResolvedJavaType javaType(MetaAccessProvider metaAccess) { throw GraalInternalError.shouldNotReachHere("illegal stamp has no Java type"); } diff -r 6aa352b260f4 -r 7c84f0ce7cae graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/IntegerStamp.java --- a/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/IntegerStamp.java Mon May 26 18:55:06 2014 +0200 +++ b/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/IntegerStamp.java Mon May 26 18:55:21 2014 +0200 @@ -64,6 +64,12 @@ } @Override + public Stamp constant(Constant c, MetaAccessProvider meta) { + long value = c.asLong(); + return StampFactory.forInteger(getBits(), value, value); + } + + @Override public boolean isLegal() { return lowerBound <= upperBound; } diff -r 6aa352b260f4 -r 7c84f0ce7cae graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/Stamp.java --- a/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/Stamp.java Mon May 26 18:55:06 2014 +0200 +++ b/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/Stamp.java Mon May 26 18:55:21 2014 +0200 @@ -88,6 +88,15 @@ public abstract Stamp illegal(); /** + * If it is possible to represent single value stamps of this kind, this method returns the + * stamp representing the single value c. stamp.constant(c).asConstant() should be equal to c. + *

+ * If it is not possible to represent single value stamps, this method returns a stamp that + * includes c, and is otherwise as narrow as possible. + */ + public abstract Stamp constant(Constant c, MetaAccessProvider meta); + + /** * Test whether two stamps have the same base type. */ public abstract boolean isCompatible(Stamp other); diff -r 6aa352b260f4 -r 7c84f0ce7cae graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/StampFactory.java --- a/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/StampFactory.java Mon May 26 18:55:06 2014 +0200 +++ b/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/StampFactory.java Mon May 26 18:55:21 2014 +0200 @@ -195,7 +195,6 @@ } public static Stamp forConstant(Constant value, MetaAccessProvider metaAccess) { - assert value.getKind() == Kind.Object; if (value.getKind() == Kind.Object) { ResolvedJavaType type = value.isNull() ? null : metaAccess.lookupJavaType(value); return new ObjectStamp(type, value.isNonNull(), value.isNonNull(), value.isNull()); diff -r 6aa352b260f4 -r 7c84f0ce7cae graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/VoidStamp.java --- a/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/VoidStamp.java Mon May 26 18:55:06 2014 +0200 +++ b/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/VoidStamp.java Mon May 26 18:55:21 2014 +0200 @@ -102,6 +102,11 @@ return true; } + @Override + public Stamp constant(Constant c, MetaAccessProvider meta) { + throw GraalInternalError.shouldNotReachHere("void stamp has no value"); + } + private static VoidStamp instance = new VoidStamp(); static VoidStamp getInstance() { diff -r 6aa352b260f4 -r 7c84f0ce7cae graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotCompare.java --- /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 18:55:21 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(); + } + } + } + +} diff -r 6aa352b260f4 -r 7c84f0ce7cae 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 Mon May 26 18:55:06 2014 +0200 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerator.java Mon May 26 18:55:21 2014 +0200 @@ -39,6 +39,7 @@ import com.oracle.graal.compiler.common.calc.*; import com.oracle.graal.hotspot.*; import com.oracle.graal.hotspot.HotSpotVMConfig.CompressEncoding; +import com.oracle.graal.hotspot.amd64.AMD64HotSpotMove.HotSpotStoreConstantOp; import com.oracle.graal.hotspot.data.*; import com.oracle.graal.hotspot.meta.*; import com.oracle.graal.hotspot.nodes.*; @@ -55,7 +56,6 @@ import com.oracle.graal.lir.amd64.AMD64Move.LoadOp; import com.oracle.graal.lir.amd64.AMD64Move.MoveFromRegOp; import com.oracle.graal.lir.amd64.AMD64Move.MoveToRegOp; -import com.oracle.graal.lir.amd64.AMD64Move.StoreConstantOp; import com.oracle.graal.lir.amd64.AMD64Move.StoreOp; import com.oracle.graal.lir.asm.*; import com.oracle.graal.lir.gen.*; @@ -480,7 +480,7 @@ if (isConstant(inputVal)) { Constant c = asConstant(inputVal); if (canStoreConstant(c, false)) { - append(new StoreConstantOp(getMemoryKind(kind), storeAddress, c, state)); + append(new HotSpotStoreConstantOp(getMemoryKind(kind), storeAddress, c, state)); return; } } @@ -499,8 +499,7 @@ 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))); + base = emitMove(Constant.forLong(encoding.base)); } append(new AMD64HotSpotMove.CompressPointer(result, asAllocatable(pointer), base, encoding, nonNull)); return result; @@ -518,8 +517,7 @@ 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))); + base = emitMove(Constant.forLong(encoding.base)); } append(new AMD64HotSpotMove.UncompressPointer(result, asAllocatable(pointer), base, encoding, nonNull)); return result; @@ -528,7 +526,9 @@ @Override protected AMD64LIRInstruction createMove(AllocatableValue dst, Value src) { - if (dst.getPlatformKind() == NarrowOopStamp.NarrowOop) { + if (src instanceof Constant) { + return new AMD64HotSpotMove.HotSpotLoadConstantOp(dst, (Constant) src); + } else if (dst.getPlatformKind() == NarrowOopStamp.NarrowOop) { if (isRegister(src) || isStackSlot(dst)) { return new MoveFromRegOp(Kind.Int, dst, src); } else { @@ -641,4 +641,35 @@ assert address.getKind() == Kind.Object : address + " - " + address.getKind() + " not an object!"; append(new AMD64Move.NullCheckOp(load(address), state)); } + + @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; + } else if (c instanceof HotSpotObjectConstant) { + return HotSpotObjectConstant.isCompressed(c); + } else { + return super.canInlineConstant(c); + } + } } diff -r 6aa352b260f4 -r 7c84f0ce7cae 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 Mon May 26 18:55:06 2014 +0200 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotMove.java Mon May 26 18:55:21 2014 +0200 @@ -36,6 +36,7 @@ import com.oracle.graal.hotspot.data.*; import com.oracle.graal.hotspot.meta.*; import com.oracle.graal.lir.*; +import com.oracle.graal.lir.StandardOp.MoveOp; import com.oracle.graal.lir.amd64.*; import com.oracle.graal.lir.amd64.AMD64Move.LoadOp; import com.oracle.graal.lir.amd64.AMD64Move.StoreConstantOp; @@ -75,6 +76,125 @@ } } + public static class HotSpotLoadConstantOp extends AMD64LIRInstruction implements MoveOp { + + @Def({REG, STACK}) private AllocatableValue result; + private final Constant input; + + public HotSpotLoadConstantOp(AllocatableValue result, Constant input) { + this.result = result; + this.input = input; + } + + @Override + public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) { + if (HotSpotCompressedNullConstant.COMPRESSED_NULL.equals(input)) { + if (isRegister(result)) { + masm.movl(asRegister(result), 0); + } else { + assert isStackSlot(result); + masm.movl((AMD64Address) crb.asAddress(result), 0); + } + } else if (input instanceof HotSpotObjectConstant) { + boolean compressed = HotSpotObjectConstant.isCompressed(input); + OopData data = new OopData(compressed ? 4 : 8, HotSpotObjectConstant.asObject(input), compressed); + if (crb.target.inlineObjects) { + crb.recordInlineDataInCode(data); + if (isRegister(result)) { + if (compressed) { + masm.movl(asRegister(result), 0xDEADDEAD); + } else { + masm.movq(asRegister(result), 0xDEADDEADDEADDEADL); + } + } else { + assert isStackSlot(result); + if (compressed) { + masm.movl((AMD64Address) crb.asAddress(result), 0xDEADDEAD); + } else { + throw GraalInternalError.shouldNotReachHere("Cannot store 64-bit constants to memory"); + } + } + } else { + if (isRegister(result)) { + AMD64Address address = (AMD64Address) crb.recordDataReferenceInCode(data); + if (compressed) { + masm.movl(asRegister(result), address); + } else { + masm.movq(asRegister(result), address); + } + } else { + throw GraalInternalError.shouldNotReachHere("Cannot directly store data patch to memory"); + } + } + } else if (input instanceof HotSpotMetaspaceConstant) { + assert input.getKind() == Kind.Int || input.getKind() == Kind.Long; + boolean compressed = input.getKind() == Kind.Int; + MetaspaceData data = new MetaspaceData(compressed ? 4 : 8, input.asLong(), HotSpotMetaspaceConstant.getMetaspaceObject(input), compressed); + crb.recordInlineDataInCode(data); + if (isRegister(result)) { + if (compressed) { + masm.movl(asRegister(result), input.asInt()); + } else { + masm.movq(asRegister(result), input.asLong()); + } + } else { + assert isStackSlot(result); + if (compressed) { + masm.movl((AMD64Address) crb.asAddress(result), input.asInt()); + } else { + throw GraalInternalError.shouldNotReachHere("Cannot store 64-bit constants to memory"); + } + } + } else { + AMD64Move.move(crb, masm, result, input); + } + } + + public Value getInput() { + return input; + } + + public AllocatableValue getResult() { + return result; + } + } + + public static class HotSpotStoreConstantOp extends StoreConstantOp { + + public HotSpotStoreConstantOp(Kind kind, AMD64AddressValue address, Constant input, LIRFrameState state) { + super(kind, address, input, state); + } + + @Override + public void emitMemAccess(CompilationResultBuilder crb, AMD64MacroAssembler masm) { + if (input.isNull() && kind == Kind.Int) { + // compressed null + masm.movl(address.toAddress(), 0); + } else if (input instanceof HotSpotObjectConstant) { + if (HotSpotObjectConstant.isCompressed(input) && crb.target.inlineObjects) { + // compressed oop + crb.recordInlineDataInCode(new OopData(0, HotSpotObjectConstant.asObject(input), true)); + masm.movl(address.toAddress(), 0xDEADDEAD); + } else { + // uncompressed oop + throw GraalInternalError.shouldNotReachHere("Cannot store 64-bit constants to memory"); + } + } else if (input instanceof HotSpotMetaspaceConstant) { + if (input.getKind() == Kind.Int) { + // compressed metaspace pointer + crb.recordInlineDataInCode(new MetaspaceData(0, input.asInt(), HotSpotMetaspaceConstant.getMetaspaceObject(input), true)); + masm.movl(address.toAddress(), input.asInt()); + } else { + // uncompressed metaspace pointer + throw GraalInternalError.shouldNotReachHere("Cannot store 64-bit constants to memory"); + } + } else { + // primitive value + super.emitMemAccess(crb, masm); + } + } + } + public static class CompressPointer extends AMD64LIRInstruction { private final CompressEncoding encoding; diff -r 6aa352b260f4 -r 7c84f0ce7cae 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 Mon May 26 18:55:06 2014 +0200 +++ b/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotLIRGenerator.java Mon May 26 18:55:21 2014 +0200 @@ -122,6 +122,9 @@ HSAILAddressValue storeAddress = asAddressValue(address); if (isConstant(inputVal)) { Constant c = asConstant(inputVal); + if (HotSpotCompressedNullConstant.COMPRESSED_NULL.equals(c)) { + c = Constant.INT_0; + } if (canStoreConstant(c, false)) { append(new StoreConstantOp(getMemoryKind(kind), storeAddress, c, state)); return; @@ -224,7 +227,9 @@ @Override protected HSAILLIRInstruction createMove(AllocatableValue dst, Value src) { if (dst.getPlatformKind() == NarrowOopStamp.NarrowOop) { - if (isRegister(src) || isStackSlot(dst)) { + if (HotSpotCompressedNullConstant.COMPRESSED_NULL.equals(src)) { + return new MoveToRegOp(Kind.Int, dst, Constant.INT_0); + } else if (isRegister(src) || isStackSlot(dst)) { return new MoveFromRegOp(Kind.Int, dst, src); } else { return new MoveToRegOp(Kind.Int, dst, src); @@ -291,5 +296,4 @@ emitMove(obj, address); append(new HSAILMove.NullCheckOp(obj, state)); } - } diff -r 6aa352b260f4 -r 7c84f0ce7cae graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotCompressedNullConstant.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotCompressedNullConstant.java Mon May 26 18:55:21 2014 +0200 @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2014, 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.meta; + +import com.oracle.graal.api.meta.*; +import com.oracle.graal.hotspot.nodes.type.*; + +/** + * The compressed representation of the {@link Constant#NULL_OBJECT null constant}. + */ +public final class HotSpotCompressedNullConstant extends Constant implements HotSpotConstant { + + private static final long serialVersionUID = 8906209595800783961L; + + public static final Constant COMPRESSED_NULL = new HotSpotCompressedNullConstant(); + + private HotSpotCompressedNullConstant() { + super(NarrowOopStamp.NarrowOop); + } + + @Override + public boolean isNull() { + return true; + } + + @Override + public boolean isDefaultForKind() { + return true; + } + + @Override + public Object asBoxedPrimitive() { + throw new IllegalArgumentException(); + } + + @Override + public int asInt() { + throw new IllegalArgumentException(); + } + + @Override + public boolean asBoolean() { + throw new IllegalArgumentException(); + } + + @Override + public long asLong() { + throw new IllegalArgumentException(); + } + + @Override + public float asFloat() { + throw new IllegalArgumentException(); + } + + @Override + public double asDouble() { + throw new IllegalArgumentException(); + } + + @Override + public String toValueString() { + return "null"; + } + + @Override + public int hashCode() { + return System.identityHashCode(this); + } + + @Override + public boolean equals(Object o) { + assert o == this || !(o instanceof HotSpotCompressedNullConstant) : "null constant is a singleton"; + return o == this; + } +} diff -r 6aa352b260f4 -r 7c84f0ce7cae graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotConstant.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotConstant.java Mon May 26 18:55:21 2014 +0200 @@ -0,0 +1,29 @@ +/* + * 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.meta; + +/** + * Marker interface for hotspot specific constants. + */ +public interface HotSpotConstant { +} diff -r 6aa352b260f4 -r 7c84f0ce7cae graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotConstantReflectionProvider.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotConstantReflectionProvider.java Mon May 26 18:55:06 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotConstantReflectionProvider.java Mon May 26 18:55:21 2014 +0200 @@ -223,7 +223,7 @@ @Override public ResolvedJavaType asJavaType(Constant constant) { - if (constant.getKind() == Kind.Object) { + if (constant instanceof HotSpotObjectConstant) { Object obj = HotSpotObjectConstant.asObject(constant); if (obj instanceof Class) { return runtime.getHostProviders().getMetaAccess().lookupJavaType((Class) obj); diff -r 6aa352b260f4 -r 7c84f0ce7cae graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMetaAccessProvider.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMetaAccessProvider.java Mon May 26 18:55:06 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMetaAccessProvider.java Mon May 26 18:55:21 2014 +0200 @@ -51,7 +51,7 @@ } public ResolvedJavaType lookupJavaType(Constant constant) { - if (constant.getKind() != Kind.Object || constant.isNull()) { + if (constant.isNull() || !(constant instanceof HotSpotObjectConstant)) { return null; } Object o = HotSpotObjectConstant.asObject(constant); diff -r 6aa352b260f4 -r 7c84f0ce7cae graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMetaspaceConstant.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMetaspaceConstant.java Mon May 26 18:55:06 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMetaspaceConstant.java Mon May 26 18:55:21 2014 +0200 @@ -26,7 +26,7 @@ import com.oracle.graal.api.meta.*; -public final class HotSpotMetaspaceConstant extends PrimitiveConstant { +public final class HotSpotMetaspaceConstant extends PrimitiveConstant implements HotSpotConstant { private static final long serialVersionUID = 1003463314013122983L; diff -r 6aa352b260f4 -r 7c84f0ce7cae graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotObjectConstant.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotObjectConstant.java Mon May 26 18:55:06 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotObjectConstant.java Mon May 26 18:55:21 2014 +0200 @@ -23,12 +23,13 @@ package com.oracle.graal.hotspot.meta; import com.oracle.graal.api.meta.*; +import com.oracle.graal.hotspot.nodes.type.*; /** * Represents a constant non-{@code null} object reference, within the compiler and across the * compiler/runtime interface. */ -public final class HotSpotObjectConstant extends Constant { +public final class HotSpotObjectConstant extends Constant implements HotSpotConstant { private static final long serialVersionUID = 3592151693708093496L; @@ -36,7 +37,7 @@ if (object == null) { return Constant.NULL_OBJECT; } else { - return new HotSpotObjectConstant(object); + return new HotSpotObjectConstant(object, false); } } @@ -59,21 +60,41 @@ public static Object asBoxedValue(Constant constant) { if (constant.isNull()) { return null; - } else if (constant.getKind() == Kind.Object) { + } else if (constant instanceof HotSpotObjectConstant) { return ((HotSpotObjectConstant) constant).object; } else { return constant.asBoxedPrimitive(); } } + public static boolean isCompressed(Constant constant) { + if (constant.isNull()) { + return HotSpotCompressedNullConstant.NULL_OBJECT.equals(constant); + } else { + return ((HotSpotObjectConstant) constant).compressed; + } + } + private final Object object; + private final boolean compressed; - private HotSpotObjectConstant(Object object) { - super(Kind.Object); + private HotSpotObjectConstant(Object object, boolean compressed) { + super(compressed ? NarrowOopStamp.NarrowOop : Kind.Object); this.object = object; + this.compressed = compressed; assert object != null; } + public Constant compress() { + assert !compressed; + return new HotSpotObjectConstant(object, true); + } + + public Constant uncompress() { + assert compressed; + return new HotSpotObjectConstant(object, false); + } + @Override public boolean isNull() { return false; @@ -135,6 +156,6 @@ @Override public String toString() { - return getKind().getJavaName() + "[" + Kind.Object.format(object) + "]"; + return (compressed ? "NarrowOop" : getKind().getJavaName()) + "[" + Kind.Object.format(object) + "]"; } } diff -r 6aa352b260f4 -r 7c84f0ce7cae graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotSuitesProvider.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotSuitesProvider.java Mon May 26 18:55:06 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotSuitesProvider.java Mon May 26 18:55:21 2014 +0200 @@ -58,7 +58,7 @@ if (ImmutableCode.getValue()) { // lowering introduces class constants, therefore it must be after lowering - ret.getHighTier().appendPhase(new LoadJavaMirrorWithKlassPhase(runtime.getConfig().classMirrorOffset)); + ret.getHighTier().appendPhase(new LoadJavaMirrorWithKlassPhase(runtime.getConfig().classMirrorOffset, runtime.getConfig().getOopEncoding())); if (VerifyPhases.getValue()) { ret.getHighTier().appendPhase(new AheadOfTimeVerificationPhase()); } diff -r 6aa352b260f4 -r 7c84f0ce7cae 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 Mon May 26 18:55:06 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/CompressionNode.java Mon May 26 18:55:21 2014 +0200 @@ -29,6 +29,7 @@ import com.oracle.graal.graph.spi.*; import com.oracle.graal.hotspot.*; import com.oracle.graal.hotspot.HotSpotVMConfig.CompressEncoding; +import com.oracle.graal.hotspot.meta.*; import com.oracle.graal.hotspot.nodes.type.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.calc.*; @@ -39,7 +40,7 @@ * Compress or uncompress an oop or metaspace pointer. */ @NodeInfo(nameTemplate = "{p#op/s}") -public final class CompressionNode extends FloatingNode implements LIRLowerable, Canonicalizable { +public final class CompressionNode extends ConvertNode implements LIRLowerable, Canonicalizable { private enum CompressionOp { Compress, @@ -49,13 +50,10 @@ 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)); + super(mkStamp(op, input.stamp(), encoding), input); this.op = op; this.encoding = encoding; - this.input = input; } public static CompressionNode compress(ValueNode input, CompressEncoding encoding) { @@ -66,6 +64,61 @@ return input.graph().unique(new CompressionNode(CompressionOp.Uncompress, input, encoding)); } + private static Constant compress(Constant c, CompressEncoding encoding) { + if (Constant.NULL_OBJECT.equals(c)) { + return HotSpotCompressedNullConstant.COMPRESSED_NULL; + } else if (c instanceof HotSpotObjectConstant) { + return ((HotSpotObjectConstant) c).compress(); + } else if (c instanceof HotSpotMetaspaceConstant) { + assert c.getKind() == Kind.Long; + return HotSpotMetaspaceConstant.forMetaspaceObject(Kind.Int, encoding.compress(c.asLong()), HotSpotMetaspaceConstant.getMetaspaceObject(c)); + } else { + throw GraalInternalError.shouldNotReachHere("invalid constant input for compress op: " + c); + } + } + + private static Constant uncompress(Constant c, CompressEncoding encoding) { + if (HotSpotCompressedNullConstant.COMPRESSED_NULL.equals(c)) { + return Constant.NULL_OBJECT; + } else if (c instanceof HotSpotObjectConstant) { + return ((HotSpotObjectConstant) c).uncompress(); + } else if (c instanceof HotSpotMetaspaceConstant) { + assert c.getKind() == Kind.Int; + return HotSpotMetaspaceConstant.forMetaspaceObject(Kind.Long, encoding.uncompress(c.asInt()), HotSpotMetaspaceConstant.getMetaspaceObject(c)); + } else { + throw GraalInternalError.shouldNotReachHere("invalid constant input for uncompress op: " + c); + } + } + + @Override + public Constant convert(Constant c) { + switch (op) { + case Compress: + return compress(c, encoding); + case Uncompress: + return uncompress(c, encoding); + default: + throw GraalInternalError.shouldNotReachHere(); + } + } + + @Override + public Constant reverse(Constant c) { + switch (op) { + case Compress: + return uncompress(c, encoding); + case Uncompress: + return compress(c, encoding); + default: + throw GraalInternalError.shouldNotReachHere(); + } + } + + @Override + public boolean isLossless() { + return true; + } + private static Stamp mkStamp(CompressionOp op, Stamp input, CompressEncoding encoding) { switch (op) { case Compress: @@ -93,20 +146,18 @@ throw GraalInternalError.shouldNotReachHere(String.format("Unexpected input stamp %s", input)); } - public ValueNode getInput() { - return input; - } - public CompressEncoding getEncoding() { return encoding; } @Override public Node canonical(CanonicalizerTool tool) { - if (input instanceof CompressionNode) { - CompressionNode other = (CompressionNode) input; + if (getInput().isConstant()) { + return ConstantNode.forConstant(stamp(), evalConst(getInput().asConstant()), tool.getMetaAccess(), graph()); + } else if (getInput() instanceof CompressionNode) { + CompressionNode other = (CompressionNode) getInput(); if (op != other.op && encoding.equals(other.encoding)) { - return other.input; + return other.getInput(); } } return this; @@ -116,8 +167,8 @@ public void generate(NodeLIRBuilderTool gen) { HotSpotLIRGenerator hsGen = (HotSpotLIRGenerator) gen.getLIRGeneratorTool(); boolean nonNull; - if (input.stamp() instanceof ObjectStamp) { - nonNull = StampTool.isObjectNonNull(input.stamp()); + if (getInput().stamp() instanceof ObjectStamp) { + nonNull = StampTool.isObjectNonNull(getInput().stamp()); } else { // metaspace pointers are never null nonNull = true; @@ -126,10 +177,10 @@ Value result; switch (op) { case Compress: - result = hsGen.emitCompress(gen.operand(input), encoding, nonNull); + result = hsGen.emitCompress(gen.operand(getInput()), encoding, nonNull); break; case Uncompress: - result = hsGen.emitUncompress(gen.operand(input), encoding, nonNull); + result = hsGen.emitUncompress(gen.operand(getInput()), encoding, nonNull); break; default: throw GraalInternalError.shouldNotReachHere(); diff -r 6aa352b260f4 -r 7c84f0ce7cae graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/phases/LoadJavaMirrorWithKlassPhase.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/phases/LoadJavaMirrorWithKlassPhase.java Mon May 26 18:55:06 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/phases/LoadJavaMirrorWithKlassPhase.java Mon May 26 18:55:21 2014 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 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 @@ -27,7 +27,9 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.compiler.common.type.*; +import com.oracle.graal.hotspot.HotSpotVMConfig.*; import com.oracle.graal.hotspot.meta.*; +import com.oracle.graal.hotspot.nodes.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.extended.*; import com.oracle.graal.phases.*; @@ -39,22 +41,24 @@ * directly. Instead the {@link Class} reference should be obtained from the {@code Klass} object. * The reason for this is, that in Class Data Sharing (CDS) a {@code Klass} object is mapped to a * fixed address in memory, but the {@code javaMirror} is not (which lives in the Java heap). - * + * * Lowering can introduce new {@link ConstantNode}s containing a {@link Class} reference, thus this * phase must be applied after {@link LoweringPhase}. - * + * * @see AheadOfTimeVerificationPhase */ public class LoadJavaMirrorWithKlassPhase extends BasePhase { private final int classMirrorOffset; + private final CompressEncoding oopEncoding; - public LoadJavaMirrorWithKlassPhase(int classMirrorOffset) { + public LoadJavaMirrorWithKlassPhase(int classMirrorOffset, CompressEncoding oopEncoding) { this.classMirrorOffset = classMirrorOffset; + this.oopEncoding = oopEncoding; } - private FloatingReadNode getClassConstantReplacement(StructuredGraph graph, PhaseContext context, Constant constant) { - if (constant.getKind() == Kind.Object && HotSpotObjectConstant.asObject(constant) instanceof Class) { + private ValueNode getClassConstantReplacement(StructuredGraph graph, PhaseContext context, Constant constant) { + if (constant instanceof HotSpotObjectConstant && HotSpotObjectConstant.asObject(constant) instanceof Class) { MetaAccessProvider metaAccess = context.getMetaAccess(); ResolvedJavaType type = metaAccess.lookupJavaType((Class) HotSpotObjectConstant.asObject(constant)); assert type instanceof HotSpotResolvedObjectType; @@ -65,7 +69,12 @@ Stamp stamp = StampFactory.exactNonNull(metaAccess.lookupJavaType(Class.class)); LocationNode location = ConstantLocationNode.create(FINAL_LOCATION, Kind.Object, classMirrorOffset, graph); FloatingReadNode freadNode = graph.unique(new FloatingReadNode(klassNode, location, null, stamp)); - return freadNode; + + if (HotSpotObjectConstant.isCompressed(constant)) { + return CompressionNode.compress(freadNode, oopEncoding); + } else { + return freadNode; + } } return null; } @@ -74,7 +83,7 @@ protected void run(StructuredGraph graph, PhaseContext context) { for (ConstantNode node : getConstantNodes(graph)) { Constant constant = node.asConstant(); - FloatingReadNode freadNode = getClassConstantReplacement(graph, context, constant); + ValueNode freadNode = getClassConstantReplacement(graph, context, constant); if (freadNode != null) { node.replace(graph, freadNode); } diff -r 6aa352b260f4 -r 7c84f0ce7cae graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Compare.java --- a/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Compare.java Mon May 26 18:55:06 2014 +0200 +++ b/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Compare.java Mon May 26 18:55:21 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(); } diff -r 6aa352b260f4 -r 7c84f0ce7cae graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ConstantNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ConstantNode.java Mon May 26 18:55:06 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ConstantNode.java Mon May 26 18:55:21 2014 +0200 @@ -153,13 +153,7 @@ } public static ConstantNode forConstant(Stamp stamp, Constant constant, MetaAccessProvider metaAccess, StructuredGraph graph) { - if (stamp instanceof PrimitiveStamp) { - return forPrimitive(stamp, constant, graph); - } else { - ConstantNode ret = forConstant(constant, metaAccess, graph); - assert ret.stamp().isCompatible(stamp); - return ret; - } + return graph.unique(new ConstantNode(constant, stamp.constant(constant, metaAccess))); } /** diff -r 6aa352b260f4 -r 7c84f0ce7cae graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/CompareNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/CompareNode.java Mon May 26 18:55:06 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/CompareNode.java Mon May 26 18:55:21 2014 +0200 @@ -126,14 +126,14 @@ } } else if (x() instanceof ConvertNode && y().isConstant()) { ConvertNode convertX = (ConvertNode) x(); - ConstantNode newY = canonicalConvertConstant(convertX, y().asConstant()); + ConstantNode newY = canonicalConvertConstant(tool, convertX, y().asConstant()); if (newY != null) { setX(convertX.getInput()); setY(newY); } } else if (y() instanceof ConvertNode && x().isConstant()) { ConvertNode convertY = (ConvertNode) y(); - ConstantNode newX = canonicalConvertConstant(convertY, x().asConstant()); + ConstantNode newX = canonicalConvertConstant(tool, convertY, x().asConstant()); if (newX != null) { setX(newX); setY(convertY.getInput()); @@ -142,11 +142,11 @@ return this; } - private ConstantNode canonicalConvertConstant(ConvertNode convert, Constant constant) { + private ConstantNode canonicalConvertConstant(CanonicalizerTool tool, ConvertNode convert, Constant constant) { if (convert.preservesOrder(condition())) { Constant reverseConverted = convert.reverse(constant); if (convert.convert(reverseConverted).equals(constant)) { - return ConstantNode.forPrimitive(convert.getInput().stamp(), reverseConverted, convert.graph()); + return ConstantNode.forConstant(convert.getInput().stamp(), reverseConverted, tool.getMetaAccess(), convert.graph()); } } return null; diff -r 6aa352b260f4 -r 7c84f0ce7cae graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/NarrowNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/NarrowNode.java Mon May 26 18:55:06 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/NarrowNode.java Mon May 26 18:55:21 2014 +0200 @@ -41,7 +41,8 @@ } public static long narrow(long value, int resultBits) { - return value & IntegerStamp.defaultMask(resultBits); + long ret = value & IntegerStamp.defaultMask(resultBits); + return SignExtendNode.signExtend(ret, resultBits); } @Override diff -r 6aa352b260f4 -r 7c84f0ce7cae graal/com.oracle.graal.test/src/com/oracle/graal/test/GCAfterTestDecorator.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.test/src/com/oracle/graal/test/GCAfterTestDecorator.java Mon May 26 18:55:21 2014 +0200 @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2014, 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.test; + +import org.junit.runner.*; + +public class GCAfterTestDecorator extends GraalJUnitRunListenerDecorator { + + public GCAfterTestDecorator(GraalJUnitRunListener l) { + super(l); + } + + @Override + public void testFinished(Description description) { + System.gc(); + super.testFinished(description); + } +} diff -r 6aa352b260f4 -r 7c84f0ce7cae graal/com.oracle.graal.test/src/com/oracle/graal/test/GraalJUnitCore.java --- a/graal/com.oracle.graal.test/src/com/oracle/graal/test/GraalJUnitCore.java Mon May 26 18:55:06 2014 +0200 +++ b/graal/com.oracle.graal.test/src/com/oracle/graal/test/GraalJUnitCore.java Mon May 26 18:55:21 2014 +0200 @@ -51,6 +51,7 @@ boolean enableTiming = false; boolean color = false; boolean eagerStackTrace = false; + boolean gcAfterTest = false; for (String each : args) { if (each.charAt(0) == '-') { // command line arguments @@ -62,6 +63,8 @@ color = true; } else if (each.contentEquals("-JUnitEagerStackTrace")) { eagerStackTrace = true; + } else if (each.contentEquals("-JUnitGCAfterTest")) { + gcAfterTest = true; } else { system.out().println("Unknown command line argument: " + each); } @@ -92,6 +95,9 @@ if (eagerStackTrace) { graalListener = new EagerStackTraceDecorator(graalListener); } + if (gcAfterTest) { + graalListener = new GCAfterTestDecorator(graalListener); + } junitCore.addListener(GraalTextListener.createRunListener(graalListener)); Result result = junitCore.run(classes.toArray(new Class[0])); for (Failure each : missingClasses) { diff -r 6aa352b260f4 -r 7c84f0ce7cae mx/mx_graal.py --- a/mx/mx_graal.py Mon May 26 18:55:06 2014 +0200 +++ b/mx/mx_graal.py Mon May 26 18:55:21 2014 +0200 @@ -970,7 +970,7 @@ f_testfile.close() harness(projectscp, vmArgs) -def _unittest(args, annotations, prefixcp="", whitelist=None, verbose=False, enable_timing=False, regex=None, color=False, eager_stacktrace=False): +def _unittest(args, annotations, prefixcp="", whitelist=None, verbose=False, enable_timing=False, regex=None, color=False, eager_stacktrace=False, gc_after_test=False): mxdir = dirname(__file__) name = 'JUnitWrapper' javaSource = join(mxdir, name + '.java') @@ -993,6 +993,8 @@ coreArgs.append('-JUnitColor') if eager_stacktrace: coreArgs.append('-JUnitEagerStackTrace') + if gc_after_test: + coreArgs.append('-JUnitGCAfterTest') def harness(projectscp, vmArgs): @@ -1025,6 +1027,7 @@ --regex run only testcases matching a regular expression --color enable colors output --eager-stacktrace print stacktrace eagerly + --gc-after-test force a GC after each test To avoid conflicts with VM options '--' can be used as delimiter. @@ -1067,6 +1070,7 @@ parser.add_argument('--regex', help='run only testcases matching a regular expression', metavar='') parser.add_argument('--color', help='enable color output', action='store_true') parser.add_argument('--eager-stacktrace', help='print stacktrace eagerly', action='store_true') + parser.add_argument('--gc-after-test', help='force a GC after each test', action='store_true') ut_args = [] delimiter = False @@ -1824,7 +1828,7 @@ out = args[0] elif len(args) > 1: mx.abort('jacocoreport takes only one argument : an output directory') - mx.run_java(['-jar', jacocoreport.get_path(True), '-in', 'jacoco.exec', '-g', join(_graal_home, 'graal'), out]) + mx.run_java(['-jar', jacocoreport.get_path(True), '--in', 'jacoco.exec', '--out', out] + [p.dir for p in mx.projects()]) def sl(args): """run an SL program""" diff -r 6aa352b260f4 -r 7c84f0ce7cae mx/projects --- a/mx/projects Mon May 26 18:55:06 2014 +0200 +++ b/mx/projects Mon May 26 18:55:21 2014 +0200 @@ -36,8 +36,8 @@ library@JACOCOAGENT@sha1=2f73a645b02e39290e577ce555f00b02004650b0 library@JACOCOREPORT@path=lib/jacocoreport.jar -library@JACOCOREPORT@urls=http://lafo.ssw.uni-linz.ac.at/jacoco/jacocoreport-0.7.1-1.jar -library@JACOCOREPORT@sha1=0c5db714804416dd1df4d8110762136ce3d5c7dc +library@JACOCOREPORT@urls=http://lafo.ssw.uni-linz.ac.at/jacoco/jacocoreport-0.7.1-2.jar +library@JACOCOREPORT@sha1=a630436391832d697a12c8f7daef8655d7a1efd2 library@DACAPO_SCALA@path=lib/dacapo-scala-0.1.0-20120216.jar library@DACAPO_SCALA@urls=http://repo.scalabench.org/snapshots/org/scalabench/benchmarks/scala-benchmark-suite/0.1.0-SNAPSHOT/scala-benchmark-suite-0.1.0-20120216.103539-3.jar