diff --git a/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/flow/MethodTypeFlowBuilder.java b/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/flow/MethodTypeFlowBuilder.java index 25bdd2c1930a..4acd3161204c 100644 --- a/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/flow/MethodTypeFlowBuilder.java +++ b/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/flow/MethodTypeFlowBuilder.java @@ -357,6 +357,8 @@ protected boolean ignoreConstant(ConstantNode cn) { if (((BytecodeExceptionNode) usage).getExceptionKind() != BytecodeExceptionKind.CLASS_CAST) { return false; } + } else if (usage instanceof FrameState) { + /* FrameState usages are only for debugging and not necessary for correctness. */ } else { return false; } diff --git a/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/heap/ImageHeapScanner.java b/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/heap/ImageHeapScanner.java index cc9e5fd727d6..8f93dd21996b 100644 --- a/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/heap/ImageHeapScanner.java +++ b/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/heap/ImageHeapScanner.java @@ -378,6 +378,11 @@ protected ImageHeapConstant createImageHeapObject(JavaConstant constant, ScanRea return value; })); } + + AnalysisType typeFromClassConstant = (AnalysisType) constantReflection.asJavaType(constant); + if (typeFromClassConstant != null) { + typeFromClassConstant.registerAsReachable(); + } } /* diff --git a/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/results/StrengthenGraphs.java b/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/results/StrengthenGraphs.java index c0beb04d0875..315daf8a4ef4 100644 --- a/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/results/StrengthenGraphs.java +++ b/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/results/StrengthenGraphs.java @@ -314,12 +314,9 @@ public void simplify(Node n, SimplifierTool tool) { } else if (n instanceof ClassIsAssignableFromNode) { ClassIsAssignableFromNode node = (ClassIsAssignableFromNode) n; - ValueNode thisClass = node.getThisClass(); - if (thisClass.isConstant()) { - AnalysisType thisType = (AnalysisType) tool.getConstantReflection().asJavaType(thisClass.asConstant()); - if (!thisType.isReachable()) { - node.replaceAndDelete(LogicConstantNode.contradiction(graph)); - } + AnalysisType nonReachableType = asConstantNonReachableType(node.getThisClass(), tool); + if (nonReachableType != null) { + node.replaceAndDelete(LogicConstantNode.contradiction(graph)); } } else if (n instanceof BytecodeExceptionNode) { @@ -330,14 +327,23 @@ public void simplify(Node n, SimplifierTool tool) { */ BytecodeExceptionNode node = (BytecodeExceptionNode) n; if (node.getExceptionKind() == BytecodeExceptionNode.BytecodeExceptionKind.CLASS_CAST) { - ValueNode expectedClass = node.getArguments().get(1); - if (expectedClass.isConstant()) { - AnalysisType expectedType = (AnalysisType) tool.getConstantReflection().asJavaType(expectedClass.asConstant()); - if (expectedType != null && !expectedType.isReachable()) { - String expectedName = getTypeName(expectedType); - ConstantNode expectedConstant = ConstantNode.forConstant(tool.getConstantReflection().forString(expectedName), tool.getMetaAccess(), graph); - node.getArguments().set(1, expectedConstant); - } + AnalysisType nonReachableType = asConstantNonReachableType(node.getArguments().get(1), tool); + if (nonReachableType != null) { + node.getArguments().set(1, ConstantNode.forConstant(tool.getConstantReflection().forString(getTypeName(nonReachableType)), tool.getMetaAccess(), graph)); + } + } + + } else if (n instanceof FrameState) { + /* + * We do not want a type to be reachable only to be used for debugging purposes in a + * FrameState. We could just null out the frame slot, but to leave as much + * information as possible we replace the java.lang.Class with the type name. + */ + FrameState node = (FrameState) n; + for (int i = 0; i < node.values().size(); i++) { + AnalysisType nonReachableType = asConstantNonReachableType(node.values().get(i), tool); + if (nonReachableType != null) { + node.values().set(i, ConstantNode.forConstant(tool.getConstantReflection().forString(getTypeName(nonReachableType)), tool.getMetaAccess(), graph)); } } @@ -352,6 +358,16 @@ public void simplify(Node n, SimplifierTool tool) { } } + private AnalysisType asConstantNonReachableType(ValueNode value, CoreProviders providers) { + if (value != null && value.isConstant()) { + AnalysisType expectedType = (AnalysisType) providers.getConstantReflection().asJavaType(value.asConstant()); + if (expectedType != null && !expectedType.isReachable()) { + return expectedType; + } + } + return null; + } + private void handleInvoke(Invoke invoke, SimplifierTool tool) { PointsToAnalysis pta = getAnalysis(); FixedNode node = invoke.asFixedNode(); diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/ameta/AnalysisConstantReflectionProvider.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/ameta/AnalysisConstantReflectionProvider.java index d5c0738c8fbc..ec7e1dfe7e2a 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/ameta/AnalysisConstantReflectionProvider.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/ameta/AnalysisConstantReflectionProvider.java @@ -37,10 +37,8 @@ import com.oracle.graal.pointsto.heap.value.ValueSupplier; import com.oracle.graal.pointsto.infrastructure.UniverseMetaAccess; import com.oracle.graal.pointsto.meta.AnalysisField; -import com.oracle.graal.pointsto.meta.AnalysisType; import com.oracle.graal.pointsto.meta.AnalysisUniverse; import com.oracle.graal.pointsto.meta.UninitializedStaticFieldValueReader; -import com.oracle.svm.core.BuildPhaseProvider; import com.oracle.svm.core.RuntimeAssertionsSupport; import com.oracle.svm.core.annotate.InjectAccessors; import com.oracle.svm.core.graal.meta.SharedConstantReflectionProvider; @@ -308,16 +306,6 @@ public JavaConstant asJavaClass(ResolvedJavaType type) { return SubstrateObjectConstant.forObject(getHostVM().dynamicHub(type)); } - protected static void registerAsReachable(SVMHost hostVM, DynamicHub dynamicHub) { - assert dynamicHub != null; - /* Make sure that the DynamicHub of this type ends up in the native image. */ - AnalysisType valueType = hostVM.lookupType(dynamicHub); - if (!valueType.isReachable() && BuildPhaseProvider.isAnalysisFinished()) { - throw VMError.shouldNotReachHere("Registering type as reachable after analysis: " + valueType); - } - valueType.registerAsReachable(); - } - private SVMHost getHostVM() { return (SVMHost) universe.hostVM(); } diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/ameta/HostedDynamicHubFeature.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/ameta/HostedDynamicHubFeature.java index 0f3b5d96a8b5..a002f68a1f99 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/ameta/HostedDynamicHubFeature.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/ameta/HostedDynamicHubFeature.java @@ -49,12 +49,8 @@ private Object replace(Object source) { if (source instanceof Class) { Class clazz = (Class) source; DynamicHub dynamicHub = hostVM.dynamicHub(metaAccess.lookupJavaType(clazz)); - AnalysisConstantReflectionProvider.registerAsReachable(hostVM, dynamicHub); return dynamicHub; } - if (source instanceof DynamicHub) { - AnalysisConstantReflectionProvider.registerAsReachable(hostVM, (DynamicHub) source); - } return source; } }