# HG changeset patch # User Lukas Stadler # Date 1328263558 -3600 # Node ID 12558f571128ebe530387090f6543ea36e423225 # Parent 73f56093d824993266297b5abedab03bf2648b0e simplifications to instanceof and checkcast hints diff -r 73f56093d824 -r 12558f571128 graal/com.oracle.max.cri/src/com/oracle/max/cri/xir/RiXirGenerator.java --- a/graal/com.oracle.max.cri/src/com/oracle/max/cri/xir/RiXirGenerator.java Fri Feb 03 10:21:02 2012 +0100 +++ b/graal/com.oracle.max.cri/src/com/oracle/max/cri/xir/RiXirGenerator.java Fri Feb 03 11:05:58 2012 +0100 @@ -77,11 +77,11 @@ XirSnippet genNewMultiArray(XirSite site, XirArgument[] lengths, RiType type); - XirSnippet genCheckCast(XirSite site, XirArgument receiver, XirArgument hub, RiType type, XirArgument[] hintHubs, boolean hintsExact); + XirSnippet genCheckCast(XirSite site, XirArgument receiver, XirArgument hub, RiType type, RiResolvedType[] hints, boolean hintsExact); - XirSnippet genInstanceOf(XirSite site, XirArgument receiver, XirArgument hub, RiType type, XirArgument[] hintHubs, boolean hintsExact); + XirSnippet genInstanceOf(XirSite site, XirArgument receiver, XirArgument hub, RiType type, RiResolvedType[] hints, boolean hintsExact); - XirSnippet genMaterializeInstanceOf(XirSite site, XirArgument receiver, XirArgument hub, XirArgument trueValue, XirArgument falseValue, RiType type, XirArgument[] hintHubs, boolean hintsExact); + XirSnippet genMaterializeInstanceOf(XirSite site, XirArgument receiver, XirArgument hub, XirArgument trueValue, XirArgument falseValue, RiType type, RiResolvedType[] hints, boolean hintsExact); XirSnippet genArrayLoad(XirSite site, XirArgument array, XirArgument index, CiKind elementKind, RiType elementType); diff -r 73f56093d824 -r 12558f571128 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/gen/LIRGenerator.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/gen/LIRGenerator.java Fri Feb 03 10:21:02 2012 +0100 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/gen/LIRGenerator.java Fri Feb 03 11:05:58 2012 +0100 @@ -480,27 +480,12 @@ @Override public void visitCheckCast(CheckCastNode x) { - XirArgument[] hints = getTypeCheckHints(x); - XirSnippet snippet = xir.genCheckCast(site(x), toXirArgument(x.object()), toXirArgument(x.targetClassInstruction()), x.targetClass(), hints, x.hintsExact()); + XirSnippet snippet = xir.genCheckCast(site(x), toXirArgument(x.object()), toXirArgument(x.targetClassInstruction()), x.targetClass(), x.hints(), x.hintsExact()); emitXir(snippet, x, state(), true); // The result of a checkcast is the unmodified object, so no need to allocate a new variable for it. setResult(x, operand(x.object())); } - private XirArgument[] getTypeCheckHints(TypeCheckNode x) { - XirArgument[] hints; - if (!GraalOptions.UseInstanceOfHints || x.hints() == null || x.hints().length == 0) { - hints = new XirArgument[0]; - } else { - assert x.hints().length == x.hintInstructions().size(); - hints = new XirArgument[x.hints().length]; - for (int i = 0; i < x.hints().length; i++) { - hints[i] = toXirArgument(x.hintInstructions().get(i)); - } - } - return hints; - } - @Override public void visitMonitorEnter(MonitorEnterNode x) { CiStackSlot lockData = frameMap.allocateStackBlock(runtime.sizeOfLockData(), false); @@ -754,9 +739,8 @@ } private void emitInstanceOfBranch(InstanceOfNode x, LabelRef trueSuccessor, LabelRef falseSuccessor, LIRDebugInfo info) { - XirArgument[] hints = getTypeCheckHints(x); XirArgument obj = toXirArgument(x.object()); - XirSnippet snippet = xir.genInstanceOf(site(x), obj, toXirArgument(x.targetClassInstruction()), x.targetClass(), hints, x.hintsExact()); + XirSnippet snippet = xir.genInstanceOf(site(x), obj, toXirArgument(x.targetClassInstruction()), x.targetClass(), x.hints(), x.hintsExact()); emitXir(snippet, x, info, null, false, x.negated() ? falseSuccessor : trueSuccessor, x.negated() ? trueSuccessor : falseSuccessor); } @@ -798,11 +782,10 @@ } private Variable emitInstanceOfConditional(InstanceOfNode x, CiValue trueValue, CiValue falseValue) { - XirArgument[] hints = getTypeCheckHints(x); XirArgument obj = toXirArgument(x.object()); XirArgument trueArg = toXirArgument(x.negated() ? falseValue : trueValue); XirArgument falseArg = toXirArgument(x.negated() ? trueValue : falseValue); - XirSnippet snippet = xir.genMaterializeInstanceOf(site(x), obj, toXirArgument(x.targetClassInstruction()), trueArg, falseArg, x.targetClass(), hints, x.hintsExact()); + XirSnippet snippet = xir.genMaterializeInstanceOf(site(x), obj, toXirArgument(x.targetClassInstruction()), trueArg, falseArg, x.targetClass(), x.hints(), x.hintsExact()); return (Variable) emitXir(snippet, null, null, false); } diff -r 73f56093d824 -r 12558f571128 graal/com.oracle.max.graal.hotspot/src/com/oracle/max/graal/hotspot/ri/HotSpotXirGenerator.java --- a/graal/com.oracle.max.graal.hotspot/src/com/oracle/max/graal/hotspot/ri/HotSpotXirGenerator.java Fri Feb 03 10:21:02 2012 +0100 +++ b/graal/com.oracle.max.graal.hotspot/src/com/oracle/max/graal/hotspot/ri/HotSpotXirGenerator.java Fri Feb 03 11:05:58 2012 +0100 @@ -666,13 +666,15 @@ // -- out of line ------------------------------------------------------- asm.bindOutOfLine(slowPath); } else { + XirOperand scratchObject = asm.createRegisterTemp("scratch", CiKind.Object, AMD64.r10); // if we get an exact match: succeed immediately for (int i = 0; i < hintCount; i++) { - XirParameter hintHub = asm.createInputParameter("hintHub" + i, CiKind.Object); + XirParameter hintHub = asm.createConstantInputParameter("hintHub" + i, CiKind.Object); + asm.mov(scratchObject, hintHub); if (i < hintCount - 1) { - asm.jeq(end, objHub, hintHub); + asm.jeq(end, objHub, scratchObject); } else { - asm.jneq(slowPath, objHub, hintHub); + asm.jneq(slowPath, objHub, scratchObject); } } asm.bindInline(end); @@ -684,8 +686,8 @@ asm.jneq(end, objHub, asm.o(null)); } } + XirOperand scratch = asm.createRegisterTemp("scratch", target.wordKind, AMD64.r10); - XirOperand scratch = asm.createRegisterTemp("scratch", target.wordKind, AMD64.r10); asm.mov(scratch, wordConst(asm, 2)); asm.callRuntime(CiRuntimeCall.Deoptimize, null); @@ -722,19 +724,21 @@ asm.jmp(trueSucc); } else { XirLabel slowPath = null; + XirOperand scratchObject = asm.createRegisterTemp("scratch", CiKind.Object, AMD64.r10); // if we get an exact match: succeed immediately for (int i = 0; i < hintCount; i++) { - XirParameter hintHub = asm.createInputParameter("hintHub" + i, CiKind.Object); + XirParameter hintHub = asm.createConstantInputParameter("hintHub" + i, CiKind.Object); + asm.mov(scratchObject, hintHub); if (i < hintCount - 1) { - asm.jeq(trueSucc, objHub, hintHub); + asm.jeq(trueSucc, objHub, scratchObject); } else { if (is(EXACT_HINTS, flags)) { - asm.jneq(falseSucc, objHub, hintHub); + asm.jneq(falseSucc, objHub, scratchObject); asm.jmp(trueSucc); } else { slowPath = asm.createOutOfLineLabel("slow path"); - asm.jneq(slowPath, objHub, hintHub); + asm.jneq(slowPath, objHub, scratchObject); asm.jmp(trueSucc); } } @@ -786,18 +790,20 @@ asm.bindInline(end); } else { XirLabel slowPath = null; + XirOperand scratchObject = asm.createRegisterTemp("scratch", CiKind.Object, AMD64.r10); // if we get an exact match: succeed immediately for (int i = 0; i < hintCount; i++) { - XirParameter hintHub = asm.createInputParameter("hintHub" + i, CiKind.Object); + XirParameter hintHub = asm.createConstantInputParameter("hintHub" + i, CiKind.Object); + asm.mov(scratchObject, hintHub); if (i < hintCount - 1) { - asm.jeq(end, objHub, hintHub); + asm.jeq(end, objHub, scratchObject); } else { if (is(EXACT_HINTS, flags)) { - asm.jeq(end, objHub, hintHub); + asm.jeq(end, objHub, scratchObject); } else { slowPath = asm.createOutOfLineLabel("slow path"); - asm.jeq(end, objHub, hintHub); + asm.jeq(end, objHub, scratchObject); asm.jmp(slowPath); } } @@ -1317,54 +1323,51 @@ } @Override - public XirSnippet genCheckCast(XirSite site, XirArgument receiver, XirArgument hub, RiType type, XirArgument[] hintHubs, boolean hintsExact) { - System.out.print(hintsExact ? "+" : "-"); - if (hintHubs == null || hintHubs.length == 0) { + public XirSnippet genCheckCast(XirSite site, XirArgument receiver, XirArgument hub, RiType type, RiResolvedType[] hints, boolean hintsExact) { + if (hints == null || hints.length == 0) { return new XirSnippet(checkCastTemplates.get(site, 0), receiver, hub); } else { - XirArgument[] params = new XirArgument[hintHubs.length + 2]; + XirArgument[] params = new XirArgument[hints.length + 2]; params[0] = receiver; params[1] = hub; - for (int i = 0; i < hintHubs.length; i++) { - params[i + 2] = hintHubs[i]; + for (int i = 0; i < hints.length; i++) { + params[i + 2] = XirArgument.forObject(hints[i]); } - XirTemplate template = hintsExact ? checkCastTemplates.get(site, hintHubs.length, EXACT_HINTS) : checkCastTemplates.get(site, hintHubs.length); + XirTemplate template = hintsExact ? checkCastTemplates.get(site, hints.length, EXACT_HINTS) : checkCastTemplates.get(site, hints.length); return new XirSnippet(template, params); } } @Override - public XirSnippet genInstanceOf(XirSite site, XirArgument object, XirArgument hub, RiType type, XirArgument[] hintHubs, boolean hintsExact) { - System.out.print(hintsExact ? "+" : "-"); - if (hintHubs == null || hintHubs.length == 0) { + public XirSnippet genInstanceOf(XirSite site, XirArgument object, XirArgument hub, RiType type, RiResolvedType[] hints, boolean hintsExact) { + if (hints == null || hints.length == 0) { return new XirSnippet(instanceOfTemplates.get(site, 0), object, hub); } else { - XirArgument[] params = new XirArgument[hintHubs.length + 2]; + XirArgument[] params = new XirArgument[hints.length + 2]; params[0] = object; params[1] = hub; - for (int i = 0; i < hintHubs.length; i++) { - params[i + 2] = hintHubs[i]; + for (int i = 0; i < hints.length; i++) { + params[i + 2] = XirArgument.forObject(hints[i]); } - XirTemplate template = hintsExact ? instanceOfTemplates.get(site, hintHubs.length, EXACT_HINTS) : instanceOfTemplates.get(site, hintHubs.length); + XirTemplate template = hintsExact ? instanceOfTemplates.get(site, hints.length, EXACT_HINTS) : instanceOfTemplates.get(site, hints.length); return new XirSnippet(template, params); } } @Override - public XirSnippet genMaterializeInstanceOf(XirSite site, XirArgument object, XirArgument hub, XirArgument trueValue, XirArgument falseValue, RiType type, XirArgument[] hintHubs, boolean hintsExact) { - System.out.print(hintsExact ? "+" : "-"); - if (hintHubs == null || hintHubs.length == 0) { + public XirSnippet genMaterializeInstanceOf(XirSite site, XirArgument object, XirArgument hub, XirArgument trueValue, XirArgument falseValue, RiType type, RiResolvedType[] hints, boolean hintsExact) { + if (hints == null || hints.length == 0) { return new XirSnippet(materializeInstanceOfTemplates.get(site, 0), object, hub, trueValue, falseValue); } else { - XirArgument[] params = new XirArgument[hintHubs.length + 4]; + XirArgument[] params = new XirArgument[hints.length + 4]; params[0] = object; params[1] = hub; params[2] = trueValue; params[3] = falseValue; - for (int i = 0; i < hintHubs.length; i++) { - params[i + 4] = hintHubs[i]; + for (int i = 0; i < hints.length; i++) { + params[i + 4] = XirArgument.forObject(hints[i]); } - XirTemplate template = hintsExact ? materializeInstanceOfTemplates.get(site, hintHubs.length, EXACT_HINTS) : materializeInstanceOfTemplates.get(site, hintHubs.length); + XirTemplate template = hintsExact ? materializeInstanceOfTemplates.get(site, hints.length, EXACT_HINTS) : materializeInstanceOfTemplates.get(site, hints.length); return new XirSnippet(template, params); } } diff -r 73f56093d824 -r 12558f571128 graal/com.oracle.max.graal.java/src/com/oracle/max/graal/java/GraphBuilderPhase.java --- a/graal/com.oracle.max.graal.java/src/com/oracle/max/graal/java/GraphBuilderPhase.java Fri Feb 03 10:21:02 2012 +0100 +++ b/graal/com.oracle.max.graal.java/src/com/oracle/max/graal/java/GraphBuilderPhase.java Fri Feb 03 11:05:58 2012 +0100 @@ -719,28 +719,23 @@ instanceOfNode = new InstanceOfNode(hub, (RiResolvedType) type, object, false); } else { if (Modifier.isFinal(resolvedType.accessFlags()) || resolvedType.isArrayClass()) { - instanceOfNode = new InstanceOfNode(hub, resolvedType, object, Collections.singletonList(hub), new RiResolvedType[] {resolvedType}, true, false); + instanceOfNode = new InstanceOfNode(hub, resolvedType, object, new RiResolvedType[] {resolvedType}, true, false); } else { RiResolvedType uniqueSubtype = resolvedType.uniqueConcreteSubtype(); if (uniqueSubtype != null) { -// TTY.println("unique concrete subtype: " + uniqueSubtype); - ConstantNode subTypeHub = appendConstant(uniqueSubtype.getEncoding(RiType.Representation.ObjectHub)); - instanceOfNode = new InstanceOfNode(hub, resolvedType, object, Collections.singletonList(subTypeHub), new RiResolvedType[] {uniqueSubtype}, false, false); + instanceOfNode = new InstanceOfNode(hub, resolvedType, object, new RiResolvedType[] {uniqueSubtype}, false, false); } else { RiTypeProfile typeProfile = method.typeProfile(bci()); if (typeProfile != null && typeProfile.types != null && typeProfile.types.length > 0) { - ArrayList hintInstructions = new ArrayList<>(typeProfile.types.length); RiResolvedType[] hints = new RiResolvedType[typeProfile.types.length]; int hintCount = 0; - + int i = 0; for (RiResolvedType hint : typeProfile.types) { -// TTY.println("profiled type: " + hint); if (hint.isSubtypeOf(resolvedType)) { - hintInstructions.add(appendConstant(hint.getEncoding(RiType.Representation.ObjectHub))); hints[hintCount++] = hint; } } - instanceOfNode = new InstanceOfNode(hub, (RiResolvedType) type, object, hintInstructions, Arrays.copyOf(hints, hintCount), false, false); + instanceOfNode = new InstanceOfNode(hub, (RiResolvedType) type, object, Arrays.copyOf(hints, hintCount), false, false); } else { instanceOfNode = new InstanceOfNode(hub, (RiResolvedType) type, object, false); } diff -r 73f56093d824 -r 12558f571128 graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/java/CheckCastNode.java --- a/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/java/CheckCastNode.java Fri Feb 03 10:21:02 2012 +0100 +++ b/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/java/CheckCastNode.java Fri Feb 03 11:05:58 2012 +0100 @@ -34,6 +34,8 @@ /** * The {@code CheckCastNode} represents a {@link Bytecodes#CHECKCAST}. + * + * The {@link #targetClass()} of a CheckCastNode can be null for array store checks! */ public final class CheckCastNode extends TypeCheckNode implements Canonicalizable, LIRLowerable, Node.IterableNodeType { @@ -51,12 +53,11 @@ * @param object the instruction producing the object */ public CheckCastNode(AnchorNode anchor, ValueNode targetClassInstruction, RiResolvedType targetClass, ValueNode object) { - this(anchor, targetClassInstruction, targetClass, object, null, EMPTY_HINTS, false); + this(anchor, targetClassInstruction, targetClass, object, EMPTY_HINTS, false); } - public CheckCastNode(AnchorNode anchor, ValueNode targetClassInstruction, RiResolvedType targetClass, ValueNode object, List hintInstructions, RiResolvedType[] hints, boolean hintsExact) { - super(targetClassInstruction, targetClass, object, hintInstructions, hints, hintsExact, targetClass == null ? StampFactory.forKind(CiKind.Object) : StampFactory.declared(targetClass)); - assert targetClass != null; + public CheckCastNode(AnchorNode anchor, ValueNode targetClassInstruction, RiResolvedType targetClass, ValueNode object, RiResolvedType[] hints, boolean hintsExact) { + super(targetClassInstruction, targetClass, object, hints, hintsExact, targetClass == null ? StampFactory.forKind(CiKind.Object) : StampFactory.declared(targetClass)); this.anchor = anchor; } diff -r 73f56093d824 -r 12558f571128 graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/java/InstanceOfNode.java --- a/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/java/InstanceOfNode.java Fri Feb 03 10:21:02 2012 +0100 +++ b/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/java/InstanceOfNode.java Fri Feb 03 11:05:58 2012 +0100 @@ -51,11 +51,11 @@ * @param object the instruction producing the object input to this instruction */ public InstanceOfNode(ValueNode targetClassInstruction, RiResolvedType targetClass, ValueNode object, boolean negated) { - this(targetClassInstruction, targetClass, object, null, EMPTY_HINTS, false, negated); + this(targetClassInstruction, targetClass, object, EMPTY_HINTS, false, negated); } - public InstanceOfNode(ValueNode targetClassInstruction, RiResolvedType targetClass, ValueNode object, List hintInstructions, RiResolvedType[] hints, boolean hintsExact, boolean negated) { - super(targetClassInstruction, targetClass, object, hintInstructions, hints, hintsExact, StampFactory.illegal()); + public InstanceOfNode(ValueNode targetClassInstruction, RiResolvedType targetClass, ValueNode object, RiResolvedType[] hints, boolean hintsExact, boolean negated) { + super(targetClassInstruction, targetClass, object, hints, hintsExact, StampFactory.illegal()); this.negated = negated; assert targetClass != null; } @@ -103,7 +103,7 @@ if (tool.assumptions() != null && hints() != null && targetClass() != null) { if (!hintsExact() && hints().length == 1 && hints()[0] == targetClass().uniqueConcreteSubtype()) { tool.assumptions().recordConcreteSubtype(targetClass(), hints()[0]); - return graph().unique(new InstanceOfNode(targetClassInstruction(), targetClass(), object(), hintInstructions(), hints(), true, negated)); + return graph().unique(new InstanceOfNode(targetClassInstruction(), targetClass(), object(), hints(), true, negated)); } } return this; @@ -111,6 +111,6 @@ @Override public BooleanNode negate() { - return graph().unique(new InstanceOfNode(targetClassInstruction(), targetClass(), object(), hintInstructions(), hints(), hintsExact(), !negated)); + return graph().unique(new InstanceOfNode(targetClassInstruction(), targetClass(), object(), hints(), hintsExact(), !negated)); } } diff -r 73f56093d824 -r 12558f571128 graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/java/TypeCheckNode.java --- a/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/java/TypeCheckNode.java Fri Feb 03 10:21:02 2012 +0100 +++ b/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/java/TypeCheckNode.java Fri Feb 03 11:05:58 2012 +0100 @@ -37,7 +37,6 @@ protected static final RiResolvedType[] EMPTY_HINTS = new RiResolvedType[0]; @Input private ValueNode object; @Input private ValueNode targetClassInstruction; - @Input private final NodeInputList hintInstructions; @Data private final RiResolvedType targetClass; @Data private final RiResolvedType[] hints; @Data private final boolean hintsExact; @@ -49,12 +48,11 @@ * @param object the node which produces the object * @param kind the result type of this node */ - public TypeCheckNode(ValueNode targetClassInstruction, RiResolvedType targetClass, ValueNode object, List hintInstructions, RiResolvedType[] hints, boolean hintsExact, Stamp stamp) { + public TypeCheckNode(ValueNode targetClassInstruction, RiResolvedType targetClass, ValueNode object, RiResolvedType[] hints, boolean hintsExact, Stamp stamp) { super(stamp); this.targetClassInstruction = targetClassInstruction; this.targetClass = targetClass; this.object = object; - this.hintInstructions = new NodeInputList<>(this, hintInstructions); this.hints = hints; this.hintsExact = hintsExact; } @@ -75,10 +73,6 @@ return targetClass; } - public NodeInputList hintInstructions() { - return hintInstructions; - } - public RiResolvedType[] hints() { return hints; }