# HG changeset patch # User Christos Kotselidis # Date 1371029865 -7200 # Node ID 9d6f0c55cda712d0b48e60f5d5c9c4e2b6fa8343 # Parent 4a7dc38ae96bbedab3dd8bfc45218b50d9e0d155# Parent c4a0e878868f186b5c5f13dd95177b6562bcb20e Merge diff -r 4a7dc38ae96b -r 9d6f0c55cda7 graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/TypeCheckHints.java --- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/TypeCheckHints.java Wed Jun 12 11:36:54 2013 +0200 +++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/TypeCheckHints.java Wed Jun 12 11:37:45 2013 +0200 @@ -47,7 +47,7 @@ public final ResolvedJavaType type; /** - * Specifies if {@link #type} was a sub-type of the checked type. + * Specifies if {@link #type} is a sub-type of the checked type. */ public final boolean positive; @@ -60,11 +60,11 @@ private static final Hint[] NO_HINTS = {}; /** - * If true, then {@link #hints} contains the only possible type that could pass the type check - * because the target of the type check is a final class or has been speculated to be a final - * class. + * If non-null, then this is the only type that could pass the type check because the target of + * the type check is a final class or has been speculated to be a final class and this value is + * the only concrete subclass of the target type. */ - public final boolean exact; + public final ResolvedJavaType exact; /** * The most likely types that the type check instruction will see. @@ -72,6 +72,16 @@ public final Hint[] hints; /** + * The profile from which this information was derived. + */ + public final JavaTypeProfile profile; + + /** + * The total probability that the type check will hit one of the types in {@link #hints}. + */ + public final double hintHitProbability; + + /** * Derives hint information for use when generating the code for a type check instruction. * * @param targetType the target type of the type check @@ -84,50 +94,58 @@ * @param maxHints the maximum length of {@link #hints} */ public TypeCheckHints(ResolvedJavaType targetType, JavaTypeProfile profile, Assumptions assumptions, double minHintHitProbability, int maxHints) { + this.profile = profile; if (targetType != null && !canHaveSubtype(targetType)) { - hints = new Hint[]{new Hint(targetType, true)}; - exact = true; + exact = targetType; } else { ResolvedJavaType uniqueSubtype = targetType == null ? null : targetType.findUniqueConcreteSubtype(); if (uniqueSubtype != null) { - hints = new Hint[]{new Hint(uniqueSubtype, true)}; if (assumptions.useOptimisticAssumptions()) { assumptions.recordConcreteSubtype(targetType, uniqueSubtype); - exact = true; + exact = uniqueSubtype; } else { - exact = false; + exact = null; } } else { - exact = false; - Hint[] hintsBuf = NO_HINTS; - JavaTypeProfile typeProfile = profile; - if (typeProfile != null) { - double notRecordedTypes = typeProfile.getNotRecordedProbability(); - ProfiledType[] ptypes = typeProfile.getTypes(); - if (notRecordedTypes < (1D - minHintHitProbability) && ptypes != null && ptypes.length > 0) { - hintsBuf = new Hint[ptypes.length]; - int hintCount = 0; - double totalHintProbability = 0.0d; - for (ProfiledType ptype : ptypes) { - if (targetType != null) { - ResolvedJavaType hintType = ptype.getType(); - hintsBuf[hintCount++] = new Hint(hintType, targetType.isAssignableFrom(hintType)); - totalHintProbability += ptype.getProbability(); - } - } - if (totalHintProbability >= minHintHitProbability) { - if (hintsBuf.length != hintCount || hintCount > maxHints) { - hintsBuf = Arrays.copyOf(hintsBuf, Math.min(maxHints, hintCount)); - } - } else { - hintsBuf = NO_HINTS; - } + exact = null; + } + } + Double[] hitProbability = {null}; + this.hints = makeHints(targetType, profile, minHintHitProbability, maxHints, hitProbability); + this.hintHitProbability = hitProbability[0]; + } + private static Hint[] makeHints(ResolvedJavaType targetType, JavaTypeProfile profile, double minHintHitProbability, int maxHints, Double[] hitProbability) { + double hitProb = 0.0d; + Hint[] hintsBuf = NO_HINTS; + if (profile != null) { + double notRecordedTypes = profile.getNotRecordedProbability(); + ProfiledType[] ptypes = profile.getTypes(); + if (notRecordedTypes < (1D - minHintHitProbability) && ptypes != null && ptypes.length > 0) { + hintsBuf = new Hint[ptypes.length]; + int hintCount = 0; + for (ProfiledType ptype : ptypes) { + if (targetType != null) { + ResolvedJavaType hintType = ptype.getType(); + hintsBuf[hintCount++] = new Hint(hintType, targetType.isAssignableFrom(hintType)); + hitProb += ptype.getProbability(); + } + if (hintCount == maxHints) { + break; } } - this.hints = hintsBuf; + if (hitProb >= minHintHitProbability) { + if (hintsBuf.length != hintCount || hintCount > maxHints) { + hintsBuf = Arrays.copyOf(hintsBuf, Math.min(maxHints, hintCount)); + } + } else { + hintsBuf = NO_HINTS; + hitProb = 0.0d; + } } } + hitProbability[0] = hitProb; + return hintsBuf; } /** diff -r 4a7dc38ae96b -r 9d6f0c55cda7 graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/JavaTypeProfile.java --- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/JavaTypeProfile.java Wed Jun 12 11:36:54 2013 +0200 +++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/JavaTypeProfile.java Wed Jun 12 11:37:45 2013 +0200 @@ -62,7 +62,7 @@ public JavaTypeProfile restrict(JavaTypeProfile otherProfile) { if (otherProfile.getNotRecordedProbability() > 0.0) { - // Not useful for restricting since there is an unknown set of types occuring. + // Not useful for restricting since there is an unknown set of types occurring. return this; } @@ -155,7 +155,20 @@ @Override public String toString() { - return "{" + item.getName() + ", " + probability + "}"; + return String.format("%.6f#%s", probability, item); } } + + @Override + public String toString() { + StringBuilder buf = new StringBuilder("JavaTypeProfile", getNotRecordedProbability())).toString(); + } } diff -r 4a7dc38ae96b -r 9d6f0c55cda7 graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/AheadOfTimeCompilationTest.java --- a/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/AheadOfTimeCompilationTest.java Wed Jun 12 11:36:54 2013 +0200 +++ b/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/AheadOfTimeCompilationTest.java Wed Jun 12 11:37:45 2013 +0200 @@ -30,13 +30,18 @@ import com.oracle.graal.api.code.*; import com.oracle.graal.api.code.CallingConvention.Type; import com.oracle.graal.api.meta.*; +import com.oracle.graal.api.runtime.*; import com.oracle.graal.compiler.*; import com.oracle.graal.compiler.test.*; +import com.oracle.graal.graph.iterators.*; +import com.oracle.graal.hotspot.meta.*; +import com.oracle.graal.hotspot.phases.*; import com.oracle.graal.java.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.extended.*; import com.oracle.graal.phases.*; import com.oracle.graal.phases.PhasePlan.PhasePosition; +import com.oracle.graal.phases.tiers.*; /** * use @@ -56,18 +61,48 @@ } @Test - @Ignore - public void testStaticFinalObject1() { - StructuredGraph result2 = compile("getStaticFinalObject", true); - assert result2.getNodes().filter(ConstantNode.class).count() == 1; - assert result2.getNodes(FloatingReadNode.class).count() == 1; + public void testStaticFinalObjectAOT() { + StructuredGraph result = compile("getStaticFinalObject", true); + assert result.getNodes().filter(ConstantNode.class).count() == 1; + assert result.getNodes(FloatingReadNode.class).count() == 2; + } + + @Test + public void testStaticFinalObject() { + StructuredGraph result = compile("getStaticFinalObject", false); + assert result.getNodes().filter(ConstantNode.class).count() == 1; + assert result.getNodes(FloatingReadNode.class).count() == 0; + } + + public static Class getClassObject() { + return AheadOfTimeCompilationTest.class; } @Test - public void testStaticFinalObject2() { - StructuredGraph result1 = compile("getStaticFinalObject", false); - assert result1.getNodes().filter(ConstantNode.class).count() == 1; - assert result1.getNodes(FloatingReadNode.class).count() == 0; + public void testClassObjectAOT() { + StructuredGraph result = compile("getClassObject", true); + + NodeIterable filter = result.getNodes().filter(ConstantNode.class); + assert filter.count() == 1; + HotSpotResolvedObjectType type = (HotSpotResolvedObjectType) runtime.lookupJavaType(AheadOfTimeCompilationTest.class); + assert filter.first().asConstant().equals(type.klass()); + + assert result.getNodes(FloatingReadNode.class).count() == 1; + assert result.getNodes(ReadNode.class).count() == 0; + } + + @Test + public void testClassObject() { + StructuredGraph result = compile("getClassObject", false); + + NodeIterable filter = result.getNodes().filter(ConstantNode.class); + assert filter.count() == 1; + Object mirror = filter.first().asConstant().asObject(); + assert mirror.getClass().equals(Class.class); + assert mirror.equals(AheadOfTimeCompilationTest.class); + + assert result.getNodes(FloatingReadNode.class).count() == 0; + assert result.getNodes(ReadNode.class).count() == 0; } private StructuredGraph compile(String test, boolean compileAOT) { @@ -82,8 +117,13 @@ phasePlan.addPhase(PhasePosition.AFTER_PARSING, graphBuilderPhase); editPhasePlan(method, graph, phasePlan); CallingConvention cc = getCallingConvention(runtime, Type.JavaCallee, graph.method(), false); + // create suites everytime, as we modify options for the compiler + final Suites suitesLocal = Graal.getRequiredCapability(SuitesProvider.class).createSuites(); + if (compileAOT) { + suitesLocal.getHighTier().addPhase(new LoadJavaMirrorWithKlassPhase()); + } final CompilationResult compResult = GraalCompiler.compileGraph(graph, cc, method, runtime, replacements, backend, runtime().getTarget(), null, phasePlan, OptimisticOptimizations.ALL, - new SpeculationLog(), suites); + new SpeculationLog(), suitesLocal); addMethod(method, compResult, graphCopy); OptCanonicalizeReads.setValue(originalSetting); diff -r 4a7dc38ae96b -r 9d6f0c55cda7 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMethod.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMethod.java Wed Jun 12 11:36:54 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMethod.java Wed Jun 12 11:37:45 2013 +0200 @@ -22,6 +22,8 @@ */ package com.oracle.graal.hotspot.meta; +import static com.oracle.graal.api.meta.MetaUtil.*; + import com.oracle.graal.api.meta.*; import com.oracle.graal.hotspot.*; @@ -30,8 +32,22 @@ private static final long serialVersionUID = 7167491397941960839L; protected String name; + /** + * Controls whether {@link #toString()} includes the qualified or simple name of the class in + * which the method is declared. + */ + public static final boolean FULLY_QUALIFIED_METHOD_NAME = false; + @Override public final String getName() { return name; } + + @Override + public final String toString() { + char h = FULLY_QUALIFIED_METHOD_NAME ? 'H' : 'h'; + String suffix = this instanceof ResolvedJavaMethod ? "" : ", unresolved"; + String fmt = String.format("HotSpotMethod<%%%c.%%n(%%p)%s>", h, suffix); + return format(fmt, this); + } } diff -r 4a7dc38ae96b -r 9d6f0c55cda7 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMethodUnresolved.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMethodUnresolved.java Wed Jun 12 11:36:54 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMethodUnresolved.java Wed Jun 12 11:37:45 2013 +0200 @@ -22,8 +22,6 @@ */ package com.oracle.graal.hotspot.meta; -import static com.oracle.graal.api.meta.MetaUtil.*; - import com.oracle.graal.api.meta.*; /** @@ -50,9 +48,4 @@ public JavaType getDeclaringClass() { return holder; } - - @Override - public String toString() { - return format("HotSpotMethod<%H.%n(%p), unresolved>", this); - } } diff -r 4a7dc38ae96b -r 9d6f0c55cda7 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaMethod.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaMethod.java Wed Jun 12 11:36:54 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaMethod.java Wed Jun 12 11:37:45 2013 +0200 @@ -22,7 +22,6 @@ */ package com.oracle.graal.hotspot.meta; -import static com.oracle.graal.api.meta.MetaUtil.*; import static com.oracle.graal.graph.UnsafeAccess.*; import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*; import static com.oracle.graal.phases.GraalOptions.*; @@ -259,11 +258,6 @@ return signature; } - @Override - public String toString() { - return format("HotSpotMethod<%H.%n(%p)>", this); - } - public int getCompiledCodeSize() { return graalRuntime().getCompilerToVM().getCompiledCodeSize(metaspaceMethod); } diff -r 4a7dc38ae96b -r 9d6f0c55cda7 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/phases/LoadJavaMirrorWithKlassPhase.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/phases/LoadJavaMirrorWithKlassPhase.java Wed Jun 12 11:37:45 2013 +0200 @@ -0,0 +1,63 @@ +/* + * 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.hotspot.phases; + +import static com.oracle.graal.api.meta.LocationIdentity.*; + +import com.oracle.graal.api.meta.*; +import com.oracle.graal.hotspot.meta.*; +import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.HeapAccess.WriteBarrierType; +import com.oracle.graal.nodes.extended.*; +import com.oracle.graal.nodes.type.*; +import com.oracle.graal.phases.*; +import com.oracle.graal.phases.tiers.*; + +public class LoadJavaMirrorWithKlassPhase extends BasePhase { + + @Override + protected void run(StructuredGraph graph, PhaseContext context) { + for (ConstantNode node : graph.getNodes().filter(ConstantNode.class)) { + Constant constant = node.asConstant(); + if (constant.getKind() == Kind.Object && constant.asObject() instanceof Class) { + ResolvedJavaType type = context.getRuntime().lookupJavaType((Class) constant.asObject()); + if (type instanceof HotSpotResolvedObjectType) { + HotSpotRuntime runtime = (HotSpotRuntime) context.getRuntime(); + + Constant klass = ((HotSpotResolvedObjectType) type).klass(); + ConstantNode klassNode = ConstantNode.forConstant(klass, runtime, graph); + + Stamp stamp = StampFactory.exactNonNull(runtime.lookupJavaType(Class.class)); + LocationNode location = graph.unique(ConstantLocationNode.create(FINAL_LOCATION, stamp.kind(), runtime.config.classMirrorOffset, graph)); + ReadNode readNode = graph.add(new ReadNode(klassNode, location, stamp, WriteBarrierType.NONE, false)); + + FixedNode afterStart = graph.start().next(); + graph.start().setNext(readNode); + readNode.setNext(afterStart); + + graph.replaceFloating(node, readNode); + } + } + } + } +} diff -r 4a7dc38ae96b -r 9d6f0c55cda7 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/CheckCastSnippets.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/CheckCastSnippets.java Wed Jun 12 11:36:54 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/CheckCastSnippets.java Wed Jun 12 11:37:45 2013 +0200 @@ -172,12 +172,10 @@ ValueNode hub = ConstantNode.forConstant(type.klass(), runtime, checkcast.graph()); Arguments args; - if (hintInfo.exact) { - ConstantNode[] hints = createHints(hintInfo, runtime, true, graph).hubs; - assert hints.length == 1; + if (hintInfo.exact != null) { args = new Arguments(exact); args.add("object", object); - args.add("exactHub", hints[0]); + args.add("exactHub", ConstantNode.forConstant(((HotSpotResolvedObjectType) hintInfo.exact).klass(), runtime, graph)); } else if (type.isPrimaryType()) { args = new Arguments(primary); args.add("hub", hub); diff -r 4a7dc38ae96b -r 9d6f0c55cda7 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/InstanceOfSnippets.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/InstanceOfSnippets.java Wed Jun 12 11:36:54 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/InstanceOfSnippets.java Wed Jun 12 11:37:45 2013 +0200 @@ -22,6 +22,9 @@ */ package com.oracle.graal.hotspot.replacements; +import static com.oracle.graal.api.code.DeoptimizationAction.*; +import static com.oracle.graal.api.meta.DeoptimizationReason.*; +import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*; import static com.oracle.graal.hotspot.replacements.HotSpotReplacementsUtil.*; import static com.oracle.graal.hotspot.replacements.TypeCheckSnippetUtils.*; import static com.oracle.graal.phases.GraalOptions.*; @@ -29,6 +32,7 @@ import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; +import com.oracle.graal.api.meta.ProfilingInfo.TriState; import com.oracle.graal.hotspot.meta.*; import com.oracle.graal.hotspot.replacements.TypeCheckSnippetUtils.Hints; import com.oracle.graal.nodes.*; @@ -54,6 +58,35 @@ public class InstanceOfSnippets implements Snippets { /** + * A test against a set of hints derived from a profile with 100% precise coverage of seen + * types. This snippet deoptimizes on any path that contradicts the profile. + */ + @Snippet + public static Object instanceofWithProfile(Object object, @VarargsParameter Word[] hints, @VarargsParameter boolean[] hintIsPositive, Object trueValue, Object falseValue, + @ConstantParameter boolean checkNull, @ConstantParameter boolean nullSeen) { + if (probability(NOT_FREQUENT_PROBABILITY, checkNull && object == null)) { + isNull.inc(); + if (!nullSeen) { + DeoptimizeNode.deopt(InvalidateReprofile, OptimizedTypeCheckViolated); + } + return falseValue; + } + Word objectHub = loadHub(object); + // if we get an exact match: succeed immediately + ExplodeLoopNode.explodeLoop(); + for (int i = 0; i < hints.length; i++) { + Word hintHub = hints[i]; + boolean positive = hintIsPositive[i]; + if (probability(NOT_FREQUENT_PROBABILITY, hintHub.equal(objectHub))) { + hintsHit.inc(); + return positive ? trueValue : falseValue; + } + } + DeoptimizeNode.deopt(InvalidateReprofile, OptimizedTypeCheckViolated); + return falseValue; + } + + /** * A test against a final type. */ @Snippet @@ -136,6 +169,7 @@ public static class Templates extends InstanceOfSnippetsTemplates { + private final SnippetInfo instanceofWithProfile = snippet(InstanceOfSnippets.class, "instanceofWithProfile"); private final SnippetInfo instanceofExact = snippet(InstanceOfSnippets.class, "instanceofExact"); private final SnippetInfo instanceofPrimary = snippet(InstanceOfSnippets.class, "instanceofPrimary"); private final SnippetInfo instanceofSecondary = snippet(InstanceOfSnippets.class, "instanceofSecondary"); @@ -155,12 +189,16 @@ ConstantNode hub = ConstantNode.forConstant(type.klass(), runtime, instanceOf.graph()); Arguments args; - if (hintInfo.exact) { - ConstantNode[] hints = createHints(hintInfo, runtime, true, hub.graph()).hubs; - assert hints.length == 1; + if (hintInfo.hintHitProbability == 1.0D) { + Hints hints = createHints(hintInfo, runtime, false, hub.graph()); + args = new Arguments(instanceofWithProfile); + args.add("object", object); + args.addVarargs("hints", Word.class, StampFactory.forKind(wordKind()), hints.hubs); + args.addVarargs("hintIsPositive", boolean.class, StampFactory.forKind(Kind.Boolean), hints.isPositive); + } else if (hintInfo.exact != null) { args = new Arguments(instanceofExact); args.add("object", object); - args.add("exactHub", hints[0]); + args.add("exactHub", ConstantNode.forConstant(((HotSpotResolvedObjectType) hintInfo.exact).klass(), runtime, hub.graph())); } else if (type.isPrimaryType()) { args = new Arguments(instanceofPrimary); args.add("hub", hub); @@ -177,6 +215,9 @@ args.add("trueValue", replacer.trueValue); args.add("falseValue", replacer.falseValue); args.addConst("checkNull", !object.stamp().nonNull()); + if (hintInfo.hintHitProbability == 1.0D) { + args.addConst("nullSeen", hintInfo.profile.getNullSeen() != TriState.FALSE); + } return args; } else { diff -r 4a7dc38ae96b -r 9d6f0c55cda7 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/TypeProfileProxyNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/TypeProfileProxyNode.java Wed Jun 12 11:36:54 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/TypeProfileProxyNode.java Wed Jun 12 11:37:45 2013 +0200 @@ -30,7 +30,7 @@ import com.oracle.graal.nodes.type.*; /** - * A node that attached a type profile to a proxied input node. + * A node that attaches a type profile to a proxied input node. */ public final class TypeProfileProxyNode extends FloatingNode implements Canonicalizable, Node.IterableNodeType { diff -r 4a7dc38ae96b -r 9d6f0c55cda7 graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/InstanceOfSnippetsTemplates.java --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/InstanceOfSnippetsTemplates.java Wed Jun 12 11:36:54 2013 +0200 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/InstanceOfSnippetsTemplates.java Wed Jun 12 11:37:45 2013 +0200 @@ -108,12 +108,12 @@ } /** - * The result of an instantiating an instanceof snippet. This enables a snippet instantiation to - * be re-used which reduces compile time and produces better code. + * The result of instantiating an instanceof snippet. This enables a snippet instantiation to be + * re-used which reduces compile time and produces better code. */ public static final class Instantiation { - private PhiNode result; + private ValueNode result; private CompareNode condition; private ValueNode trueValue; private ValueNode falseValue; @@ -125,9 +125,9 @@ return result != null; } - void initialize(PhiNode phi, ValueNode t, ValueNode f) { + void initialize(ValueNode r, ValueNode t, ValueNode f) { assert !isInitialized(); - this.result = phi; + this.result = r; this.trueValue = t; this.falseValue = f; } @@ -137,8 +137,12 @@ * * @param testValue the returned condition is true if the result is equal to this value */ - CompareNode asCondition(ValueNode testValue) { + LogicNode asCondition(ValueNode testValue) { assert isInitialized(); + if (result.isConstant()) { + assert testValue.isConstant(); + return LogicConstantNode.forBoolean(result.asConstant().equals(testValue.asConstant()), result.graph()); + } if (condition == null || condition.y() != testValue) { // Re-use previously generated condition if the trueValue for the test is the same condition = createCompareNode(Condition.EQ, result, testValue); @@ -207,10 +211,18 @@ @Override public void replace(ValueNode oldNode, ValueNode newNode) { + if (newNode.isConstant()) { + LogicConstantNode logicConstant = LogicConstantNode.forBoolean(newNode.asConstant().asInt() != 0, newNode.graph()); + usage.replaceFirstInput(oldNode, logicConstant); + // PrintStream out = System.out; + // out.println(newNode.graph() + ": " + this); + GraalInternalError.shouldNotReachHere(instanceOf.graph().toString()); + return; + } assert newNode instanceof PhiNode; assert oldNode == instanceOf; newNode.inferStamp(); - instantiation.initialize((PhiNode) newNode, trueValue, falseValue); + instantiation.initialize(newNode, trueValue, falseValue); usage.replaceFirstInput(oldNode, instantiation.asCondition(trueValue)); } } @@ -239,10 +251,18 @@ @Override public void replace(ValueNode oldNode, ValueNode newNode) { + if (newNode.isConstant()) { + LogicConstantNode logicConstant = LogicConstantNode.forBoolean(newNode.asConstant().asInt() != 0, newNode.graph()); + usage.replaceFirstInput(oldNode, logicConstant); + // PrintStream out = System.out; + // out.println(newNode.graph() + ": " + this); + GraalInternalError.shouldNotReachHere(instanceOf.graph().toString()); + return; + } assert newNode instanceof PhiNode; assert oldNode == instanceOf; newNode.inferStamp(); - instantiation.initialize((PhiNode) newNode, trueValue, falseValue); + instantiation.initialize(newNode, trueValue, falseValue); usage.replaceAtUsages(newNode); usage.clearInputs(); assert usage.usages().isEmpty(); diff -r 4a7dc38ae96b -r 9d6f0c55cda7 graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/SnippetTemplate.java --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/SnippetTemplate.java Wed Jun 12 11:36:54 2013 +0200 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/SnippetTemplate.java Wed Jun 12 11:37:45 2013 +0200 @@ -192,7 +192,7 @@ @Override public String toString() { StringBuilder result = new StringBuilder(); - result.append("Parameters<").append(MetaUtil.format("%H.%n", info.method)).append(" ["); + result.append("Parameters<").append(MetaUtil.format("%h.%n", info.method)).append(" ["); String sep = ""; for (int i = 0; i < info.getParameterCount(); i++) { result.append(sep); @@ -229,6 +229,38 @@ this.length = Array.getLength(value); } } + + @Override + public String toString() { + if (value instanceof boolean[]) { + return Arrays.toString((boolean[]) value); + } + if (value instanceof byte[]) { + return Arrays.toString((byte[]) value); + } + if (value instanceof char[]) { + return Arrays.toString((char[]) value); + } + if (value instanceof float[]) { + return Arrays.toString((short[]) value); + } + if (value instanceof float[]) { + return Arrays.toString((int[]) value); + } + if (value instanceof float[]) { + return Arrays.toString((long[]) value); + } + if (value instanceof float[]) { + return Arrays.toString((float[]) value); + } + if (value instanceof double[]) { + return Arrays.toString((double[]) value); + } + if (value instanceof Object[]) { + return Arrays.toString((Object[]) value); + } + return String.valueOf(value); + } } static class CacheKey {