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

(cherry picked from commit 777cb82)
  • Loading branch information
zakkak committed Dec 18, 2023
1 parent 6e1462f commit c629840
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.InternalFeature;
import com.oracle.svm.core.feature.AutomaticallyRegisteredFeature;
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 implements InternalFeature, ReachabilityHandler {

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 @@ -93,7 +95,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 @@ -125,7 +127,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 c629840

Please sign in to comment.