diff --git a/substratevm/src/com.oracle.graal.pointsto.standalone/src/com/oracle/graal/pointsto/standalone/heap/StandaloneHeapSnapshotVerifier.java b/substratevm/src/com.oracle.graal.pointsto.standalone/src/com/oracle/graal/pointsto/standalone/heap/StandaloneHeapSnapshotVerifier.java index 98926736963a..eb20034344a6 100644 --- a/substratevm/src/com.oracle.graal.pointsto.standalone/src/com/oracle/graal/pointsto/standalone/heap/StandaloneHeapSnapshotVerifier.java +++ b/substratevm/src/com.oracle.graal.pointsto.standalone/src/com/oracle/graal/pointsto/standalone/heap/StandaloneHeapSnapshotVerifier.java @@ -41,9 +41,9 @@ public StandaloneHeapSnapshotVerifier(BigBang bb, ImageHeap imageHeap, ImageHeap } @Override - protected ObjectScanner installObjectScanner(UniverseMetaAccess metaAccess, CompletionExecutor executor) { + protected ObjectScanner installObjectScanner(UniverseMetaAccess metaAccess, CompletionExecutor executor, boolean skipReachableCheck) { StandaloneImageHeapScanner standaloneImageHeapScanner = (StandaloneImageHeapScanner) this.scanner; - return new StandaloneObjectScanner(bb, executor, scannedObjects, new ScanningObserver(), standaloneImageHeapScanner.getShouldScanConstant(), + return new StandaloneObjectScanner(bb, executor, scannedObjects, new ScanningObserver(skipReachableCheck), standaloneImageHeapScanner.getShouldScanConstant(), standaloneImageHeapScanner.getShouldScanField()); } } diff --git a/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/heap/HeapSnapshotVerifier.java b/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/heap/HeapSnapshotVerifier.java index 8b2fe293b534..c02730ed3e55 100644 --- a/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/heap/HeapSnapshotVerifier.java +++ b/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/heap/HeapSnapshotVerifier.java @@ -84,20 +84,25 @@ public boolean checkHeapSnapshot(DebugContext debug, UniverseMetaAccess metaAcce return checkHeapSnapshot(metaAccess, executor, stage, false, embeddedConstants); } + public boolean checkHeapSnapshot(UniverseMetaAccess metaAccess, CompletionExecutor executor, String phase, boolean forAnalysis, Map embeddedConstants) { + return checkHeapSnapshot(metaAccess, executor, phase, forAnalysis, embeddedConstants, false); + } + /** * Heap verification does a complete scan from roots (static fields and embedded constant) and * compares the object graph against the shadow heap. If any new reachable objects or primitive * values are found then the verifier automatically patches the shadow heap. If this is during * analysis then the heap scanner will also notify the analysis of the new objects. */ - public boolean checkHeapSnapshot(UniverseMetaAccess metaAccess, CompletionExecutor executor, String phase, boolean forAnalysis, Map embeddedConstants) { + protected boolean checkHeapSnapshot(UniverseMetaAccess metaAccess, CompletionExecutor executor, String phase, boolean forAnalysis, Map embeddedConstants, + boolean skipReachableCheck) { info("Verifying the heap snapshot %s%s ...", phase, (forAnalysis ? ", iteration " + iterations : "")); analysisModified = false; heapPatched = false; int reachableTypesBefore = bb.getUniverse().getReachableTypes(); iterations++; scannedObjects.reset(); - ObjectScanner objectScanner = installObjectScanner(metaAccess, executor); + ObjectScanner objectScanner = installObjectScanner(metaAccess, executor, skipReachableCheck); executor.start(); scanTypes(objectScanner); objectScanner.scanBootImageHeapRoots(embeddedConstants); @@ -132,8 +137,8 @@ public boolean checkHeapSnapshot(UniverseMetaAccess metaAccess, CompletionExecut return analysisModified || verificationReachableTypes > 0; } - protected ObjectScanner installObjectScanner(@SuppressWarnings("unused") UniverseMetaAccess metaAccess, CompletionExecutor executor) { - return new ObjectScanner(bb, executor, scannedObjects, new ScanningObserver()); + protected ObjectScanner installObjectScanner(@SuppressWarnings("unused") UniverseMetaAccess metaAccess, CompletionExecutor executor, boolean skipReachableCheck) { + return new ObjectScanner(bb, executor, scannedObjects, new ScanningObserver(skipReachableCheck)); } protected void scanTypes(@SuppressWarnings("unused") ObjectScanner objectScanner) { @@ -144,7 +149,10 @@ public void cleanupAfterAnalysis() { protected final class ScanningObserver implements ObjectScanningObserver { - public ScanningObserver() { + private final boolean skipReachableCheck; + + public ScanningObserver(boolean skipReachableCheck) { + this.skipReachableCheck = skipReachableCheck; } @Override @@ -418,7 +426,7 @@ private void ensureTypeScanned(JavaConstant typeConstant, AnalysisType type, Sca @SuppressWarnings({"unchecked", "rawtypes"}) private void ensureTypeScanned(JavaConstant value, JavaConstant typeConstant, AnalysisType type, ScanReason reason) { - if (!type.isReachable()) { + if (!skipReachableCheck && !type.isReachable()) { error(reason, "The heap snapshot verifier discovered a type not marked as reachable: %s", type); } Object task = imageHeap.getSnapshot(typeConstant); diff --git a/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/typestate/DefaultVirtualInvokeTypeFlow.java b/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/typestate/DefaultVirtualInvokeTypeFlow.java index 4c093c434751..d3de0688bacd 100644 --- a/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/typestate/DefaultVirtualInvokeTypeFlow.java +++ b/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/typestate/DefaultVirtualInvokeTypeFlow.java @@ -37,6 +37,7 @@ import com.oracle.graal.pointsto.flow.TypeFlow; import com.oracle.graal.pointsto.meta.AnalysisMethod; import com.oracle.graal.pointsto.meta.AnalysisType; +import com.oracle.graal.pointsto.meta.BaseLayerType; import com.oracle.graal.pointsto.meta.PointsToAnalysisMethod; import com.oracle.svm.common.meta.MultiMethod.MultiMethodKey; @@ -73,7 +74,7 @@ public void onObservedUpdate(PointsToAnalysis bb) { } for (AnalysisType type : receiverState.types(bb)) { - assert receiverType.isAssignableFrom(type) : type + " should be a subtype of " + receiverType; + assert receiverType.isAssignableFrom(type) || type.getWrapped() instanceof BaseLayerType : type + " should be a subtype of " + receiverType; if (isSaturated()) { /*- * The receiver can become saturated during the callees linking, which saturates diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/heap/SVMImageHeapVerifier.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/heap/SVMImageHeapVerifier.java index 797c0431fbe3..61ddc21ea4ae 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/heap/SVMImageHeapVerifier.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/heap/SVMImageHeapVerifier.java @@ -36,6 +36,7 @@ import com.oracle.graal.pointsto.infrastructure.UniverseMetaAccess; import com.oracle.graal.pointsto.meta.AnalysisType; import com.oracle.graal.pointsto.util.CompletionExecutor; +import com.oracle.svm.core.imagelayer.ImageLayerBuildingSupport; import com.oracle.svm.hosted.SVMHost; import jdk.vm.ci.meta.Constant; @@ -48,7 +49,8 @@ public SVMImageHeapVerifier(BigBang bb, ImageHeap imageHeap, ImageHeapScanner sc @Override public boolean checkHeapSnapshot(UniverseMetaAccess metaAccess, CompletionExecutor executor, String phase, boolean forAnalysis, Map embeddedConstants) { - return super.checkHeapSnapshot(metaAccess, executor, phase, forAnalysis, embeddedConstants) || imageStateModified(); + boolean skipReachableCheck = forAnalysis && ImageLayerBuildingSupport.buildingExtensionLayer(); + return super.checkHeapSnapshot(metaAccess, executor, phase, forAnalysis, embeddedConstants, skipReachableCheck) || imageStateModified(); } /**