From e6190e359c94da4978e945798e7b1a723f7ac8ad Mon Sep 17 00:00:00 2001
From: Foivos Zakkak <fzakkak@redhat.com>
Date: Tue, 7 Nov 2023 11:13:31 +0200
Subject: [PATCH] Use synchronized data structures for reachability handlers
 registration

Prevent data races in reachability handlers registration when using
`-H:-RunReachabilityHandlersConcurrently`.

Closes https://github.com/oracle/graal/issues/5868
---
 .../com/oracle/svm/hosted/ReachabilityHandlerFeature.java | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/ReachabilityHandlerFeature.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/ReachabilityHandlerFeature.java
index 21a5ee6371918..7ad1d65a80217 100644
--- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/ReachabilityHandlerFeature.java
+++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/ReachabilityHandlerFeature.java
@@ -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;
 
@@ -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;
@@ -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 ConcurrentIdentityHashMap<Object, Set<Object>> activeHandlers = new ConcurrentIdentityHashMap<>();
+    private final ConcurrentIdentityHashMap<Object, Map<Object, Set<Object>>> triggeredHandlers = new ConcurrentIdentityHashMap<>();
 
     public static ReachabilityHandlerFeature singleton() {
         return ImageSingletons.lookup(ReachabilityHandlerFeature.class);
@@ -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<>());
+        Set<Object> triggerSet = activeHandlers.computeIfAbsent(callback, c -> ConcurrentHashMap.newKeySet());
 
         for (Object trigger : triggers) {
             if (trigger instanceof Class) {