Skip to content

Commit 0f8d9bf

Browse files
committed
[GR-36898] Re-run analysis if verification marks types as reachable.
PullRequest: graal/11028
2 parents 1377605 + 3562b7f commit 0f8d9bf

File tree

6 files changed

+46
-67
lines changed

6 files changed

+46
-67
lines changed

substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/PointsToAnalysis.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -718,7 +718,6 @@ public void runAnalysis(DebugContext debugContext, Function<AnalysisUniverse, Bo
718718
}
719719
/* Outer analysis loop is done. Check if heap verification modifies analysis. */
720720
if (!analysisModified()) {
721-
assert universe.getHeapVerifier().checkTypes();
722721
return;
723722
}
724723
}

substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/heap/HeapSnapshotVerifier.java

Lines changed: 35 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ public boolean requireAnalysisIteration(CompletionExecutor executor) throws Inte
7777
info("Verifying the heap snapshot...");
7878
analysisModified = false;
7979
heapPatched = false;
80+
int reachableTypesBefore = bb.getUniverse().getReachableTypes();
8081
iterations++;
8182
scannedObjects.reset();
8283
ObjectScanner objectScanner = new ObjectScanner(bb, executor, scannedObjects, new ScanningObserver());
@@ -85,32 +86,29 @@ public boolean requireAnalysisIteration(CompletionExecutor executor) throws Inte
8586
objectScanner.scanBootImageHeapRoots();
8687
executor.complete();
8788
executor.shutdown();
89+
int verificationReachableTypes = bb.getUniverse().getReachableTypes() - reachableTypesBefore;
8890
if (heapPatched) {
8991
info("Heap verification patched the heap snapshot.");
9092
} else {
9193
info("Heap verification didn't find any heap snapshot modifications.");
9294
}
95+
if (verificationReachableTypes > 0) {
96+
info("Heap verification made " + verificationReachableTypes + " new types reachable.");
97+
} else {
98+
info("Heap verification didn't make any new types reachable.");
99+
}
93100
if (analysisModified) {
94101
info("Heap verification modified the analysis state. Executing an additional analysis iteration.");
95102
} else {
96103
info("Heap verification didn't modify the analysis state. Heap state stabilized after " + iterations + " iterations.");
97104
info("Exiting analysis.");
98105
}
99-
return analysisModified;
106+
return analysisModified || verificationReachableTypes > 0;
100107
}
101108

102109
protected void scanTypes(@SuppressWarnings("unused") ObjectScanner objectScanner) {
103110
}
104111

105-
public boolean checkTypes() {
106-
for (AnalysisType t : bb.getUniverse().getTypes()) {
107-
if (t.isReachable() && !initializationInfoComputed(t)) {
108-
throw AnalysisError.shouldNotReachHere("Type is not initialized " + t.getName());
109-
}
110-
}
111-
return true;
112-
}
113-
114112
public void cleanupAfterAnalysis() {
115113
scannedObjects = null;
116114
}
@@ -224,80 +222,62 @@ public void forScannedConstant(JavaConstant value, ScanReason reason) {
224222
Object object = constantAsObject(bb, value);
225223
Class<?> objectClass = object.getClass();
226224
if (objectClass.equals(Class.class)) {
227-
/*
228-
* Ensure that java.lang.Class constants are fully initialized and scanned. If a
229-
* type is marked as reachable during the verification then it's class
230-
* initialization info will be missing since
231-
* ClassInitializationFeature.buildClassInitializationInfo() hasn't processed it
232-
* yet.
233-
*/
225+
/* Ensure that java.lang.Class constants are scanned. */
234226
AnalysisType type = bb.getMetaAccess().lookupJavaType((Class<?>) object);
235-
if (!initializationInfoComputed(type)) {
236-
onNoInitInfoForClassConstant(type, reason);
237-
} else {
238-
ensureTypeScanned(value, type, reason);
239-
}
227+
ensureTypeScanned(value, type, reason);
240228
} else {
241229
/*
242-
* Ensure that the Class of any other constants are also fully initialized and
243-
* scanned. An object replacer can introduce new types which otherwise could be
244-
* missed by the verifier. For example
245-
* com.oracle.svm.hosted.annotation.AnnotationObjectReplacer creates annotation
246-
* proxy types on the fly for constant annotation objects.
230+
* Ensure that the Class of any other constants are also scanned. An object replacer
231+
* can introduce new types which otherwise could be missed by the verifier. For
232+
* example com.oracle.svm.hosted.annotation.AnnotationObjectReplacer creates
233+
* annotation proxy types on the fly for constant annotation objects.
247234
*/
248235
AnalysisType type = bb.getMetaAccess().lookupJavaType(objectClass);
249-
if (!initializationInfoComputed(type)) {
250-
onNoInitInfoForObjectType(value, type, reason);
251-
} else {
252-
ensureTypeScanned(bb.getConstantReflectionProvider().asJavaClass(type), type, reason);
253-
}
236+
ensureTypeScanned(value, bb.getConstantReflectionProvider().asJavaClass(type), type, reason);
254237
}
255238
}
256239

