|
39 | 39 | import java.util.Map;
|
40 | 40 | import java.util.Set;
|
41 | 41 | import java.util.concurrent.ConcurrentHashMap;
|
| 42 | +import java.util.concurrent.atomic.AtomicBoolean; |
42 | 43 | import java.util.concurrent.atomic.AtomicReference;
|
43 | 44 | import java.util.concurrent.atomic.AtomicReferenceFieldUpdater;
|
44 | 45 | import java.util.concurrent.locks.ReentrantLock;
|
|
61 | 62 | import com.oracle.graal.pointsto.infrastructure.WrappedJavaMethod;
|
62 | 63 | import com.oracle.graal.pointsto.reports.ReportUtils;
|
63 | 64 | import com.oracle.graal.pointsto.util.AnalysisError;
|
64 |
| -import com.oracle.graal.pointsto.util.AnalysisFuture; |
65 | 65 | import com.oracle.graal.pointsto.util.AtomicUtils;
|
66 | 66 | import com.oracle.graal.pointsto.util.ConcurrentLightHashSet;
|
67 | 67 | import com.oracle.svm.common.meta.MultiMethod;
|
@@ -143,8 +143,6 @@ public record Signature(String name, AnalysisType[] parameterTypes) {
|
143 | 143 |
|
144 | 144 | private final MultiMethodKey multiMethodKey;
|
145 | 145 |
|
146 |
| - private AnalysisFuture<Void> parsedCallBack; |
147 |
| - |
148 | 146 | /**
|
149 | 147 | * Map from a key to the corresponding implementation. All multi-method implementations for a
|
150 | 148 | * given Java method share the same map. This allows one to easily switch between different
|
@@ -178,6 +176,7 @@ public record Signature(String name, AnalysisType[] parameterTypes) {
|
178 | 176 | private final boolean enableReachableInCurrentLayer;
|
179 | 177 |
|
180 | 178 | private final AtomicReference<GraphCacheEntry> parsedGraphCacheState = new AtomicReference<>(GraphCacheEntry.UNPARSED);
|
| 179 | + private final AtomicBoolean trackedGraphPersisted = new AtomicBoolean(false); |
181 | 180 |
|
182 | 181 | private EncodedGraph analyzedGraph;
|
183 | 182 |
|
@@ -551,17 +550,10 @@ protected void notifyImplementationInvokedCallbacks() {
|
551 | 550 | ConcurrentLightHashSet.removeElementIf(this, implementationInvokedNotificationsUpdater, ElementNotification::isNotified);
|
552 | 551 | }
|
553 | 552 |
|
554 |
| - public void registerParsedGraphCallback(AnalysisFuture<Void> parsingCallBack) { |
555 |
| - this.parsedCallBack = parsingCallBack; |
556 |
| - if (getParsedGraphCacheStateObject() instanceof AnalysisParsedGraph) { |
557 |
| - notifyParsedCallback(); |
558 |
| - } |
559 |
| - } |
560 |
| - |
561 |
| - private void notifyParsedCallback() { |
562 |
| - if (parsedCallBack != null) { |
563 |
| - parsedCallBack.ensureDone(); |
564 |
| - parsedCallBack = null; |
| 553 | + private void persistTrackedGraph(AnalysisParsedGraph graph) { |
| 554 | + if (isTrackedAcrossLayers() && trackedGraphPersisted.compareAndSet(false, true)) { |
| 555 | + ImageLayerWriter imageLayerWriter = getUniverse().getImageLayerWriter(); |
| 556 | + imageLayerWriter.persistAnalysisParsedGraph(this, graph); |
565 | 557 | }
|
566 | 558 | }
|
567 | 559 |
|
@@ -696,15 +688,16 @@ public void onReachable(Object reason) {
|
696 | 688 | @Override
|
697 | 689 | protected void onTrackedAcrossLayers(Object reason) {
|
698 | 690 | AnalysisError.guarantee(!getUniverse().sealed(), "Method %s was marked as tracked after the universe was sealed", this);
|
699 |
| - ImageLayerWriter imageLayerWriter = getUniverse().getImageLayerWriter(); |
700 |
| - imageLayerWriter.onTrackedAcrossLayer(this, reason); |
| 691 | + getUniverse().getImageLayerWriter().onTrackedAcrossLayer(this, reason); |
701 | 692 | declaringClass.registerAsTrackedAcrossLayers(reason);
|
702 | 693 | for (AnalysisType parameter : toParameterList()) {
|
703 | 694 | parameter.registerAsTrackedAcrossLayers(reason);
|
704 | 695 | }
|
705 | 696 | signature.getReturnType().registerAsTrackedAcrossLayers(reason);
|
706 | 697 |
|
707 |
| - registerParsedGraphCallback(new AnalysisFuture<>(() -> imageLayerWriter.persistAnalysisParsedGraph(this))); |
| 698 | + if (getParsedGraphCacheStateObject() instanceof AnalysisParsedGraph analysisParsedGraph) { |
| 699 | + persistTrackedGraph(analysisParsedGraph); |
| 700 | + } |
708 | 701 | }
|
709 | 702 |
|
710 | 703 | public void registerOverrideReachabilityNotification(MethodOverrideReachableNotification notification) {
|
@@ -1254,9 +1247,13 @@ private AnalysisParsedGraph setGraph(BigBang bb, Stage stage, GraphCacheEntry ex
|
1254 | 1247 | boolean result = parsedGraphCacheState.compareAndSet(lockState, newEntry);
|
1255 | 1248 | AnalysisError.guarantee(result, "State transition failed");
|
1256 | 1249 |
|
1257 |
| - notifyParsedCallback(); |
| 1250 | + AnalysisParsedGraph analysisParsedGraph = (AnalysisParsedGraph) newEntry.get(stage); |
| 1251 | + |
| 1252 | + if (stage == Stage.finalStage()) { |
| 1253 | + persistTrackedGraph(analysisParsedGraph); |
| 1254 | + } |
1258 | 1255 |
|
1259 |
| - return (AnalysisParsedGraph) newEntry.get(stage); |
| 1256 | + return analysisParsedGraph; |
1260 | 1257 |
|
1261 | 1258 | } catch (Throwable ex) {
|
1262 | 1259 | parsedGraphCacheState.set(GraphCacheEntry.createParsingError(stage, expectedValue, ex));
|
|
0 commit comments