Skip to content

Commit

Permalink
Use synchronized data structures for reachability handlers registration
Browse files Browse the repository at this point in the history
Prevent data races in reachability handlers registration when using
`-H:-RunReachabilityHandlersConcurrently`.

Closes oracle#5868
  • Loading branch information
zakkak committed Nov 9, 2023
1 parent ebc75fa commit 777cb82
Showing 1 changed file with 6 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.BiConsumer;
import java.util.function.Consumer;

Expand All @@ -44,6 +45,7 @@
import com.oracle.svm.core.SubstrateOptions;
import com.oracle.svm.core.feature.AutomaticallyRegisteredFeature;
import com.oracle.svm.core.feature.InternalFeature;
import com.oracle.svm.core.util.ConcurrentIdentityHashMap;
import com.oracle.svm.core.util.UserError;
import com.oracle.svm.core.util.VMError;
import com.oracle.svm.hosted.FeatureImpl.BeforeAnalysisAccessImpl;
Expand All @@ -52,8 +54,8 @@
@AutomaticallyRegisteredFeature
public class ReachabilityHandlerFeature extends ReachabilityHandler implements InternalFeature {

private final IdentityHashMap<Object, Set<Object>> activeHandlers = new IdentityHashMap<>();
private final IdentityHashMap<Object, Map<Object, Set<Object>>> triggeredHandlers = new IdentityHashMap<>();
private final Map<Object, Set<Object>> activeHandlers = new ConcurrentIdentityHashMap<>();
private final Map<Object, Map<Object, Set<Object>>> triggeredHandlers = new ConcurrentIdentityHashMap<>();

public static ReachabilityHandlerFeature singleton() {
return ImageSingletons.lookup(ReachabilityHandlerFeature.class);
Expand Down Expand Up @@ -88,7 +90,7 @@ private void registerReachabilityHandler(BeforeAnalysisAccess a, Object callback
BeforeAnalysisAccessImpl access = (BeforeAnalysisAccessImpl) a;
AnalysisMetaAccess metaAccess = access.getMetaAccess();

Set<Object> triggerSet = activeHandlers.computeIfAbsent(callback, c -> new HashSet<>());
var triggerSet = activeHandlers.computeIfAbsent(callback, c -> ConcurrentHashMap.newKeySet());

for (Object trigger : triggers) {
if (trigger instanceof Class) {
Expand Down Expand Up @@ -119,7 +121,7 @@ public void duringAnalysis(DuringAnalysisAccess a) {
Set<Object> triggers = activeHandlers.get(callback);
if (callback instanceof Consumer) {
if (isTriggered(access, triggers)) {
triggeredHandlers.put(callback, null);
triggeredHandlers.put(callback, Map.of());
toExactCallback(callback).accept(access);
completedCallbacks.add(callback);
}
Expand Down

0 comments on commit 777cb82

Please sign in to comment.