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 5d7de5582216..2edafcb27ebc 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 @@ -203,13 +203,18 @@ public TypeData computeTypeData(AnalysisType type) { return data; } + void markTypeReachable(AnalysisType type, ScanReason reason) { + if (universe.sealed() && !type.isReachable()) { + throw AnalysisError.typeNotFound(type); + } + type.registerAsReachable(reason); + } + void markTypeInstantiated(AnalysisType type, ScanReason reason) { - if (universe.sealed()) { - AnalysisError.guarantee(type.isReachable(), "The type %s should have been reachable during analysis.", type); - AnalysisError.guarantee(type.isInstantiated(), "The type %s should have been instantiated during analysis.", type); - } else { - type.registerAsInstantiated(reason); + if (universe.sealed() && !type.isInstantiated()) { + throw AnalysisError.typeNotFound(type); } + type.registerAsInstantiated(reason); } public JavaConstant getImageHeapConstant(JavaConstant constant) { @@ -278,9 +283,9 @@ protected ImageHeapConstant getOrCreateImageHeapConstant(JavaConstant javaConsta return existingTask instanceof ImageHeapConstant ? (ImageHeapConstant) existingTask : ((AnalysisFuture) existingTask).ensureDone(); } - private static void ensureFieldPositionsComputed(ImageHeapConstant baseLayerConstant, ScanReason reason) { + private void ensureFieldPositionsComputed(ImageHeapConstant baseLayerConstant, ScanReason reason) { AnalysisType objectType = baseLayerConstant.getType(); - objectType.registerAsReachable(reason); + markTypeReachable(objectType, reason); objectType.getStaticFields(); objectType.getInstanceFields(true); } @@ -331,7 +336,7 @@ private ImageHeapArray createImageHeapObjectArray(JavaConstant constant, Analysi /* Read hosted array element values only when the array is initialized. */ array.constantData.hostedValuesReader = new AnalysisFuture<>(() -> { checkSealed(reason, "Trying to materialize an ImageHeapObjectArray for %s after the ImageHeapScanner is sealed.", constant); - type.registerAsReachable(reason); + markTypeReachable(type, reason); ScanReason arrayReason = new ArrayScan(type, array, reason); Object[] elementValues = new Object[length]; for (int idx = 0; idx < length; idx++) { @@ -367,10 +372,10 @@ private ImageHeapInstance createImageHeapInstance(JavaConstant constant, Analysi /* If this is a Class constant register the corresponding type as reachable. */ AnalysisType typeFromClassConstant = (AnalysisType) constantReflection.asJavaType(instance); if (typeFromClassConstant != null) { - typeFromClassConstant.registerAsReachable(reason); + markTypeReachable(typeFromClassConstant, reason); } /* We are about to query the type's fields, the type must be marked as reachable. */ - type.registerAsReachable(reason); + markTypeReachable(type, reason); ResolvedJavaField[] instanceFields = type.getInstanceFields(true); Object[] hostedFieldValues = new Object[instanceFields.length]; for (ResolvedJavaField javaField : instanceFields) { diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/image/NativeImageCodeCache.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/image/NativeImageCodeCache.java index 0ba4177b7ff6..863c241d40a5 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/image/NativeImageCodeCache.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/image/NativeImageCodeCache.java @@ -45,6 +45,7 @@ import java.util.List; import java.util.Map; import java.util.Map.Entry; +import java.util.Optional; import java.util.Set; import java.util.stream.Collectors; @@ -321,8 +322,14 @@ protected void buildRuntimeMetadata(DebugContext debug, SnippetReflectionProvide // Build run-time metadata. HostedFrameInfoCustomization frameInfoCustomization = new HostedFrameInfoCustomization(); CodeInfoEncoder.Encoders encoders = new CodeInfoEncoder.Encoders(true, clazz -> { - if (clazz != null && !imageHeap.hMetaAccess.optionalLookupJavaType(clazz).isPresent()) { - throw VMError.shouldNotReachHere("Type added to the runtime metadata without being seen by the analysis: %s", clazz); + if (clazz != null) { + Optional hostedType = imageHeap.hMetaAccess.optionalLookupJavaType(clazz); + if (hostedType.isPresent()) { + boolean reachable = hostedType.get().getWrapped().isReachable(); + VMError.guarantee(reachable, "Type added to the runtime metadata was seen by the analysis, but not marked as reachable: %s", clazz); + } else { + throw VMError.shouldNotReachHere("Type added to the runtime metadata without being seen by the analysis: %s", clazz); + } } }); HostedConstantAccess hostedConstantAccess = new HostedConstantAccess(snippetReflection); diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/reflect/ReflectionDataBuilder.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/reflect/ReflectionDataBuilder.java index 4ed3331b39fd..5b6941dc6bf0 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/reflect/ReflectionDataBuilder.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/reflect/ReflectionDataBuilder.java @@ -683,6 +683,7 @@ private void checkSubtypeForOverridingFields(AnalysisType subtype, Collection