Skip to content

Commit dbccfc5

Browse files
committed
Refactor heap scanning.
1 parent b0dc1b8 commit dbccfc5

File tree

51 files changed

+2233
-149
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

51 files changed

+2233
-149
lines changed

sdk/src/org.graalvm.nativeimage/src/org/graalvm/nativeimage/impl/RuntimeReflectionSupport.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2017, 2021, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2017, 2022, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* The Universal Permissive License (UPL), Version 1.0
@@ -58,4 +58,6 @@ public interface RuntimeReflectionSupport extends ReflectionRegistry {
5858
int getReflectionMethodsCount();
5959

6060
int getReflectionFieldsCount();
61+
62+
boolean requiresProcessing();
6163
}

substratevm/ci_includes/gate.hocon

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ builds += [
6969
}
7070
${labsjdk-ce-17} ${svm-common-gate} ${svm-common-windows-jdk17} ${svmUnittest} {
7171
name: "gate-svm-windows-basics"
72+
timelimit: "1:30:00"
7273
run: [
7374
${svm-cmd-gate} ["build,helloworld,test,svmjunit"]
7475
]

substratevm/mx.substratevm/suite.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -429,6 +429,8 @@
429429
"jdk.internal.module",
430430
"sun.text.spi",
431431
"jdk.internal.reflect",
432+
"sun.util.cldr",
433+
"sun.util.locale"
432434
],
433435
"jdk.internal.vm.ci" : [
434436
"jdk.vm.ci.runtime",
@@ -736,6 +738,7 @@
736738
"sun.reflect.annotation",
737739
"sun.reflect.generics.repository",
738740
"jdk.internal.reflect",
741+
"sun.reflect.generics.scope"
739742
],
740743
"jdk.internal.vm.ci" : [
741744
"jdk.vm.ci.code",
@@ -1178,7 +1181,9 @@
11781181
"sun.reflect.generics.reflectiveObjects",
11791182
"sun.reflect.generics.repository",
11801183
"sun.reflect.generics.tree",
1184+
"sun.reflect.generics.scope",
11811185
"sun.util.calendar",
1186+
"sun.util.locale",
11821187
"sun.security.jca",
11831188
"sun.security.util",
11841189
"sun.security.provider",
@@ -1187,6 +1192,7 @@
11871192
"sun.reflect.generics.repository",
11881193
"jdk.internal.org.objectweb.asm",
11891194
"sun.util.locale.provider",
1195+
"sun.util.cldr",
11901196
"sun.util.resources",
11911197
"sun.invoke.util",
11921198
"sun.net",
@@ -1478,6 +1484,8 @@
14781484
"exports" : [
14791485
"com.oracle.graal.pointsto",
14801486
"com.oracle.graal.pointsto.api",
1487+
"com.oracle.graal.pointsto.heap",
1488+
"com.oracle.graal.pointsto.heap.value",
14811489
"com.oracle.graal.pointsto.reports",
14821490
"com.oracle.graal.pointsto.constraints",
14831491
"com.oracle.graal.pointsto.util",

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,4 +122,7 @@ default void onFieldAccessed(AnalysisField field) {
122122
default void onTypeInstantiated(AnalysisType type, UsageKind usageKind) {
123123
}
124124

125+
@SuppressWarnings("unused")
126+
default void onTypeInitialized(AnalysisType type) {
127+
}
125128
}

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

Lines changed: 36 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,6 @@
5757
import org.graalvm.compiler.printer.GraalDebugHandlersFactory;
5858
import org.graalvm.nativeimage.hosted.Feature;
5959

60-
import com.oracle.graal.pointsto.ObjectScanner.ReusableSet;
6160
import com.oracle.graal.pointsto.api.HostVM;
6261
import com.oracle.graal.pointsto.api.PointstoOptions;
6362
import com.oracle.graal.pointsto.constraints.UnsupportedFeatures;
@@ -128,7 +127,7 @@ public abstract class PointsToAnalysis implements BigBang {
128127
private final CompletionExecutor.Timing timing;
129128

130129
public final Timer typeFlowTimer;
131-
public final Timer checkObjectsTimer;
130+
public final Timer verifyHeapTimer;
132131
public final Timer processFeaturesTimer;
133132
public final Timer analysisTimer;
134133

@@ -142,7 +141,7 @@ public PointsToAnalysis(OptionValues options, AnalysisUniverse universe, HostedP
142141
this.hostVM = hostVM;
143142
String imageName = hostVM.getImageName();
144143
this.typeFlowTimer = new Timer(imageName, "(typeflow)", false);
145-
this.checkObjectsTimer = new Timer(imageName, "(objects)", false);
144+
this.verifyHeapTimer = new Timer(imageName, "(verify)", false);
146145
this.processFeaturesTimer = new Timer(imageName, "(features)", false);
147146
this.analysisTimer = new Timer(imageName, "analysis", true);
148147

@@ -194,14 +193,14 @@ public Timer getProcessFeaturesTimer() {
194193
@Override
195194
public void printTimers() {
196195
typeFlowTimer.print();
197-
checkObjectsTimer.print();
196+
verifyHeapTimer.print();
198197
processFeaturesTimer.print();
199198
}
200199

201200
@Override
202201
public void printTimerStatistics(PrintWriter out) {
203202
StatisticsPrinter.print(out, "typeflow_time_ms", typeFlowTimer.getTotalTime());
204-
StatisticsPrinter.print(out, "objects_time_ms", checkObjectsTimer.getTotalTime());
203+
StatisticsPrinter.print(out, "verify_time_ms", verifyHeapTimer.getTotalTime());
205204
StatisticsPrinter.print(out, "features_time_ms", processFeaturesTimer.getTotalTime());
206205
StatisticsPrinter.print(out, "total_analysis_time_ms", analysisTimer.getTotalTime());
207206

@@ -323,13 +322,15 @@ public void cleanupAfterAnalysis() {
323322
allSynchronizedTypeFlow = null;
324323
unsafeLoads = null;
325324
unsafeStores = null;
326-
scannedObjects = null;
327325

328326
ConstantObjectsProfiler.constantTypes.clear();
329327

330328
universe.getTypes().forEach(AnalysisType::cleanupAfterAnalysis);
331329
universe.getFields().forEach(AnalysisField::cleanupAfterAnalysis);
332330
universe.getMethods().forEach(AnalysisMethod::cleanupAfterAnalysis);
331+
332+
universe.getHeapScanner().cleanupAfterAnalysis();
333+
universe.getHeapVerifier().cleanupAfterAnalysis();
333334
}
334335

335336
@Override
@@ -570,10 +571,6 @@ public ConstantFieldProvider getConstantFieldProvider() {
570571
return providers.getConstantFieldProvider();
571572
}
572573

573-
public CompletionExecutor getExecutor() {
574-
return executor;
575-
}
576-
577574
@Override
578575
public void checkUserLimitations() {
579576
}
@@ -630,26 +627,9 @@ public void postTask(final DebugContextRunnable task) {
630627
public boolean finish() throws InterruptedException {
631628
try (Indent indent = debug.logAndIndent("starting analysis in BigBang.finish")) {
632629
universe.setAnalysisDataValid(false);
633-
boolean didSomeWork = false;
634-
635-
int numTypes;
636-
do {
637-
didSomeWork |= doTypeflow();
638-
639-
/*
640-
* Check if the object graph introduces any new types, which leads to new operations
641-
* being posted.
642-
*/
643-
assert executor.getPostedOperations() == 0;
644-
numTypes = universe.getTypes().size();
645-
try (StopTimer t = checkObjectsTimer.start()) {
646-
// track static fields
647-
checkObjectGraph();
648-
}
649-
} while (executor.getPostedOperations() != 0 || numTypes != universe.getTypes().size());
650-
630+
boolean didSomeWork = doTypeflow();
631+
assert executor.getPostedOperations() == 0;
651632
universe.setAnalysisDataValid(true);
652-
653633
return didSomeWork;
654634
}
655635
}
@@ -668,39 +648,11 @@ public boolean doTypeflow() throws InterruptedException {
668648
return didSomeWork;
669649
}
670650

671-
private ReusableSet scannedObjects = new ReusableSet();
672-
673-
@SuppressWarnings("try")
674-
private void checkObjectGraph() throws InterruptedException {
675-
scannedObjects.reset();
676-
// scan constants
677-
boolean isParallel = PointstoOptions.ScanObjectsParallel.getValue(options);
678-
ObjectScanner objectScanner = new AnalysisObjectScanner(this, isParallel ? executor : null, scannedObjects);
679-
checkObjectGraph(objectScanner);
680-
if (isParallel) {
681-
executor.start();
682-
objectScanner.scanBootImageHeapRoots(null, null);
683-
executor.complete();
684-
executor.shutdown();
685-
executor.init(timing);
686-
} else {
687-
objectScanner.scanBootImageHeapRoots(null, null);
688-
}
689-
}
690-
691651
@Override
692652
public HeapScanningPolicy scanningPolicy() {
693653
return heapScanningPolicy;
694654
}
695655

696-
/**
697-
* Traverses the object graph to discover references to new types.
698-
*
699-
* @param objectScanner
700-
*/
701-
protected void checkObjectGraph(ObjectScanner objectScanner) {
702-
}
703-
704656
@Override
705657
public HostVM getHostVM() {
706658
return hostVM;
@@ -744,8 +696,9 @@ public void runAnalysis(DebugContext debugContext, Function<AnalysisUniverse, Bo
744696
"The analysis itself %s find a change in type states in the last iteration.",
745697
numIterations, analysisChanged ? "DID" : "DID NOT"));
746698
}
747-
748-
/* Allow features to change the universe. */
699+
/*
700+
* Allow features to change the universe.
701+
*/
749702
int numTypes = universe.getTypes().size();
750703
int numMethods = universe.getMethods().size();
751704
int numFields = universe.getFields().size();
@@ -754,12 +707,35 @@ public void runAnalysis(DebugContext debugContext, Function<AnalysisUniverse, Bo
754707
throw AnalysisError.shouldNotReachHere(
755708
"When a feature makes more types, methods, or fields reachable, it must require another analysis iteration via DuringAnalysisAccess.requireAnalysisIteration()");
756709
}
757-
return;
710+
/*
711+
* Manual rescanning doesn't explicitly require analysis iterations, but it can
712+
* insert some pending operations.
713+
*/
714+
boolean pendingOperations = executor.getPostedOperations() > 0;
715+
if (pendingOperations) {
716+
System.out.println("Found pending operations, continuing analysis.");
717+
continue;
718+
}
719+
/* Outer analysis loop is done. Check if heap verification modifies analysis. */
720+
if (!analysisModified()) {
721+
return;
722+
}
758723
}
759724
}
760725
}
761726
}
762727

728+
@SuppressWarnings("try")
729+
private boolean analysisModified() throws InterruptedException {
730+
boolean analysisModified;
731+
try (StopTimer ignored = verifyHeapTimer.start()) {
732+
analysisModified = universe.getHeapVerifier().requireAnalysisIteration(executor);
733+
}
734+
/* Initialize for the next iteration. */
735+
executor.init(timing);
736+
return analysisModified;
737+
}
738+
763739
@SuppressFBWarnings(value = "NP_NONNULL_PARAM_VIOLATION", justification = "ForkJoinPool does support null for the exception handler.")
764740
public static ForkJoinPool createExecutor(DebugContext debug, int numberOfThreads) {
765741
ForkJoinPool.ForkJoinWorkerThreadFactory factory = debugThreadFactory(debug.areScopesEnabled() || debug.areMetricsEnabled() ? debug : null);

0 commit comments

Comments
 (0)