[NFC][sanitizer] Atomix relaxed in TwoLevelMap
authorVitaly Buka <vitalybuka@google.com>
Mon, 25 Oct 2021 00:17:39 +0000 (17:17 -0700)
committerVitaly Buka <vitalybuka@google.com>
Sun, 31 Oct 2021 19:18:03 +0000 (12:18 -0700)
This is NOOP in x86_64.
On arch64 it avoids Data Memory Barrier with visible improvements on micro benchmarks.

Reviewed By: dvyukov

Differential Revision: https://reviews.llvm.org/D112391

compiler-rt/lib/sanitizer_common/sanitizer_flat_map.h

index e8c34c1..05fb554 100644 (file)
@@ -129,7 +129,16 @@ class TwoLevelMap {
   }
 
   T *GetOrCreate(uptr idx) const {
-    T *res = Get(idx);
+    DCHECK_LT(idx, kSize1);
+    // This code needs to use memory_order_acquire/consume, but we use
+    // memory_order_relaxed for performance reasons (matters for arm64). We
+    // expect memory_order_relaxed to be effectively equivalent to
+    // memory_order_consume in this case for all relevant architectures: all
+    // dependent data is reachable only by dereferencing the resulting pointer.
+    // If relaxed load fails to see stored ptr, the code will fall back to
+    // Create() and reload the value again with locked mutex as a memory
+    // barrier.
+    T *res = reinterpret_cast<T *>(atomic_load_relaxed(&map1_[idx]));
     if (LIKELY(res))
       return res;
     return Create(idx);