Skip to content

Commit 39feec1

Browse files
committed
Rename verification phase and update documentation.
1 parent 9f110a3 commit 39feec1

File tree

4 files changed

+50
-21
lines changed

4 files changed

+50
-21
lines changed

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

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -207,7 +207,20 @@ public void runAnalysis(DebugContext debugContext, Function<AnalysisUniverse, Bo
207207
private boolean analysisModified() {
208208
boolean analysisModified;
209209
try (Timer.StopTimer ignored = verifyHeapTimer.start()) {
210-
analysisModified = universe.getHeapVerifier().checkHeapSnapshot(metaAccess, executor, "after analysis", true);
210+
/*
211+
* After the analysis reaches a stable state check if the shadow heap contains all
212+
* objects reachable from roots. If this leads to analysis state changes, an additional
213+
* analysis iteration will be run.
214+
*
215+
* We reuse the analysis executor, which at this point should be in before-start state:
216+
* the analysis finished and it re-initialized the executor for the next iteration. The
217+
* verifier controls the life cycle of the executor: it starts it and then waits until
218+
* all operations are completed. The same executor is implicitly used by the shadow heap
219+
* scanner and the verifier also passes it to the root scanner, so when
220+
* checkHeapSnapshot returns all heap scanning and verification tasks are completed.
221+
*/
222+
assert executor.isBeforeStart();
223+
analysisModified = universe.getHeapVerifier().checkHeapSnapshot(metaAccess, executor, "during analysis", true);
211224
}
212225
/* Initialize for the next iteration. */
213226
executor.init(getTiming());

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,12 @@ public HeapSnapshotVerifier(BigBang bb, ImageHeap imageHeap, ImageHeapScanner sc
7373
verbosity = Options.HeapVerifierVerbosity.getValue(bb.getOptions());
7474
}
7575

76+
/**
77+
* Heap verification does a complete scan from roots (static fields and embedded constant) and
78+
* compares the object graph against the shadow heap. If any new reachable objects or primitive
79+
* values are found then the verifier automatically patches the shadow heap. If this is during
80+
* analysis then the heap scanner will also notify the analysis of the new objects.
81+
*/
7682
public boolean checkHeapSnapshot(UniverseMetaAccess metaAccess, CompletionExecutor executor, String phase, boolean forAnalysis) {
7783
info("Verifying the heap snapshot %s%s ...", phase, (forAnalysis ? ", iteration " + iterations : ""));
7884
analysisModified = false;

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

Lines changed: 26 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -534,24 +534,6 @@ protected boolean skipScanning() {
534534
return false;
535535
}
536536

537-
/**
538-
* When a re-scanning is triggered while the analysis is running in parallel, it is necessary to
539-
* do the re-scanning in a separate executor task to avoid deadlocks. For example,
540-
* lookupJavaField might need to wait for the reachability handler to be finished that actually
541-
* triggered the re-scanning.
542-
*
543-
* In the (legacy) Feature.duringAnalysis state, the executor is not running and we must not
544-
* schedule new tasks, because that would be treated as "the analysis has not finished yet". So
545-
* in that case we execute the task directly.
546-
*/
547-
private void maybeRunInExecutor(CompletionExecutor.DebugContextRunnable task) {
548-
if (bb.executorIsStarted()) {
549-
bb.postTask(task);
550-
} else {
551-
task.run(null);
552-
}
553-
}
554-
555537
public void rescanRoot(Field reflectionField) {
556538
if (skipScanning()) {
557539
return;
@@ -726,7 +708,31 @@ protected AnalysisField lookupJavaField(String className, String fieldName) {
726708
return metaAccess.lookupJavaField(ReflectionUtil.lookupField(getClass(className), fieldName));
727709
}
728710

729-
public void postTask(Runnable task) {
730-
universe.getBigbang().postTask(debug -> task.run());
711+
/**
712+
* When a re-scanning is triggered while the analysis is running in parallel, it is necessary to
713+
* do the re-scanning in a separate executor task to avoid deadlocks. For example,
714+
* lookupJavaField might need to wait for the reachability handler to be finished that actually
715+
* triggered the re-scanning. We reuse the analysis executor, whose lifetime is controlled by
716+
* the analysis engine.
717+
*
718+
* In the (legacy) Feature.duringAnalysis state, the executor is not running and we must not
719+
* schedule new tasks, because that would be treated as "the analysis has not finished yet". So
720+
* in that case we execute the task directly.
721+
*/
722+
private void maybeRunInExecutor(CompletionExecutor.DebugContextRunnable task) {
723+
if (bb.executorIsStarted()) {
724+
bb.postTask(task);
725+
} else {
726+
task.run(null);
727+
}
728+
}
729+
730+
/**
731+
* Post the task to the analysis executor. Its lifetime is controlled by the analysis engine or
732+
* the heap verifier such that all heap scanning tasks are also completed when analysis reaches
733+
* a stable state or heap verification is completed.
734+
*/
735+
private void postTask(Runnable task) {
736+
bb.postTask(debug -> task.run());
731737
}
732738
}

substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/util/CompletionExecutor.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -277,6 +277,10 @@ public void shutdown() {
277277
setState(State.UNUSED);
278278
}
279279

280+
public boolean isBeforeStart() {
281+
return state.get() == State.BEFORE_START;
282+
}
283+
280284
public boolean isStarted() {
281285
return state.get() == State.STARTED;
282286
}

0 commit comments

Comments
 (0)