# HG changeset patch # User Doug Simon # Date 1369253610 -7200 # Node ID d734ee4f97382d04970f9652a8d120b11fe3e300 # Parent 7f92277c3a374b916495281eb418eec1500a4e33# Parent e92fdf3e155883083119adfab976d623e7f9a11a Merge. diff -r 7f92277c3a37 -r d734ee4f9738 graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/Register.java --- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/Register.java Wed May 22 17:47:24 2013 +0200 +++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/Register.java Wed May 22 22:13:30 2013 +0200 @@ -213,7 +213,8 @@ public boolean equals(Object obj) { if (obj instanceof Register) { Register other = (Register) obj; - if (number == other.number && name.equals(other.name)) { + if (number == other.number) { + assert name.equals(other.name); assert encoding == other.encoding; assert registerCategory == other.registerCategory; return true; diff -r 7f92277c3a37 -r d734ee4f9738 graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/ValueUtil.java --- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/ValueUtil.java Wed May 22 17:47:24 2013 +0200 +++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/ValueUtil.java Wed May 22 22:13:30 2013 +0200 @@ -120,7 +120,7 @@ } public static boolean sameRegister(Value v1, Value v2) { - return isRegister(v1) && isRegister(v2) && asRegister(v1) == asRegister(v2); + return isRegister(v1) && isRegister(v2) && asRegister(v1).equals(asRegister(v2)); } public static boolean sameRegister(Value v1, Value v2, Value v3) { @@ -128,7 +128,7 @@ } public static boolean differentRegisters(Value v1, Value v2) { - return !isRegister(v1) || !isRegister(v2) || asRegister(v1) != asRegister(v2); + return !isRegister(v1) || !isRegister(v2) || !asRegister(v1).equals(asRegister(v2)); } public static boolean differentRegisters(Value v1, Value v2, Value v3) { diff -r 7f92277c3a37 -r d734ee4f9738 graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/VirtualObject.java --- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/VirtualObject.java Wed May 22 17:47:24 2013 +0200 +++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/VirtualObject.java Wed May 22 22:13:30 2013 +0200 @@ -147,7 +147,8 @@ } else { Kind componentKind = type.getComponentType().getKind().getStackKind(); for (int i = 0; i < values.length; i++) { - assert values[i].getKind().getStackKind() == componentKind : values[i].getKind() + " != " + componentKind; + assert values[i].getKind().getStackKind() == componentKind || componentKind.getBitCount() >= values[i].getKind().getStackKind().getBitCount() : values[i].getKind() + " != " + + componentKind; } } diff -r 7f92277c3a37 -r d734ee4f9738 graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/Kind.java --- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/Kind.java Wed May 22 17:47:24 2013 +0200 +++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/Kind.java Wed May 22 22:13:30 2013 +0200 @@ -362,8 +362,12 @@ case Char: case Short: return 16; + case Float: + return 32; case Int: return 32; + case Double: + return 64; case Long: return 64; default: diff -r 7f92277c3a37 -r d734ee4f9738 graal/com.oracle.graal.asm.amd64/src/com/oracle/graal/asm/amd64/AMD64Address.java --- a/graal/com.oracle.graal.asm.amd64/src/com/oracle/graal/asm/amd64/AMD64Address.java Wed May 22 17:47:24 2013 +0200 +++ b/graal/com.oracle.graal.asm.amd64/src/com/oracle/graal/asm/amd64/AMD64Address.java Wed May 22 22:13:30 2013 +0200 @@ -114,11 +114,11 @@ StringBuilder s = new StringBuilder(); s.append("["); String sep = ""; - if (getBase() != Register.None) { + if (!getBase().equals(Register.None)) { s.append(getBase()); sep = " + "; } - if (getIndex() != Register.None) { + if (!getIndex().equals(Register.None)) { s.append(sep).append(getIndex()).append(" * ").append(getScale().value); sep = " + "; } diff -r 7f92277c3a37 -r d734ee4f9738 graal/com.oracle.graal.asm.amd64/src/com/oracle/graal/asm/amd64/AMD64Assembler.java --- a/graal/com.oracle.graal.asm.amd64/src/com/oracle/graal/asm/amd64/AMD64Assembler.java Wed May 22 17:47:24 2013 +0200 +++ b/graal/com.oracle.graal.asm.amd64/src/com/oracle/graal/asm/amd64/AMD64Assembler.java Wed May 22 22:13:30 2013 +0200 @@ -216,7 +216,7 @@ } protected void emitOperandHelper(Register reg, AMD64Address addr) { - assert reg != Register.None; + assert !reg.equals(Register.None); emitOperandHelper(encode(reg), addr); } @@ -230,14 +230,14 @@ AMD64Address.Scale scale = addr.getScale(); int disp = addr.getDisplacement(); - if (base == Register.Frame) { + if (base.equals(Register.Frame)) { assert frameRegister != null : "cannot use register " + Register.Frame + " in assembler with null register configuration"; base = frameRegister; } - if (base == AMD64.rip) { // also matches Placeholder + if (base.equals(AMD64.rip)) { // also matches Placeholder // [00 000 101] disp32 - assert index == Register.None : "cannot use RIP relative addressing with index register"; + assert index.equals(Register.None) : "cannot use RIP relative addressing with index register"; emitByte(0x05 | regenc); emitInt(disp); } else if (base.isValid()) { @@ -245,28 +245,28 @@ if (index.isValid()) { int indexenc = encode(index) << 3; // [base + indexscale + disp] - if (disp == 0 && base != rbp && (base != r13)) { + if (disp == 0 && !base.equals(rbp) && !base.equals(r13)) { // [base + indexscale] // [00 reg 100][ss index base] - assert index != rsp : "illegal addressing mode"; + assert !index.equals(rsp) : "illegal addressing mode"; emitByte(0x04 | regenc); emitByte(scale.log2 << 6 | indexenc | baseenc); } else if (isByte(disp)) { // [base + indexscale + imm8] // [01 reg 100][ss index base] imm8 - assert index != rsp : "illegal addressing mode"; + assert !index.equals(rsp) : "illegal addressing mode"; emitByte(0x44 | regenc); emitByte(scale.log2 << 6 | indexenc | baseenc); emitByte(disp & 0xFF); } else { // [base + indexscale + disp32] // [10 reg 100][ss index base] disp32 - assert index != rsp : "illegal addressing mode"; + assert !index.equals(rsp) : "illegal addressing mode"; emitByte(0x84 | regenc); emitByte(scale.log2 << 6 | indexenc | baseenc); emitInt(disp); } - } else if (base == rsp || (base == r12)) { + } else if (base.equals(rsp) || base.equals(r12)) { // [rsp + disp] if (disp == 0) { // [rsp] @@ -288,8 +288,8 @@ } } else { // [base + disp] - assert base != rsp && (base != r12) : "illegal addressing mode"; - if (disp == 0 && base != rbp && (base != r13)) { + assert !base.equals(rsp) && !base.equals(r12) : "illegal addressing mode"; + if (disp == 0 && !base.equals(rbp) && !base.equals(r13)) { // [base] // [00 reg base] emitByte(0x00 | regenc | baseenc); @@ -310,7 +310,7 @@ int indexenc = encode(index) << 3; // [indexscale + disp] // [00 reg 100][ss index 101] disp32 - assert index != rsp : "illegal addressing mode"; + assert !index.equals(rsp) : "illegal addressing mode"; emitByte(0x04 | regenc); emitByte(scale.log2 << 6 | indexenc | 0x05); emitInt(disp); @@ -531,7 +531,7 @@ // cmpxchg r,[m] is equivalent to X86.rax, = CAS (m, X86.rax, r) cmpl(rax, adr); movl(rax, adr); - if (reg != rax) { + if (reg.equals(rax)) { Label l = new Label(); jccb(ConditionFlag.NotEqual, l); movl(adr, reg); diff -r 7f92277c3a37 -r d734ee4f9738 graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalCompiler.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalCompiler.java Wed May 22 17:47:24 2013 +0200 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalCompiler.java Wed May 22 22:13:30 2013 +0200 @@ -125,7 +125,8 @@ } else { Debug.dump(graph, "initial state"); } - new VerifyValueUsage(runtime).apply(graph); + new VerifyUsageWithEquals(runtime, Value.class).apply(graph); + new VerifyUsageWithEquals(runtime, Register.class).apply(graph); if (GraalOptions.OptCanonicalizer) { new CanonicalizerPhase.Instance(runtime, assumptions).apply(graph); diff -r 7f92277c3a37 -r d734ee4f9738 graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/LinearScanWalker.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/LinearScanWalker.java Wed May 22 17:47:24 2013 +0200 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/LinearScanWalker.java Wed May 22 22:13:30 2013 +0200 @@ -654,12 +654,12 @@ int number = availableReg.number; if (usePos[number] >= intervalTo) { // this register is free for the full interval - if (minFullReg == null || availableReg == hint || (usePos[number] < usePos[minFullReg.number] && minFullReg != hint)) { + if (minFullReg == null || availableReg.equals(hint) || (usePos[number] < usePos[minFullReg.number] && !minFullReg.equals(hint))) { minFullReg = availableReg; } } else if (usePos[number] > regNeededUntil) { // this register is at least free until regNeededUntil - if (maxPartialReg == null || availableReg == hint || (usePos[number] > usePos[maxPartialReg.number] && maxPartialReg != hint)) { + if (maxPartialReg == null || availableReg.equals(hint) || (usePos[number] > usePos[maxPartialReg.number] && !maxPartialReg.equals(hint))) { maxPartialReg = availableReg; } } diff -r 7f92277c3a37 -r d734ee4f9738 graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotEpilogueOp.java --- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotEpilogueOp.java Wed May 22 17:47:24 2013 +0200 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotEpilogueOp.java Wed May 22 22:13:30 2013 +0200 @@ -53,7 +53,7 @@ masm.movq(rbp, (AMD64Address) tasm.asAddress(savedRbp)); } else { Register framePointer = asRegister(savedRbp); - if (framePointer != rbp) { + if (!framePointer.equals(rbp)) { masm.movq(rbp, framePointer); } } diff -r 7f92277c3a37 -r d734ee4f9738 graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64IndirectCallOp.java --- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64IndirectCallOp.java Wed May 22 17:47:24 2013 +0200 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64IndirectCallOp.java Wed May 22 22:13:30 2013 +0200 @@ -61,13 +61,13 @@ public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) { tasm.recordMark(Marks.MARK_INLINE_INVOKE); Register callReg = asRegister(targetAddress); - assert callReg != METHOD; + assert !callReg.equals(METHOD); AMD64Call.indirectCall(tasm, masm, callReg, callTarget, state); } @Override protected void verify() { super.verify(); - assert asRegister(metaspaceMethod) == METHOD; + assert asRegister(metaspaceMethod).equals(METHOD); } } diff -r 7f92277c3a37 -r d734ee4f9738 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompilationTask.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompilationTask.java Wed May 22 17:47:24 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompilationTask.java Wed May 22 22:13:30 2013 +0200 @@ -184,8 +184,8 @@ bailout.printStackTrace(TTY.cachedOut); } } catch (Throwable t) { + t.printStackTrace(TTY.cachedOut); if (GraalOptions.ExitVMOnException) { - t.printStackTrace(TTY.cachedOut); System.exit(-1); } } diff -r 7f92277c3a37 -r d734ee4f9738 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/AbstractMethodHandleNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/AbstractMethodHandleNode.java Wed May 22 17:47:24 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/AbstractMethodHandleNode.java Wed May 22 22:13:30 2013 +0200 @@ -273,9 +273,20 @@ ValueNode[] args = replacementArguments.toArray(new ValueNode[replacementArguments.size()]); callTarget = new SelfReplacingMethodCallTargetNode(invokeKind, targetMethod, targetArguments, returnType, replacementTargetMethod, args, replacementReturnType); } + graph().add(callTarget); - graph().add(callTarget); - InvokeNode invoke = graph().add(new InvokeNode(callTarget, getBci())); + // The call target can have a different return type than the invoker, + // e.g. the target returns an Object but the invoker void. In this case + // we need to use the stamp of the invoker. Note: always using the + // invoker's stamp would be wrong because it's a less concrete type + // (usually java.lang.Object). + InvokeNode invoke; + if (callTarget.returnStamp().kind() != stamp().kind()) { + invoke = new InvokeNode(callTarget, getBci(), stamp()); + } else { + invoke = new InvokeNode(callTarget, getBci()); + } + graph().add(invoke); invoke.setStateAfter(stateAfter()); return invoke; } diff -r 7f92277c3a37 -r d734ee4f9738 graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Arithmetic.java --- a/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Arithmetic.java Wed May 22 17:47:24 2013 +0200 +++ b/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Arithmetic.java Wed May 22 22:13:30 2013 +0200 @@ -273,7 +273,7 @@ protected void verify() { super.verify(); // left input in rax, right input in any register but rax and rdx, result quotient in rax, result remainder in rdx - assert asRegister(x) == AMD64.rax; + assert asRegister(x).equals(AMD64.rax); assert differentRegisters(y, AMD64.rax.asValue(), AMD64.rdx.asValue()); verifyKind(opcode, divResult, x, y); verifyKind(opcode, remResult, x, y); @@ -360,9 +360,9 @@ case IMUL: masm.imull(asIntReg(dst), asIntReg(src)); break; case IOR: masm.orl(asIntReg(dst), asIntReg(src)); break; case IXOR: masm.xorl(asIntReg(dst), asIntReg(src)); break; - case ISHL: assert asIntReg(src) == AMD64.rcx; masm.shll(asIntReg(dst)); break; - case ISHR: assert asIntReg(src) == AMD64.rcx; masm.sarl(asIntReg(dst)); break; - case IUSHR: assert asIntReg(src) == AMD64.rcx; masm.shrl(asIntReg(dst)); break; + case ISHL: assert asIntReg(src).equals(AMD64.rcx); masm.shll(asIntReg(dst)); break; + case ISHR: assert asIntReg(src).equals(AMD64.rcx); masm.sarl(asIntReg(dst)); break; + case IUSHR: assert asIntReg(src).equals(AMD64.rcx); masm.shrl(asIntReg(dst)); break; case LADD: masm.addq(asLongReg(dst), asLongReg(src)); break; case LSUB: masm.subq(asLongReg(dst), asLongReg(src)); break; @@ -370,9 +370,9 @@ case LAND: masm.andq(asLongReg(dst), asLongReg(src)); break; case LOR: masm.orq(asLongReg(dst), asLongReg(src)); break; case LXOR: masm.xorq(asLongReg(dst), asLongReg(src)); break; - case LSHL: assert asIntReg(src) == AMD64.rcx; masm.shlq(asLongReg(dst)); break; - case LSHR: assert asIntReg(src) == AMD64.rcx; masm.sarq(asLongReg(dst)); break; - case LUSHR: assert asIntReg(src) == AMD64.rcx; masm.shrq(asLongReg(dst)); break; + case LSHL: assert asIntReg(src).equals(AMD64.rcx); masm.shlq(asLongReg(dst)); break; + case LSHR: assert asIntReg(src).equals(AMD64.rcx); masm.sarq(asLongReg(dst)); break; + case LUSHR: assert asIntReg(src).equals(AMD64.rcx); masm.shrq(asLongReg(dst)); break; case FADD: masm.addss(asFloatReg(dst), asFloatReg(src)); break; case FSUB: masm.subss(asFloatReg(dst), asFloatReg(src)); break; @@ -556,6 +556,6 @@ || (opcode.name().startsWith("L") && result.getKind() == Kind.Long && x.getKind() == Kind.Long && y.getKind() == Kind.Long) || (opcode.name().startsWith("F") && result.getKind() == Kind.Float && x.getKind() == Kind.Float && y.getKind() == Kind.Float) || (opcode.name().startsWith("D") && result.getKind() == Kind.Double && x.getKind() == Kind.Double && y.getKind() == Kind.Double) - || (opcode.name().matches(".U?SH.") && result.getKind() == x.getKind() && y.getKind() == Kind.Int && (isConstant(y) || asRegister(y) == AMD64.rcx)); + || (opcode.name().matches(".U?SH.") && result.getKind() == x.getKind() && y.getKind() == Kind.Int && (isConstant(y) || asRegister(y).equals(AMD64.rcx))); } } diff -r 7f92277c3a37 -r d734ee4f9738 graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64ControlFlow.java --- a/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64ControlFlow.java Wed May 22 17:47:24 2013 +0200 +++ b/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64ControlFlow.java Wed May 22 22:13:30 2013 +0200 @@ -404,7 +404,7 @@ private static void cmove(TargetMethodAssembler tasm, AMD64MacroAssembler masm, Value result, ConditionFlag cond, Value other) { if (isRegister(other)) { - assert asRegister(other) != asRegister(result) : "other already overwritten by previous move"; + assert !asRegister(other).equals(asRegister(result)) : "other already overwritten by previous move"; switch (other.getKind()) { case Int: masm.cmovl(cond, asRegister(result), asRegister(other)); break; case Long: masm.cmovq(cond, asRegister(result), asRegister(other)); break; diff -r 7f92277c3a37 -r d734ee4f9738 graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Move.java --- a/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Move.java Wed May 22 17:47:24 2013 +0200 +++ b/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Move.java Wed May 22 22:13:30 2013 +0200 @@ -526,7 +526,7 @@ } protected static void compareAndSwap(TargetMethodAssembler tasm, AMD64MacroAssembler masm, AllocatableValue result, AMD64AddressValue address, AllocatableValue cmpValue, AllocatableValue newValue) { - assert asRegister(cmpValue) == AMD64.rax && asRegister(result) == AMD64.rax; + assert asRegister(cmpValue).equals(AMD64.rax) && asRegister(result).equals(AMD64.rax); if (tasm.target.isMP) { masm.lock(); diff -r 7f92277c3a37 -r d734ee4f9738 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/InvokeNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/InvokeNode.java Wed May 22 17:47:24 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/InvokeNode.java Wed May 22 22:13:30 2013 +0200 @@ -30,6 +30,7 @@ import com.oracle.graal.graph.*; import com.oracle.graal.nodes.extended.*; import com.oracle.graal.nodes.spi.*; +import com.oracle.graal.nodes.type.Stamp; import com.oracle.graal.nodes.util.*; /** @@ -48,11 +49,22 @@ /** * Constructs a new Invoke instruction. * + * @param callTarget the target method being called * @param bci the bytecode index of the original invoke (used for debug infos) - * @param callTarget the target method being called */ public InvokeNode(CallTargetNode callTarget, int bci) { - super(callTarget.returnStamp()); + this(callTarget, bci, callTarget.returnStamp()); + } + + /** + * Constructs a new Invoke instruction. + * + * @param callTarget the target method being called + * @param bci the bytecode index of the original invoke (used for debug infos) + * @param stamp the stamp to be used for this value + */ + public InvokeNode(CallTargetNode callTarget, int bci, Stamp stamp) { + super(stamp); this.callTarget = callTarget; this.bci = bci; this.polymorphic = false; diff -r 7f92277c3a37 -r d734ee4f9738 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/PiNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/PiNode.java Wed May 22 17:47:24 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/PiNode.java Wed May 22 22:13:30 2013 +0200 @@ -61,12 +61,6 @@ @Override public boolean inferStamp() { - if (stamp() instanceof ObjectStamp && object().objectStamp().alwaysNull() && objectStamp().nonNull()) { - // a null value flowing into a nonNull PiNode should be guarded by a type/isNull guard, - // but the - // compiler might see this situation before the branch is deleted - return false; - } return updateStamp(stamp().join(object().stamp())); } diff -r 7f92277c3a37 -r d734ee4f9738 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ValueNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ValueNode.java Wed May 22 17:47:24 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ValueNode.java Wed May 22 22:13:30 2013 +0200 @@ -60,7 +60,7 @@ * @return true if the stamp has changed, false otherwise. */ protected final boolean updateStamp(Stamp newStamp) { - if (newStamp.equals(stamp)) { + if (newStamp == null || newStamp.equals(stamp)) { return false; } else { stamp = newStamp; diff -r 7f92277c3a37 -r d734ee4f9738 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeCastNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeCastNode.java Wed May 22 17:47:24 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeCastNode.java Wed May 22 22:13:30 2013 +0200 @@ -52,12 +52,6 @@ if (stamp() == StampFactory.forNodeIntrinsic()) { return false; } - if (object().objectStamp().alwaysNull() && objectStamp().nonNull()) { - // a null value flowing into a nonNull UnsafeCastNode should be guarded by a type/isNull - // guard, but the - // compiler might see this situation before the branch is deleted - return false; - } return updateStamp(stamp().join(object().stamp())); } diff -r 7f92277c3a37 -r d734ee4f9738 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/CheckCastNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/CheckCastNode.java Wed May 22 17:47:24 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/CheckCastNode.java Wed May 22 22:13:30 2013 +0200 @@ -69,9 +69,6 @@ @Override public boolean inferStamp() { - if (object().objectStamp().alwaysNull() && objectStamp().nonNull()) { - return false; - } return updateStamp(stamp().join(object().stamp())); } diff -r 7f92277c3a37 -r d734ee4f9738 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/ObjectStamp.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/ObjectStamp.java Wed May 22 17:47:24 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/ObjectStamp.java Wed May 22 22:13:30 2013 +0200 @@ -22,6 +22,8 @@ */ package com.oracle.graal.nodes.type; +import java.lang.reflect.*; + import com.oracle.graal.api.meta.*; public class ObjectStamp extends Stamp { @@ -33,14 +35,29 @@ public ObjectStamp(ResolvedJavaType type, boolean exactType, boolean nonNull, boolean alwaysNull) { super(Kind.Object); - assert !exactType || type != null; - assert !(nonNull && alwaysNull); + assert isValid(type, exactType, nonNull, alwaysNull); this.type = type; this.exactType = exactType; this.nonNull = nonNull; this.alwaysNull = alwaysNull; } + public static boolean isValid(ResolvedJavaType type, boolean exactType, boolean nonNull, boolean alwaysNull) { + if (exactType && type == null) { + return false; + } + + if (exactType && Modifier.isAbstract(type.getModifiers()) && !type.isArray()) { + return false; + } + + if (nonNull && alwaysNull) { + return false; + } + + return true; + } + @Override public ResolvedJavaType javaType(MetaAccessProvider metaAccess) { if (type != null) { @@ -152,12 +169,19 @@ joinType = type; } } + if (joinType == type && joinExactType == exactType && joinNonNull == nonNull && joinAlwaysNull == alwaysNull) { return this; } else if (joinType == other.type && joinExactType == other.exactType && joinNonNull == other.nonNull && joinAlwaysNull == other.alwaysNull) { return other; } else { - return new ObjectStamp(joinType, joinExactType, joinNonNull, joinAlwaysNull); + if (isValid(joinType, joinExactType, joinNonNull, joinAlwaysNull)) { + return new ObjectStamp(joinType, joinExactType, joinNonNull, joinAlwaysNull); + } else { + // This situation can happen in case the compiler wants to join two contradicting + // stamps. + return null; + } } } diff -r 7f92277c3a37 -r d734ee4f9738 graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningPhase.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningPhase.java Wed May 22 17:47:24 2013 +0200 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningPhase.java Wed May 22 22:13:30 2013 +0200 @@ -255,7 +255,7 @@ callerHasMoreInformationAboutArguments = true; } else { Stamp joinedStamp = localNode.stamp().join(arg.stamp()); - if (!joinedStamp.equals(localNode.stamp())) { + if (joinedStamp != null && !joinedStamp.equals(localNode.stamp())) { localNode.setStamp(joinedStamp); callerHasMoreInformationAboutArguments = true; } diff -r 7f92277c3a37 -r d734ee4f9738 graal/com.oracle.graal.phases/src/com/oracle/graal/phases/verify/VerifyUsageWithEquals.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/verify/VerifyUsageWithEquals.java Wed May 22 22:13:30 2013 +0200 @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2013, 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.phases.verify; + +import com.oracle.graal.api.meta.*; +import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.calc.*; +import com.oracle.graal.nodes.type.*; +import com.oracle.graal.phases.*; + +public class VerifyUsageWithEquals extends VerifyPhase { + + private MetaAccessProvider runtime; + private Class klass; + + public VerifyUsageWithEquals(MetaAccessProvider runtime, Class klass) { + this.runtime = runtime; + this.klass = klass; + } + + private boolean isAssignableType(ValueNode node) { + if (node.stamp() instanceof ObjectStamp) { + ResolvedJavaType valueType = runtime.lookupJavaType(klass); + ResolvedJavaType nodeType = node.objectStamp().type(); + + if (valueType.isAssignableFrom(nodeType)) { + return true; + } + } + return false; + } + + private static boolean isNullConstant(ValueNode node) { + return node.isConstant() && node.asConstant().isNull(); + } + + private boolean checkUsage(ValueNode x, ValueNode y) { + return isAssignableType(x) && !isNullConstant(y); + } + + private static boolean isEqualsMethod(StructuredGraph graph) { + Signature signature = graph.method().getSignature(); + return graph.method().getName().equals("equals") && signature.getParameterCount(false) == 1 && signature.getParameterKind(0).equals(Kind.Object); + } + + @Override + protected boolean verify(StructuredGraph graph) { + for (ObjectEqualsNode cn : graph.getNodes().filter(ObjectEqualsNode.class)) { + if (!isEqualsMethod(graph)) { + // bail out if we compare an object of type klass with == or != (except null checks) + assert !(checkUsage(cn.x(), cn.y()) && checkUsage(cn.y(), cn.x())) : "VerifyUsage of " + klass.getName() + ": " + cn.x() + " or " + cn.y() + " in " + graph.method() + + " uses object identity. Should use equals() instead."; + } + } + return true; + } +} diff -r 7f92277c3a37 -r d734ee4f9738 graal/com.oracle.graal.phases/src/com/oracle/graal/phases/verify/VerifyValueUsage.java --- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/verify/VerifyValueUsage.java Wed May 22 17:47:24 2013 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,62 +0,0 @@ -/* - * Copyright (c) 2013, 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.phases.verify; - -import com.oracle.graal.api.meta.*; -import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.calc.*; -import com.oracle.graal.nodes.type.*; -import com.oracle.graal.phases.*; - -public class VerifyValueUsage extends VerifyPhase { - - private MetaAccessProvider runtime; - - public VerifyValueUsage(MetaAccessProvider runtime) { - this.runtime = runtime; - } - - private boolean checkType(ValueNode node) { - if (node.stamp() instanceof ObjectStamp) { - ResolvedJavaType valueType = runtime.lookupJavaType(Value.class); - ResolvedJavaType nodeType = node.objectStamp().type(); - - if (valueType.isAssignableFrom(nodeType)) { - return true; - } - } - return false; - } - - @Override - protected boolean verify(StructuredGraph graph) { - for (ObjectEqualsNode cn : graph.getNodes().filter(ObjectEqualsNode.class)) { - Signature signature = graph.method().getSignature(); - if (!(graph.method().getName().equals("equals") && signature.getParameterCount(false) == 1 && signature.getParameterKind(0).equals(Kind.Object))) { - assert !((checkType(cn.x()) && !(cn.y() instanceof ConstantNode)) || (checkType(cn.y()) && !(cn.x() instanceof ConstantNode))) : "VerifyValueUsage: " + cn.x() + " or " + cn.y() + - " in " + graph.method() + " uses object identity. Should use equals() instead."; - } - } - return true; - } -}