# HG changeset patch # User Doug Simon # Date 1351588945 -3600 # Node ID 7bf5a6c42db7c6e073f59f81311f511cdbccebf1 # Parent 0b8410de13654b00cbd649e347e4823f268937ac factored CheckCastDynamicNode out of CheckCastNode diff -r 0b8410de1365 -r 7bf5a6c42db7 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java Tue Oct 30 08:57:28 2012 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java Tue Oct 30 10:22:25 2012 +0100 @@ -43,7 +43,6 @@ import com.oracle.graal.api.code.Register.RegisterFlag; import com.oracle.graal.api.code.RuntimeCall.Descriptor; import com.oracle.graal.api.meta.*; -import com.oracle.graal.api.meta.ResolvedJavaType.Representation; import com.oracle.graal.graph.*; import com.oracle.graal.hotspot.*; import com.oracle.graal.hotspot.bridge.*; @@ -470,7 +469,6 @@ Kind elementKind = storeIndexed.elementKind(); LocationNode arrayLocation = createArrayLocation(graph, elementKind, storeIndexed.index()); ValueNode value = storeIndexed.value(); - CheckCastNode checkcast = null; ValueNode array = storeIndexed.array(); if (elementKind == Kind.Object && !value.objectStamp().alwaysNull()) { // Store check! @@ -478,8 +476,7 @@ if (arrayType != null && array.objectStamp().isExactType()) { ResolvedJavaType elementType = arrayType.getComponentType(); if (elementType.getSuperclass() != null) { - ConstantNode type = ConstantNode.forConstant(elementType.getEncoding(Representation.ObjectHub), this, graph); - checkcast = graph.add(new CheckCastNode(type, elementType, value)); + CheckCastNode checkcast = graph.add(new CheckCastNode(elementType, value, null)); graph.addBeforeFixed(storeIndexed, checkcast); value = checkcast; } else { @@ -488,7 +485,7 @@ } else { LoadHubNode arrayClass = graph.add(new LoadHubNode(array)); FloatingReadNode arrayElementKlass = graph.unique(new FloatingReadNode(arrayClass, LocationNode.create(LocationNode.FINAL_LOCATION, Kind.Object, config.arrayClassElementOffset, graph), null, StampFactory.objectNonNull())); - checkcast = graph.add(new CheckCastNode(arrayElementKlass, null, value)); + CheckCastDynamicNode checkcast = graph.add(new CheckCastDynamicNode(arrayElementKlass, value)); graph.addBeforeFixed(storeIndexed, checkcast); graph.addBeforeFixed(checkcast, arrayClass); value = checkcast; @@ -541,6 +538,8 @@ graph.replaceFixed(loadHub, hub); } else if (n instanceof CheckCastNode) { checkcastSnippets.lower((CheckCastNode) n, tool); + } else if (n instanceof CheckCastDynamicNode) { + checkcastSnippets.lower((CheckCastDynamicNode) n); } else if (n instanceof InstanceOfNode) { instanceofSnippets.lower((InstanceOfNode) n, tool); } else if (n instanceof NewInstanceNode) { diff -r 0b8410de1365 -r 7bf5a6c42db7 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/CheckCastSnippets.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/CheckCastSnippets.java Tue Oct 30 08:57:28 2012 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/CheckCastSnippets.java Tue Oct 30 10:22:25 2012 +0100 @@ -134,25 +134,15 @@ * in an object array store check). */ @Snippet - public static Object checkcastUnknown( + public static Object checkcastDynamic( @Parameter("hub") Object hub, @Parameter("object") Object object, - @VarargsParameter("hints") Object[] hints, @ConstantParameter("checkNull") boolean checkNull) { if (checkNull && object == null) { isNull.inc(); return object; } Object objectHub = loadHub(object); - // if we get an exact match: succeed immediately - ExplodeLoopNode.explodeLoop(); - for (int i = 0; i < hints.length; i++) { - Object hintHub = hints[i]; - if (hintHub == objectHub) { - hintsHit.inc(); - return object; - } - } if (!checkUnknownSubType(hub, objectHub)) { DeoptimizeNode.deopt(DeoptimizationAction.InvalidateReprofile, DeoptimizationReason.ClassCastException); } @@ -237,14 +227,14 @@ private final ResolvedJavaMethod exact; private final ResolvedJavaMethod primary; private final ResolvedJavaMethod secondary; - private final ResolvedJavaMethod unknown; + private final ResolvedJavaMethod dynamic; public Templates(CodeCacheProvider runtime) { super(runtime, CheckCastSnippets.class); exact = snippet("checkcastExact", Object.class, Object.class, boolean.class); primary = snippet("checkcastPrimary", Object.class, Object.class, boolean.class, int.class); secondary = snippet("checkcastSecondary", Object.class, Object.class, Object[].class, boolean.class); - unknown = snippet("checkcastUnknown", Object.class, Object.class, Object[].class, boolean.class); + dynamic = snippet("checkcastDynamic", Object.class, Object.class, boolean.class); } /** @@ -252,25 +242,22 @@ */ public void lower(CheckCastNode checkcast, LoweringTool tool) { StructuredGraph graph = (StructuredGraph) checkcast.graph(); - ValueNode hub = checkcast.targetClassInstruction(); ValueNode object = checkcast.object(); - TypeCheckHints hintInfo = new TypeCheckHints(checkcast.targetClass(), checkcast.profile(), tool.assumptions(), GraalOptions.CheckcastMinHintHitProbability, GraalOptions.CheckcastMaxHints); - final HotSpotResolvedJavaType target = (HotSpotResolvedJavaType) checkcast.targetClass(); + TypeCheckHints hintInfo = new TypeCheckHints(checkcast.type(), checkcast.profile(), tool.assumptions(), GraalOptions.CheckcastMinHintHitProbability, GraalOptions.CheckcastMaxHints); + final HotSpotResolvedJavaType type = (HotSpotResolvedJavaType) checkcast.type(); + ValueNode hub = ConstantNode.forObject(type.klassOop(), runtime, checkcast.graph()); boolean checkNull = !object.stamp().nonNull(); Arguments arguments; Key key; - if (target == null) { - HotSpotKlassOop[] hints = createHints(hintInfo); - key = new Key(unknown).add("hints", vargargs(Object.class, hints.length)).add("checkNull", checkNull); - arguments = arguments("hub", hub).add("object", object).add("hints", hints); - } else if (hintInfo.exact) { + assert type != null; + if (hintInfo.exact) { HotSpotKlassOop[] hints = createHints(hintInfo); assert hints.length == 1; key = new Key(exact).add("checkNull", checkNull); arguments = arguments("object", object).add("exactHub", hints[0]); - } else if (target.isPrimaryType()) { - key = new Key(primary).add("checkNull", checkNull).add("superCheckOffset", target.superCheckOffset()); + } else if (type.isPrimaryType()) { + key = new Key(primary).add("checkNull", checkNull).add("superCheckOffset", type.superCheckOffset()); arguments = arguments("hub", hub).add("object", object); } else { HotSpotKlassOop[] hints = createHints(hintInfo); @@ -283,6 +270,23 @@ template.instantiate(runtime, checkcast, DEFAULT_REPLACER, arguments); } + /** + * Lowers a dynamic checkcast node. + */ + public void lower(CheckCastDynamicNode checkcast) { + StructuredGraph graph = (StructuredGraph) checkcast.graph(); + ValueNode hub = checkcast.type(); + ValueNode object = checkcast.object(); + boolean checkNull = !object.stamp().nonNull(); + + Key key = new Key(dynamic).add("checkNull", checkNull); + Arguments arguments = arguments("hub", hub).add("object", object); + + SnippetTemplate template = cache.get(key); + Debug.log("Lowering dynamic checkcast in %s: node=%s, template=%s, arguments=%s", graph, checkcast, template, arguments); + template.instantiate(runtime, checkcast, DEFAULT_REPLACER, arguments); + } + static HotSpotKlassOop[] createHints(TypeCheckHints hints) { HotSpotKlassOop[] hintHubs = new HotSpotKlassOop[hints.types.length]; for (int i = 0; i < hintHubs.length; i++) { diff -r 0b8410de1365 -r 7bf5a6c42db7 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/InstanceOfSnippets.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/InstanceOfSnippets.java Tue Oct 30 08:57:28 2012 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/InstanceOfSnippets.java Tue Oct 30 10:22:25 2012 +0100 @@ -181,8 +181,8 @@ public void lower(InstanceOfNode instanceOf, LoweringTool tool) { ValueNode object = instanceOf.object(); TypeCheckHints hintInfo = new TypeCheckHints(instanceOf.type(), instanceOf.profile(), tool.assumptions(), GraalOptions.CheckcastMinHintHitProbability, GraalOptions.CheckcastMaxHints); - final HotSpotResolvedJavaType target = (HotSpotResolvedJavaType) instanceOf.type(); - ConstantNode hub = ConstantNode.forObject(target.klassOop(), runtime, instanceOf.graph()); + final HotSpotResolvedJavaType type = (HotSpotResolvedJavaType) instanceOf.type(); + ConstantNode hub = ConstantNode.forObject(type.klassOop(), runtime, instanceOf.graph()); boolean checkNull = !object.stamp().nonNull(); for (Node usage : instanceOf.usages().snapshot()) { @@ -204,8 +204,8 @@ assert hints.length == 1; key = new Key(materializeExact).add("checkNull", checkNull); arguments = arguments("object", object).add("exactHub", hints[0]).add("trueValue", trueValue).add("falseValue", falseValue); - } else if (target.isPrimaryType()) { - key = new Key(materializePrimary).add("checkNull", checkNull).add("superCheckOffset", target.superCheckOffset()); + } else if (type.isPrimaryType()) { + key = new Key(materializePrimary).add("checkNull", checkNull).add("superCheckOffset", type.superCheckOffset()); arguments = arguments("hub", hub).add("object", object).add("trueValue", trueValue).add("falseValue", falseValue); } else { HotSpotKlassOop[] hints = createHints(hintInfo); @@ -243,8 +243,8 @@ assert hints.length == 1; key = new Key(materializeExact).add("checkNull", checkNull); arguments = arguments("object", object).add("exactHub", hints[0]).add("trueValue", trueValue).add("falseValue", falseValue); - } else if (target.isPrimaryType()) { - key = new Key(materializePrimary).add("checkNull", checkNull).add("superCheckOffset", target.superCheckOffset()); + } else if (type.isPrimaryType()) { + key = new Key(materializePrimary).add("checkNull", checkNull).add("superCheckOffset", type.superCheckOffset()); arguments = arguments("hub", hub).add("object", object).add("trueValue", trueValue).add("falseValue", falseValue); } else { HotSpotKlassOop[] hints = createHints(hintInfo); diff -r 0b8410de1365 -r 7bf5a6c42db7 graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java --- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java Tue Oct 30 08:57:28 2012 +0100 +++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java Tue Oct 30 10:22:25 2012 +0100 @@ -633,9 +633,8 @@ JavaType type = lookupType(cpi, CHECKCAST); boolean initialized = type instanceof ResolvedJavaType; if (initialized) { - ConstantNode typeInstruction = genTypeOrDeopt(Representation.ObjectHub, type, true); ValueNode object = frameState.apop(); - CheckCastNode checkCast = currentGraph.add(new CheckCastNode(typeInstruction, (ResolvedJavaType) type, object, getProfileForTypeCheck((ResolvedJavaType) type))); + CheckCastNode checkCast = currentGraph.add(new CheckCastNode((ResolvedJavaType) type, object, getProfileForTypeCheck((ResolvedJavaType) type))); append(checkCast); frameState.apush(checkCast); } else { @@ -1411,11 +1410,10 @@ } } - ConstantNode typeInstruction = genTypeOrDeopt(Representation.ObjectHub, catchType, initialized); - if (typeInstruction != null) { + if (initialized) { Block nextBlock = block.successors.size() == 1 ? unwindBlock(block.deoptBci) : block.successors.get(1); ValueNode exception = frameState.stackAt(0); - CheckCastNode checkCast = currentGraph.add(new CheckCastNode(typeInstruction, (ResolvedJavaType) catchType, exception)); + CheckCastNode checkCast = currentGraph.add(new CheckCastNode((ResolvedJavaType) catchType, exception, null)); frameState.apop(); frameState.push(Kind.Object, checkCast); FixedNode catchSuccessor = createTarget(block.successors.get(0), frameState); @@ -1425,6 +1423,8 @@ checkCast.setNext(catchSuccessor); IfNode ifNode = currentGraph.add(new IfNode(currentGraph.unique(new InstanceOfNode((ResolvedJavaType) catchType, exception, null)), checkCast, nextDispatch, 0.5, graphId)); append(ifNode); + } else { + append(currentGraph.add(new DeoptimizeNode(DeoptimizationAction.InvalidateRecompile, DeoptimizationReason.Unresolved, graphId))); } } diff -r 0b8410de1365 -r 7bf5a6c42db7 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/CheckCastDynamicNode.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/CheckCastDynamicNode.java Tue Oct 30 10:22:25 2012 +0100 @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2009, 2011, 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.nodes.java; + +import com.oracle.graal.graph.*; +import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.spi.*; +import com.oracle.graal.nodes.type.*; + +/** + * Implements a type check where the type being checked is loaded at runtime. + * This is used, for instance, to implement an object array store check. + */ +public final class CheckCastDynamicNode extends FixedWithNextNode implements Canonicalizable, Lowerable, Node.IterableNodeType { + + @Input private ValueNode object; + @Input private ValueNode type; + + /** + * @param type the type being cast to + * @param object the instruction producing the object + */ + public CheckCastDynamicNode(ValueNode type, ValueNode object) { + super(StampFactory.object()); + this.type = type; + this.object = object; + } + + @Override + public void lower(LoweringTool tool) { + tool.getRuntime().lower(this, tool); + } + + @Override + public boolean inferStamp() { + if (object().stamp().nonNull() && !stamp().nonNull()) { + setStamp(StampFactory.objectNonNull()); + return true; + } + return super.inferStamp(); + } + + @Override + public ValueNode canonical(CanonicalizerTool tool) { + assert object() != null : this; + + if (object().objectStamp().alwaysNull()) { + return object(); + } + return this; + } + + public ValueNode object() { + return object; + } + + /** + * Gets the runtime-loaded type being cast to. + */ + public ValueNode type() { + return type; + } +} diff -r 0b8410de1365 -r 7bf5a6c42db7 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 Tue Oct 30 08:57:28 2012 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/CheckCastNode.java Tue Oct 30 10:22:25 2012 +0100 @@ -29,29 +29,24 @@ import com.oracle.graal.nodes.type.*; /** - * Implements a type check that results in a {@link ClassCastException} if it fails. + * Implements a type check against a compile-time known type. */ public final class CheckCastNode extends FixedWithNextNode implements Canonicalizable, Lowerable, Node.IterableNodeType { @Input private ValueNode object; - @Input private ValueNode targetClassInstruction; - private final ResolvedJavaType targetClass; + private final ResolvedJavaType type; private final JavaTypeProfile profile; /** * Creates a new CheckCast instruction. - * @param targetClassInstruction the instruction which produces the class which is being cast to - * @param targetClass the class being cast to + * + * @param type the type being cast to * @param object the instruction producing the object */ - public CheckCastNode(ValueNode targetClassInstruction, ResolvedJavaType targetClass, ValueNode object) { - this(targetClassInstruction, targetClass, object, null); - } - - public CheckCastNode(ValueNode targetClassInstruction, ResolvedJavaType targetClass, ValueNode object, JavaTypeProfile profile) { - super(targetClass == null ? StampFactory.object() : StampFactory.declared(targetClass)); - this.targetClassInstruction = targetClassInstruction; - this.targetClass = targetClass; + public CheckCastNode(ResolvedJavaType type, ValueNode object, JavaTypeProfile profile) { + super(StampFactory.declared(type)); + assert type != null; + this.type = type; this.object = object; this.profile = profile; } @@ -64,7 +59,7 @@ @Override public boolean inferStamp() { if (object().stamp().nonNull() && !stamp().nonNull()) { - setStamp(targetClass == null ? StampFactory.objectNonNull() : StampFactory.declaredNonNull(targetClass)); + setStamp(StampFactory.declaredNonNull(type)); return true; } return super.inferStamp(); @@ -74,9 +69,9 @@ public ValueNode canonical(CanonicalizerTool tool) { assert object() != null : this; - if (targetClass != null) { + if (type != null) { ResolvedJavaType objectType = object().objectStamp().type(); - if (objectType != null && objectType.isSubtypeOf(targetClass)) { + if (objectType != null && objectType.isSubtypeOf(type)) { // we don't have to check for null types here because they will also pass the checkcast. return object(); } @@ -92,19 +87,11 @@ return object; } - public ValueNode targetClassInstruction() { - return targetClassInstruction; - } - /** - * Gets the target class, i.e. the class being cast to, or the class being tested against. - * This may be null in the case where the type being tested is dynamically loaded such as - * when checking an object array store. - * - * @return the target class or null if not known + * Gets the type being cast to. */ - public ResolvedJavaType targetClass() { - return targetClass; + public ResolvedJavaType type() { + return type; } public JavaTypeProfile profile() { diff -r 0b8410de1365 -r 7bf5a6c42db7 graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ConditionalEliminationPhase.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ConditionalEliminationPhase.java Tue Oct 30 08:57:28 2012 +0100 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ConditionalEliminationPhase.java Tue Oct 30 10:22:25 2012 +0100 @@ -326,7 +326,7 @@ } else if (node instanceof CheckCastNode) { CheckCastNode checkCast = (CheckCastNode) node; ResolvedJavaType type = state.getNodeType(checkCast.object()); - if (checkCast.targetClass() != null && type != null && type.isSubtypeOf(checkCast.targetClass())) { + if (type != null && type.isSubtypeOf(checkCast.type())) { PiNode piNode; boolean nonNull = state.knownNotNull.contains(checkCast.object()); piNode = graph.unique(new PiNode(checkCast.object(), lastBegin, nonNull ? StampFactory.declaredNonNull(type) : StampFactory.declared(type))); diff -r 0b8410de1365 -r 7bf5a6c42db7 graal/com.oracle.graal.snippets.test/src/com/oracle/graal/snippets/CheckCastTest.java --- a/graal/com.oracle.graal.snippets.test/src/com/oracle/graal/snippets/CheckCastTest.java Tue Oct 30 08:57:28 2012 +0100 +++ b/graal/com.oracle.graal.snippets.test/src/com/oracle/graal/snippets/CheckCastTest.java Tue Oct 30 10:22:25 2012 +0100 @@ -34,27 +34,13 @@ */ public class CheckCastTest extends TypeCheckTest { - /** - * Enables making the target type "unknown" at compile time. - */ - boolean unknown; - @Override protected void replaceProfile(StructuredGraph graph, JavaTypeProfile profile) { CheckCastNode ccn = graph.getNodes(CheckCastNode.class).first(); if (ccn != null) { - ResolvedJavaType targetClass = unknown ? null : ccn.targetClass(); - CheckCastNode ccnNew = graph.add(new CheckCastNode(ccn.targetClassInstruction(), targetClass, ccn.object(), profile)); + CheckCastNode ccnNew = graph.add(new CheckCastNode(ccn.type(), ccn.object(), profile)); graph.replaceFixedWithFixed(ccn, ccnNew); } - unknown = false; - } - - @Override - protected void test(String name, JavaTypeProfile profile, Object... args) { - super.test(name, profile, args); - unknown = true; - super.test(name, profile, args); } @Test @@ -113,12 +99,12 @@ @Test public void test8() { - test("arrayStore", profile(), new Object[100], "111"); + test("arrayStore", new Object[100], "111"); } @Test public void test8_1() { - test("arrayFill", profile(), new Object[100], "111"); + test("arrayFill", new Object[100], "111"); } public static Number asNumber(Object o) { @@ -197,6 +183,6 @@ @Test public void test10() { Object o = new Depth13[3][]; - test("asDepth12Arr", profile(), o); + test("asDepth12Arr", o); } } diff -r 0b8410de1365 -r 7bf5a6c42db7 graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/SnippetVerificationPhase.java --- a/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/SnippetVerificationPhase.java Tue Oct 30 08:57:28 2012 +0100 +++ b/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/SnippetVerificationPhase.java Tue Oct 30 10:22:25 2012 +0100 @@ -54,7 +54,7 @@ verify(!isWord(node) || ((StoreFieldNode) usage).object() != node, node, usage, "cannot store to word value"); } else if (usage instanceof CheckCastNode) { verify(!isWord(node), node, usage, "word value cannot be cast"); - verify(!isWord(((CheckCastNode) usage).targetClass()), node, usage, "cannot cast to word value"); + verify(!isWord(((CheckCastNode) usage).type()), node, usage, "cannot cast to word value"); } else if (usage instanceof LoadIndexedNode) { verify(!isWord(node) || ((LoadIndexedNode) usage).array() != node, node, usage, "cannot load from word value"); verify(!isWord(node) || ((LoadIndexedNode) usage).index() != node, node, usage, "cannot use word value as index"); diff -r 0b8410de1365 -r 7bf5a6c42db7 graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PartialEscapeAnalysisPhase.java --- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PartialEscapeAnalysisPhase.java Tue Oct 30 08:57:28 2012 +0100 +++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PartialEscapeAnalysisPhase.java Tue Oct 30 10:22:25 2012 +0100 @@ -419,7 +419,7 @@ ObjectState obj = state.objectState(x.object()); assert obj != null : x; if (obj.materializedValue == null) { - if (x.targetClass() != null && obj.virtual.type().isSubtypeOf(x.targetClass())) { + if (obj.virtual.type().isSubtypeOf(x.type())) { metricOtherRemoved.increment(); state.addAndMarkAlias(obj.virtual, x, true); // throw new UnsupportedOperationException("probably incorrect - losing dependency"); diff -r 0b8410de1365 -r 7bf5a6c42db7 graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/experimental/SplitPartialEscapeAnalysisPhase.java --- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/experimental/SplitPartialEscapeAnalysisPhase.java Tue Oct 30 08:57:28 2012 +0100 +++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/experimental/SplitPartialEscapeAnalysisPhase.java Tue Oct 30 10:22:25 2012 +0100 @@ -414,7 +414,7 @@ ObjectState obj = state.objectState(x.object()); if (obj != null) { if (obj.materializedValue == null) { - if (x.targetClass() != null && obj.virtual.type().isSubtypeOf(x.targetClass())) { + if (obj.virtual.type().isSubtypeOf(x.type())) { state.addAndMarkAlias(obj.virtual, x); effects.deleteFixedNode(x); } else {