# HG changeset patch # User Tom Rodriguez # Date 1418875078 28800 # Node ID cbb09734754597475b6815484143a05a307a4b3f # Parent 37a5c6b8b930f9464e75c50b5ae30acf00f180ed Convert compare against Class to compare against Klass diff -r 37a5c6b8b930 -r cbb097347545 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ClassGetHubNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ClassGetHubNode.java Wed Dec 17 13:39:48 2014 -0800 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ClassGetHubNode.java Wed Dec 17 19:57:58 2014 -0800 @@ -25,6 +25,7 @@ import static com.oracle.graal.hotspot.replacements.HotSpotReplacementsUtil.*; import com.oracle.graal.api.meta.*; +import com.oracle.graal.compiler.common.calc.*; import com.oracle.graal.graph.*; import com.oracle.graal.graph.spi.*; import com.oracle.graal.hotspot.*; @@ -34,6 +35,7 @@ import com.oracle.graal.nodeinfo.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.HeapAccess.BarrierType; +import com.oracle.graal.nodes.calc.*; import com.oracle.graal.nodes.extended.*; import com.oracle.graal.nodes.spi.*; @@ -44,7 +46,7 @@ * {@link ReadNode#canonicalizeRead(ValueNode, LocationNode, ValueNode, CanonicalizerTool)}. */ @NodeInfo -public class ClassGetHubNode extends FloatingGuardedNode implements Lowerable, Canonicalizable { +public class ClassGetHubNode extends FloatingGuardedNode implements Lowerable, Canonicalizable, ConvertNode { @Input protected ValueNode clazz; protected final HotSpotGraalRuntimeProvider runtime; @@ -110,4 +112,36 @@ @NodeIntrinsic public static native KlassPointer readClass(Class clazz, GuardingNode guard); + public ValueNode getValue() { + return clazz; + } + + public Constant convert(Constant c) { + ResolvedJavaType exactType = runtime.getHostProviders().getConstantReflection().asJavaType(c); + if (exactType instanceof HotSpotResolvedObjectType) { + HotSpotResolvedObjectType objectType = (HotSpotResolvedObjectType) exactType; + return objectType.getObjectHub(); + } else { + assert exactType instanceof HotSpotResolvedPrimitiveType; + return JavaConstant.NULL_POINTER; + } + } + + public Constant reverse(Constant c) { + assert !c.equals(JavaConstant.NULL_POINTER); + ResolvedJavaType objectType = runtime.getHostProviders().getConstantReflection().asJavaType(c); + return objectType.getJavaClass(); + } + + public boolean isLossless() { + return false; + } + + @Override + public boolean preservesOrder(Condition op, Constant value) { + assert op == Condition.EQ || op == Condition.NE; + ResolvedJavaType exactType = runtime.getHostProviders().getConstantReflection().asJavaType(value); + return exactType instanceof HotSpotResolvedObjectType; + } + } diff -r 37a5c6b8b930 -r cbb097347545 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HubGetClassNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HubGetClassNode.java Wed Dec 17 13:39:48 2014 -0800 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HubGetClassNode.java Wed Dec 17 19:57:58 2014 -0800 @@ -29,10 +29,12 @@ import com.oracle.graal.graph.*; import com.oracle.graal.graph.spi.*; import com.oracle.graal.hotspot.*; +import com.oracle.graal.hotspot.meta.*; import com.oracle.graal.hotspot.word.*; import com.oracle.graal.nodeinfo.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.HeapAccess.BarrierType; +import com.oracle.graal.nodes.calc.*; import com.oracle.graal.nodes.extended.*; import com.oracle.graal.nodes.spi.*; @@ -41,18 +43,18 @@ * also used by {@link ClassGetHubNode} to eliminate chains of {@code klass._java_mirror._klass}. */ @NodeInfo -public class HubGetClassNode extends FloatingGuardedNode implements Lowerable, Canonicalizable { +public class HubGetClassNode extends FloatingGuardedNode implements Lowerable, Canonicalizable, ConvertNode { @Input protected ValueNode hub; - protected final HotSpotVMConfig config; + protected final HotSpotGraalRuntimeProvider runtime; - public static HubGetClassNode create(@InjectedNodeParameter MetaAccessProvider metaAccess, @InjectedNodeParameter HotSpotVMConfig config, ValueNode hub) { - return new HubGetClassNode(hub, metaAccess, config); + public static HubGetClassNode create(@InjectedNodeParameter MetaAccessProvider metaAccess, @InjectedNodeParameter HotSpotGraalRuntimeProvider runtime, ValueNode hub) { + return new HubGetClassNode(hub, metaAccess, runtime); } - protected HubGetClassNode(ValueNode hub, MetaAccessProvider metaAccess, HotSpotVMConfig config) { + protected HubGetClassNode(ValueNode hub, MetaAccessProvider metaAccess, HotSpotGraalRuntimeProvider runtime) { super(StampFactory.declaredNonNull(metaAccess.lookupJavaType(Class.class)), null); this.hub = hub; - this.config = config; + this.runtime = runtime; } public ValueNode getHub() { @@ -81,7 +83,7 @@ return; } - LocationNode location = ConstantLocationNode.create(CLASS_MIRROR_LOCATION, config.classMirrorOffset, graph()); + LocationNode location = ConstantLocationNode.create(CLASS_MIRROR_LOCATION, runtime.getConfig().classMirrorOffset, graph()); assert !hub.isConstant(); FloatingReadNode read = graph().unique(FloatingReadNode.create(hub, location, null, stamp(), getGuard(), BarrierType.NONE)); graph().replaceFloating(this, read); @@ -90,4 +92,32 @@ @NodeIntrinsic public static native Class readClass(KlassPointer hub); + @Override + public ValueNode getValue() { + return hub; + } + + @Override + public Constant convert(Constant c) { + return runtime.getHostProviders().getConstantReflection().asJavaType(c).getJavaClass(); + } + + @Override + public Constant reverse(Constant c) { + ResolvedJavaType type = runtime.getHostProviders().getConstantReflection().asJavaType(c); + if (type instanceof HotSpotResolvedObjectType) { + return ((HotSpotResolvedObjectType) type).getObjectHub(); + } else { + assert type instanceof HotSpotResolvedPrimitiveType; + return JavaConstant.NULL_POINTER; + } + } + + @Override + public boolean isLossless() { + /* + * Any concrete Klass* has a corresponding java.lang.Class + */ + return true; + } } diff -r 37a5c6b8b930 -r cbb097347545 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 Wed Dec 17 13:39:48 2014 -0800 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/CompareNode.java Wed Dec 17 19:57:58 2014 -0800 @@ -137,7 +137,7 @@ } private ConstantNode canonicalConvertConstant(CanonicalizerTool tool, ConvertNode convert, Constant constant) { - if (convert.preservesOrder(condition())) { + if (convert.preservesOrder(condition(), constant)) { Constant reverseConverted = convert.reverse(constant); if (convert.convert(reverseConverted).equals(constant)) { return ConstantNode.forConstant(convert.getValue().stamp(), reverseConverted, tool.getMetaAccess()); diff -r 37a5c6b8b930 -r cbb097347545 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ConvertNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ConvertNode.java Wed Dec 17 13:39:48 2014 -0800 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ConvertNode.java Wed Dec 17 19:57:58 2014 -0800 @@ -56,5 +56,16 @@ return isLossless(); } + /** + * Check whether a conversion preserves comparison order against a particular constant value. + * + * @param op a comparison operator + * @param value + * @return true iff (c1 op value) == (convert(c1) op convert(value)) for value and all c1 + */ + default boolean preservesOrder(Condition op, Constant value) { + return preservesOrder(op); + } + ValueNode asNode(); } diff -r 37a5c6b8b930 -r cbb097347545 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ObjectEqualsNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ObjectEqualsNode.java Wed Dec 17 13:39:48 2014 -0800 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ObjectEqualsNode.java Wed Dec 17 19:57:58 2014 -0800 @@ -23,6 +23,7 @@ package com.oracle.graal.nodes.calc; import com.oracle.graal.api.meta.*; +import com.oracle.graal.compiler.common.*; import com.oracle.graal.compiler.common.type.*; import com.oracle.graal.nodeinfo.*; import com.oracle.graal.nodes.*; @@ -84,7 +85,7 @@ /* * One of the two objects has identity, the other doesn't. In code, this looks like * "Integer.valueOf(a) == new Integer(b)", which is always false. - * + * * In other words: an object created via valueOf can never be equal to one created * by new in the same compilation unit. */ @@ -111,6 +112,11 @@ @Override protected CompareNode duplicateModified(ValueNode newX, ValueNode newY) { - return ObjectEqualsNode.create(newX, newY); + if (newX.stamp() instanceof ObjectStamp && newY.stamp() instanceof ObjectStamp) { + return ObjectEqualsNode.create(newX, newY); + } else if (newX.stamp() instanceof AbstractPointerStamp && newY.stamp() instanceof AbstractPointerStamp) { + return PointerEqualsNode.create(newX, newY); + } + throw GraalInternalError.shouldNotReachHere(); } }