257-
private void ensureTypeScanned(JavaConstant value, AnalysisType type, ScanReason reason) {
240+
private void ensureTypeScanned(JavaConstant typeConstant, AnalysisType type, ScanReason reason) {
241+
ensureTypeScanned(null, typeConstant, type, reason);
242+
}
243+
244+
private void ensureTypeScanned(JavaConstant object, JavaConstant typeConstant, AnalysisType type, ScanReason reason) {
258245
AnalysisError.guarantee(type.isReachable(), "The heap snapshot verifier discovered a type not marked as reachable " + type.toJavaName());
259-
AnalysisFuture<ImageHeapObject> task = imageHeap.getTask(value);
246+
AnalysisFuture<ImageHeapObject> task = imageHeap.getTask(typeConstant);
260247
/* Make sure the DynamicHub value is scanned. */
261248
if (task == null) {
262-
onNoTaskForClassConstant(value, reason);
263-
scanner.toImageHeapObject(value, reason, null);
249+
onNoTaskForClassConstant(type, reason);
250+
scanner.toImageHeapObject(typeConstant, reason, null);
264251
heapPatched = true;
265252
} else {
266253
if (task.isDone()) {
267254
JavaConstant snapshot = task.guardedGet().getObject();
268-
if (!Objects.equals(snapshot, value)) {
269-
throw error(reason, "Value mismatch for class constant snapshot: %s %n new value: %s %n", snapshot, value);
255+
if (!Objects.equals(snapshot, typeConstant)) {
256+
throw error(reason, "Value mismatch for class constant snapshot: %s %n new value: %s %n", snapshot, typeConstant);
270257
}
271258
} else {
272-
/* If there is a task for the hub it should have been triggered. */
273-
throw error(reason, "Snapshot not yet computed for class constant %n new value: %s %n", value);
259+
onTaskForClassConstantNotDone(object, type, reason);
260+
task.ensureDone();
274261
}
275262
}
276263
}
277264
}
278265

279-
protected boolean initializationInfoComputed(@SuppressWarnings("unused") AnalysisType type) {
280-
return true;
281-
}
282-
283-
private void onNoInitInfoForClassConstant(AnalysisType type, ScanReason reason) {
266+
private void onNoTaskForClassConstant(AnalysisType type, ScanReason reason) {
284267
analysisModified = true;
285268
if (printAll()) {
286-
warning(reason, "No initialization info computed for class constant %s %n", type.toJavaName());
269+
warning(reason, "No snapshot task found for class constant %s %n", type.toJavaName());
287270
}
288271
}
289272

290-
private void onNoInitInfoForObjectType(JavaConstant object, AnalysisType type, ScanReason reason) {
273+
private void onTaskForClassConstantNotDone(JavaConstant object, AnalysisType type, ScanReason reason) {
291274
analysisModified = true;
292275
if (printAll()) {
293-
warning(reason, "No initialization info computed for class %s of object %s %n", type.toJavaName(), object);
294-
}
295-
}
296-
297-
private void onNoTaskForClassConstant(JavaConstant value, ScanReason reason) {
298-
analysisModified = true;
299-
if (printAll()) {
300-
warning(reason, "No snapshot task found for class constant %s %n", value);
276+
if (object != null) {
277+
warning(reason, "Snapshot not yet computed for class %s of object %s %n", type.toJavaName(), object);
278+
} else {
279+
warning(reason, "Snapshot not yet computed for class constant %n new value: %s %n", type.toJavaName());
280+
}
301281
}
302282
}
303283

substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/heap/ImageHeapScanner.java

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -388,10 +388,6 @@ private boolean notifyAnalysis(JavaConstant array, AnalysisType arrayType, JavaC
388388
return analysisModified;
389389
}
390390

391-
protected JavaConstant interceptArrayElement(JavaConstant elementValue) {
392-
return elementValue;
393-
}
394-
395391
void onObjectReachable(ImageHeapObject imageHeapObject) {
396392
AnalysisType objectType = metaAccess.lookupJavaType(imageHeapObject.getObject());
397393
imageHeap.add(objectType, imageHeapObject);

substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/meta/AnalysisType.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -463,6 +463,7 @@ public boolean registerAsReachable() {
463463

464464
private void markReachable() {
465465
if (AtomicUtils.atomicMark(isReachable)) {
466+
universe.notifyReachableType();
466467
universe.hostVM.checkForbidden(this, UsageKind.Reachable);
467468
if (isArray()) {
468469
/*

substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/meta/AnalysisUniverse.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,8 @@ public class AnalysisUniverse implements Universe {
114114
private final SnippetReflectionProvider snippetReflection;
115115
private final AnalysisFactory analysisFactory;
116116

117+
private final AtomicInteger numReachableTypes = new AtomicInteger();
118+
117119
private AnalysisType objectClass;
118120
private AnalysisType cloneableClass;
119121
private final JavaKind wordKind;
@@ -730,4 +732,12 @@ public void setHeapVerifier(HeapSnapshotVerifier heapVerifier) {
730732
public HeapSnapshotVerifier getHeapVerifier() {
731733
return heapVerifier;
732734
}
735+
736+
public void notifyReachableType() {
737+
numReachableTypes.incrementAndGet();
738+
}
739+
740+
public int getReachableTypes() {
741+
return numReachableTypes.get();
742+
}
733743
}

substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/heap/SVMImageHeapVerifier.java

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,6 @@
3434
import com.oracle.graal.pointsto.heap.ImageHeapScanner;
3535
import com.oracle.graal.pointsto.meta.AnalysisType;
3636
import com.oracle.graal.pointsto.util.CompletionExecutor;
37-
import com.oracle.svm.core.hub.DynamicHub;
3837
import com.oracle.svm.core.meta.SubstrateObjectConstant;
3938
import com.oracle.svm.hosted.SVMHost;
4039
import com.oracle.svm.hosted.analysis.NativeImagePointsToAnalysis;
@@ -82,12 +81,6 @@ private static void verifyHub(SVMHost svmHost, ObjectScanner objectScanner, Anal
8281
objectScanner.scanConstant(hubConstant, ObjectScanner.OtherReason.HUB);
8382
}
8483

85-
@Override
86-
protected boolean initializationInfoComputed(AnalysisType type) {
87-
DynamicHub hub = svmHost().dynamicHub(type);
88-
return hub.getClassInitializationInfo() != null;
89-
}
90-
9184
private SVMHost svmHost() {
9285
return (SVMHost) bb.getHostVM();
9386
}

0 commit comments

Comments
 (0)