# HG changeset patch # User Lukas Stadler # Date 1328285626 -3600 # Node ID b494d6f329a322ce8e52099fc51aec1dd4c6e3b8 # Parent 12558f571128ebe530387090f6543ea36e423225 some more checkcast opts diff -r 12558f571128 -r b494d6f329a3 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/util/Util.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/util/Util.java Fri Feb 03 11:05:58 2012 +0100 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/util/Util.java Fri Feb 03 17:13:46 2012 +0100 @@ -22,9 +22,11 @@ */ package com.oracle.max.graal.compiler.util; +import java.lang.reflect.*; import java.util.*; import com.oracle.max.cri.ci.*; +import com.oracle.max.cri.ri.*; import com.oracle.max.criutils.*; import com.oracle.max.graal.graph.*; import com.oracle.max.graal.nodes.*; @@ -371,4 +373,8 @@ public static boolean isFloating(Node n) { return n instanceof FloatingNode; } + + public static boolean isFinalClass(RiResolvedType type) { + return Modifier.isFinal(type.accessFlags()) || (type.isArrayClass() && Modifier.isFinal(type.componentType().accessFlags())); + } } diff -r 12558f571128 -r b494d6f329a3 graal/com.oracle.max.graal.debug/src/com/oracle/max/graal/debug/Debug.java --- a/graal/com.oracle.max.graal.debug/src/com/oracle/max/graal/debug/Debug.java Fri Feb 03 11:05:58 2012 +0100 +++ b/graal/com.oracle.max.graal.debug/src/com/oracle/max/graal/debug/Debug.java Fri Feb 03 17:13:46 2012 +0100 @@ -103,7 +103,6 @@ public static void dump(Object object, String msg, Object... args) { if (ENABLED && DebugScope.getInstance().isDumpEnabled()) { - System.out.println("dumping"); DebugScope.getInstance().dump(object, msg, args); } } diff -r 12558f571128 -r b494d6f329a3 graal/com.oracle.max.graal.hotspot/src/com/oracle/max/graal/hotspot/ri/HotSpotTypeResolvedImpl.java --- a/graal/com.oracle.max.graal.hotspot/src/com/oracle/max/graal/hotspot/ri/HotSpotTypeResolvedImpl.java Fri Feb 03 11:05:58 2012 +0100 +++ b/graal/com.oracle.max.graal.hotspot/src/com/oracle/max/graal/hotspot/ri/HotSpotTypeResolvedImpl.java Fri Feb 03 17:13:46 2012 +0100 @@ -81,7 +81,11 @@ @Override public RiResolvedType uniqueConcreteSubtype() { - return (RiResolvedType) compiler.getVMEntries().RiType_uniqueConcreteSubtype(this); + if (isArrayClass()) { + return Modifier.isFinal(componentType().accessFlags()) ? this : null; + } else { + return (RiResolvedType) compiler.getVMEntries().RiType_uniqueConcreteSubtype(this); + } } @Override diff -r 12558f571128 -r b494d6f329a3 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 11:05:58 2012 +0100 +++ b/graal/com.oracle.max.graal.hotspot/src/com/oracle/max/graal/hotspot/ri/HotSpotXirGenerator.java Fri Feb 03 17:13:46 2012 +0100 @@ -643,8 +643,7 @@ protected XirTemplate create(CiXirAssembler asm, long flags, int hintCount) { asm.restart(CiKind.Void); XirParameter object = asm.createInputParameter("object", CiKind.Object); - final XirOperand hub; - hub = asm.createConstantInputParameter("hub", CiKind.Object); + final XirOperand hub = is(EXACT_HINTS, flags) ? null : asm.createConstantInputParameter("hub", CiKind.Object); XirOperand objHub = asm.createTemp("objHub", CiKind.Object); @@ -703,8 +702,7 @@ protected XirTemplate create(CiXirAssembler asm, long flags, int hintCount) { asm.restart(CiKind.Void); XirParameter object = asm.createInputParameter("object", CiKind.Object); - final XirOperand hub; - hub = asm.createConstantInputParameter("hub", CiKind.Object); + final XirOperand hub = is(EXACT_HINTS, flags) ? null : asm.createConstantInputParameter("hub", CiKind.Object); XirOperand objHub = asm.createTemp("objHub", CiKind.Object); @@ -763,8 +761,7 @@ protected XirTemplate create(CiXirAssembler asm, long flags, int hintCount) { XirOperand result = asm.restart(CiKind.Int); XirParameter object = asm.createInputParameter("object", CiKind.Object); - final XirOperand hub; - hub = asm.createConstantInputParameter("hub", CiKind.Object); + final XirOperand hub = is(EXACT_HINTS, flags) ? null : asm.createConstantInputParameter("hub", CiKind.Object); XirOperand trueValue = asm.createConstantInputParameter("trueValue", CiKind.Int); XirOperand falseValue = asm.createConstantInputParameter("falseValue", CiKind.Int); @@ -1327,11 +1324,14 @@ if (hints == null || hints.length == 0) { return new XirSnippet(checkCastTemplates.get(site, 0), receiver, hub); } else { - XirArgument[] params = new XirArgument[hints.length + 2]; - params[0] = receiver; - params[1] = hub; - for (int i = 0; i < hints.length; i++) { - params[i + 2] = XirArgument.forObject(hints[i]); + XirArgument[] params = new XirArgument[hints.length + (hintsExact ? 1 : 2)]; + int i = 0; + params[i++] = receiver; + if (!hintsExact) { + params[i++] = hub; + } + for (RiResolvedType hint : hints) { + params[i++] = XirArgument.forObject(hint); } XirTemplate template = hintsExact ? checkCastTemplates.get(site, hints.length, EXACT_HINTS) : checkCastTemplates.get(site, hints.length); return new XirSnippet(template, params); @@ -1343,11 +1343,14 @@ if (hints == null || hints.length == 0) { return new XirSnippet(instanceOfTemplates.get(site, 0), object, hub); } else { - XirArgument[] params = new XirArgument[hints.length + 2]; - params[0] = object; - params[1] = hub; - for (int i = 0; i < hints.length; i++) { - params[i + 2] = XirArgument.forObject(hints[i]); + XirArgument[] params = new XirArgument[hints.length + (hintsExact ? 1 : 2)]; + int i = 0; + params[i++] = object; + if (!hintsExact) { + params[i++] = hub; + } + for (RiResolvedType hint : hints) { + params[i++] = XirArgument.forObject(hint); } XirTemplate template = hintsExact ? instanceOfTemplates.get(site, hints.length, EXACT_HINTS) : instanceOfTemplates.get(site, hints.length); return new XirSnippet(template, params); @@ -1359,13 +1362,16 @@ if (hints == null || hints.length == 0) { return new XirSnippet(materializeInstanceOfTemplates.get(site, 0), object, hub, trueValue, falseValue); } else { - XirArgument[] params = new XirArgument[hints.length + 4]; - params[0] = object; - params[1] = hub; - params[2] = trueValue; - params[3] = falseValue; - for (int i = 0; i < hints.length; i++) { - params[i + 4] = XirArgument.forObject(hints[i]); + XirArgument[] params = new XirArgument[hints.length + (hintsExact ? 3 : 4)]; + int i = 0; + params[i++] = object; + if (!hintsExact) { + params[i++] = hub; + } + params[i++] = trueValue; + params[i++] = falseValue; + for (RiResolvedType hint : hints) { + params[i++] = XirArgument.forObject(hint); } XirTemplate template = hintsExact ? materializeInstanceOfTemplates.get(site, hints.length, EXACT_HINTS) : materializeInstanceOfTemplates.get(site, hints.length); return new XirSnippet(template, params); diff -r 12558f571128 -r b494d6f329a3 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 11:05:58 2012 +0100 +++ b/graal/com.oracle.max.graal.java/src/com/oracle/max/graal/java/GraphBuilderPhase.java Fri Feb 03 17:13:46 2012 +0100 @@ -687,6 +687,32 @@ } } + private static final RiResolvedType[] EMPTY_TYPE_ARRAY = new RiResolvedType[0]; + + private RiResolvedType[] getTypeCheckHints(RiResolvedType type, int maxHints) { + if (!GraalOptions.UseInstanceOfHints || Util.isFinalClass(type)) { + return new RiResolvedType[] {type}; + } else { + RiResolvedType uniqueSubtype = type.uniqueConcreteSubtype(); + if (uniqueSubtype != null) { + return new RiResolvedType[] {uniqueSubtype}; + } else { + RiTypeProfile typeProfile = method.typeProfile(bci()); + if (typeProfile != null && typeProfile.types != null && typeProfile.types.length > 0 && typeProfile.morphism <= maxHints) { + RiResolvedType[] hints = new RiResolvedType[typeProfile.types.length]; + int hintCount = 0; + for (RiResolvedType hint : typeProfile.types) { + if (hint.isSubtypeOf(type)) { + hints[hintCount++] = hint; + } + } + return Arrays.copyOf(hints, Math.min(maxHints, hintCount)); + } + return EMPTY_TYPE_ARRAY; + } + } + } + private void genCheckCast() { int cpi = stream().readCPI(); RiType type = lookupType(cpi, CHECKCAST); @@ -696,7 +722,13 @@ ValueNode object = frameState.apop(); AnchorNode anchor = currentGraph.add(new AnchorNode()); append(anchor); - CheckCastNode checkCast = currentGraph.unique(new CheckCastNode(anchor, typeInstruction, (RiResolvedType) type, object)); + CheckCastNode checkCast; + if (type instanceof RiResolvedType) { + RiResolvedType[] hints = getTypeCheckHints((RiResolvedType) type, 2); + checkCast = currentGraph.unique(new CheckCastNode(anchor, typeInstruction, (RiResolvedType) type, object, hints, Util.isFinalClass((RiResolvedType) type))); + } else { + checkCast = currentGraph.unique(new CheckCastNode(anchor, typeInstruction, (RiResolvedType) type, object)); + } append(currentGraph.add(new ValueAnchorNode(checkCast))); frameState.apush(checkCast); } else { @@ -714,34 +746,8 @@ RiResolvedType resolvedType = (RiResolvedType) type; ConstantNode hub = appendConstant(resolvedType.getEncoding(RiType.Representation.ObjectHub)); - final InstanceOfNode instanceOfNode; - if (!GraalOptions.UseInstanceOfHints) { - instanceOfNode = new InstanceOfNode(hub, (RiResolvedType) type, object, false); - } else { - if (Modifier.isFinal(resolvedType.accessFlags()) || resolvedType.isArrayClass()) { - instanceOfNode = new InstanceOfNode(hub, resolvedType, object, new RiResolvedType[] {resolvedType}, true, false); - } else { - RiResolvedType uniqueSubtype = resolvedType.uniqueConcreteSubtype(); - if (uniqueSubtype != null) { - 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) { - RiResolvedType[] hints = new RiResolvedType[typeProfile.types.length]; - int hintCount = 0; - int i = 0; - for (RiResolvedType hint : typeProfile.types) { - if (hint.isSubtypeOf(resolvedType)) { - hints[hintCount++] = hint; - } - } - instanceOfNode = new InstanceOfNode(hub, (RiResolvedType) type, object, Arrays.copyOf(hints, hintCount), false, false); - } else { - instanceOfNode = new InstanceOfNode(hub, (RiResolvedType) type, object, false); - } - } - } - } + RiResolvedType[] hints = getTypeCheckHints(resolvedType, 1); + InstanceOfNode instanceOfNode = new InstanceOfNode(hub, (RiResolvedType) type, object, hints, Util.isFinalClass(resolvedType), false); frameState.ipush(append(MaterializeNode.create(currentGraph.unique(instanceOfNode), currentGraph))); } else { PlaceholderNode trueSucc = currentGraph.add(new PlaceholderNode()); diff -r 12558f571128 -r b494d6f329a3 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 11:05:58 2012 +0100 +++ b/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/java/CheckCastNode.java Fri Feb 03 17:13:46 2012 +0100 @@ -82,6 +82,13 @@ return object(); } } + + 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 CheckCastNode(anchor, targetClassInstruction(), targetClass(), object(), hints(), true)); + } + } return this; } diff -r 12558f571128 -r b494d6f329a3 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 11:05:58 2012 +0100 +++ b/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/java/InstanceOfNode.java Fri Feb 03 17:13:46 2012 +0100 @@ -67,20 +67,6 @@ @Override public ValueNode canonical(CanonicalizerTool tool) { RiResolvedType exact = object().exactType(); - - if (exact == null) { - if (object().declaredType() != null) { - if (Modifier.isFinal(object().declaredType().accessFlags()) || object().declaredType().isArrayClass()) { - exact = object().declaredType(); - } else if (tool.assumptions() != null) { - exact = object().declaredType().uniqueConcreteSubtype(); - if (exact != null) { - tool.assumptions().recordConcreteSubtype(object().declaredType(), exact); - } - } - } - } - if (exact != null) { boolean result = exact.isSubtypeOf(targetClass()); if (result != negated) {