Skip to content

Commit 7819b15

Browse files
committed
Remove ReachabilityHandler abstraction.
1 parent 052977f commit 7819b15

File tree

3 files changed

+68
-185
lines changed

3 files changed

+68
-185
lines changed

substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/ConcurrentReachabilityHandler.java

Lines changed: 0 additions & 129 deletions
This file was deleted.

substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/FeatureImpl.java

Lines changed: 68 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
import java.util.Map;
4040
import java.util.Objects;
4141
import java.util.Set;
42+
import java.util.concurrent.ConcurrentHashMap;
4243
import java.util.function.BiConsumer;
4344
import java.util.function.Consumer;
4445
import java.util.function.Function;
@@ -59,6 +60,10 @@
5960
import com.oracle.graal.pointsto.heap.ImageHeapConstant;
6061
import com.oracle.graal.pointsto.heap.ImageHeapScanner;
6162
import com.oracle.graal.pointsto.infrastructure.SubstitutionProcessor;
63+
import com.oracle.graal.pointsto.meta.AnalysisElement;
64+
import com.oracle.graal.pointsto.meta.AnalysisElement.ElementNotification;
65+
import com.oracle.graal.pointsto.meta.AnalysisElement.MethodOverrideReachableNotification;
66+
import com.oracle.graal.pointsto.meta.AnalysisElement.SubtypeReachableNotification;
6267
import com.oracle.graal.pointsto.meta.AnalysisField;
6368
import com.oracle.graal.pointsto.meta.AnalysisMetaAccess;
6469
import com.oracle.graal.pointsto.meta.AnalysisMethod;
@@ -358,14 +363,13 @@ public SVMHost getHostVM() {
358363
public static class BeforeAnalysisAccessImpl extends AnalysisAccessBase implements Feature.BeforeAnalysisAccess {
359364

360365
private final NativeLibraries nativeLibraries;
361-
private final ReachabilityHandler reachabilityHandler;
362366
private final ClassForNameSupport classForNameSupport;
367+
private final Map<Consumer<DuringAnalysisAccess>, ElementNotification> reachabilityNotifications = new ConcurrentHashMap<>();
363368

364369
public BeforeAnalysisAccessImpl(FeatureHandler featureHandler, ImageClassLoader imageClassLoader, Inflation bb, NativeLibraries nativeLibraries,
365370
DebugContext debugContext) {
366371
super(featureHandler, imageClassLoader, bb, debugContext);
367372
this.nativeLibraries = nativeLibraries;
368-
this.reachabilityHandler = new ConcurrentReachabilityHandler();
369373
this.classForNameSupport = ClassForNameSupport.currentLayer();
370374
}
371375

@@ -469,22 +473,80 @@ public void registerHierarchyForReflectiveInstantiation(Class<?> c) {
469473

470474
@Override
471475
public void registerReachabilityHandler(Consumer<DuringAnalysisAccess> callback, Object... elements) {
472-
reachabilityHandler.registerReachabilityHandler(this, callback, elements);
476+
/*
477+
* All callback->notification pairs are tracked by the reachabilityNotifications map to
478+
* prevent registering the same callback multiple times. The notifications are also
479+
* tracked by each AnalysisElement, i.e., each trigger, and are removed as soon as they
480+
* are notified.
481+
*/
482+
ElementNotification notification = reachabilityNotifications.computeIfAbsent(callback, ElementNotification::new);
483+
484+
if (notification.isNotified()) {
485+
/* Already notified from an earlier registration, nothing to do. */
486+
return;
487+
}
488+
489+
for (Object trigger : elements) {
490+
AnalysisElement analysisElement = switch (trigger) {
491+
case Class<?> clazz -> getMetaAccess().lookupJavaType(clazz);
492+
case Field field -> getMetaAccess().lookupJavaField(field);
493+
case Executable executable -> getMetaAccess().lookupJavaMethod(executable);
494+
default -> throw UserError.abort("'registerReachabilityHandler' called with an element that is not a Class, Field, or Executable: %s",
495+
trigger.getClass().getTypeName());
496+
};
497+
498+
analysisElement.registerReachabilityNotification(notification);
499+
if (analysisElement.isTriggered()) {
500+
/*
501+
* Element already triggered, just notify the callback. At this point we could
502+
* just notify the callback and bail out, but, for debugging, it may be useful
503+
* to execute the notification for each trigger. Note that although the
504+
* notification can be shared between multiple triggers the notification
505+
* mechanism ensures that the callback itself is only executed once.
506+
*/
507+
analysisElement.notifyReachabilityCallback(getUniverse(), notification);
508+
}
509+
}
473510
}
474511

475512
@Override
476513
public void registerMethodOverrideReachabilityHandler(BiConsumer<DuringAnalysisAccess, Executable> callback, Executable baseMethod) {
477-
reachabilityHandler.registerMethodOverrideReachabilityHandler(this, callback, baseMethod);
514+
AnalysisMethod baseAnalysisMethod = getMetaAccess().lookupJavaMethod(baseMethod);
515+
MethodOverrideReachableNotification notification = new MethodOverrideReachableNotification(callback);
516+
baseAnalysisMethod.registerOverrideReachabilityNotification(notification);
517+
518+
/*
519+
* Notify for already reachable overrides. When a new override becomes reachable all
520+
* installed reachability callbacks in the supertypes declaring the method are
521+
* triggered.
522+
*/
523+
for (AnalysisMethod override : reachableMethodOverrides(baseAnalysisMethod)) {
524+
notification.notifyCallback(getUniverse(), override);
525+
}
478526
}
479527

480528
@Override
481529
public void registerSubtypeReachabilityHandler(BiConsumer<DuringAnalysisAccess, Class<?>> callback, Class<?> baseClass) {
482-
reachabilityHandler.registerSubtypeReachabilityHandler(this, callback, baseClass);
530+
AnalysisType baseType = getMetaAccess().lookupJavaType(baseClass);
531+
SubtypeReachableNotification notification = new SubtypeReachableNotification(callback);
532+
baseType.registerSubtypeReachabilityNotification(notification);
533+
534+
/*
535+
* Notify for already reachable subtypes. When a new type becomes reachable all
536+
* installed reachability callbacks in the supertypes are triggered.
537+
*/
538+
for (AnalysisType subtype : reachableSubtypes(baseType)) {
539+
notification.notifyCallback(getUniverse(), subtype);
540+
}
483541
}
484542

485543
@Override
486544
public void registerClassInitializerReachabilityHandler(Consumer<DuringAnalysisAccess> callback, Class<?> clazz) {
487-
reachabilityHandler.registerClassInitializerReachabilityHandler(this, callback, clazz);
545+
/*
546+
* In our current static analysis implementations, there is no difference between the
547+
* reachability of a class and the reachability of its class initializer.
548+
*/
549+
registerReachabilityHandler(callback, clazz);
488550
}
489551

490552
@Override

substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/ReachabilityHandler.java

Lines changed: 0 additions & 50 deletions
This file was deleted.

0 commit comments

Comments
 (0)