[compiler-rt] r204148 - tsan: addrhashmap: fix bug with initialization of addresses in add array

Dmitry Vyukov dvyukov at google.com
Tue Mar 18 05:52:11 PDT 2014


Author: dvyukov
Date: Tue Mar 18 07:52:11 2014
New Revision: 204148

URL: http://llvm.org/viewvc/llvm-project?rev=204148&view=rev
Log:
tsan: addrhashmap: fix bug with initialization of addresses in add array


Modified:
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_addrhashmap.h

Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_addrhashmap.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_addrhashmap.h?rev=204148&r1=204147&r2=204148&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_addrhashmap.h (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_addrhashmap.h Tue Mar 18 07:52:11 2014
@@ -229,6 +229,7 @@ void AddrHashMap<T, kSize>::acquire(Hand
     // Allocate a new add array.
     const uptr kInitSize = 64;
     add = (AddBucket*)InternalAlloc(kInitSize);
+    internal_memset(add, 0, kInitSize);
     add->cap = (kInitSize - sizeof(*add)) / sizeof(add->cells[0]) + 1;
     add->size = 0;
     atomic_store(&b->add, (uptr)add, memory_order_relaxed);
@@ -237,7 +238,8 @@ void AddrHashMap<T, kSize>::acquire(Hand
     // Grow existing add array.
     uptr oldsize = sizeof(*add) + (add->cap - 1) * sizeof(add->cells[0]);
     uptr newsize = oldsize * 2;
-    AddBucket *add1 = (AddBucket*)InternalAlloc(oldsize * 2);
+    AddBucket *add1 = (AddBucket*)InternalAlloc(newsize);
+    internal_memset(add1, 0, newsize);
     add1->cap = (newsize - sizeof(*add)) / sizeof(add->cells[0]) + 1;
     add1->size = add->size;
     internal_memcpy(add1->cells, add->cells, add->size * sizeof(add->cells[0]));
@@ -248,6 +250,7 @@ void AddrHashMap<T, kSize>::acquire(Hand
   // Store.
   uptr i = add->size++;
   Cell *c = &add->cells[i];
+  CHECK_EQ(atomic_load(&c->addr, memory_order_relaxed), 0);
   h->addidx_ = i;
   h->cell_ = c;
 }
@@ -274,18 +277,22 @@ void AddrHashMap<T, kSize>::release(Hand
     AddBucket *add = (AddBucket*)atomic_load(&b->add, memory_order_relaxed);
     if (h->addidx_ == -1U) {
       // Removed from embed array, move an add element into the freed cell.
-      if (add) {
+      if (add && add->size != 0) {
         uptr last = --add->size;
         Cell *c1 = &add->cells[last];
         c->val = c1->val;
         uptr addr1 = atomic_load(&c1->addr, memory_order_relaxed);
         atomic_store(&c->addr, addr1, memory_order_release);
+        atomic_store(&c1->addr, 0, memory_order_release);
       }
     } else {
       // Removed from add array, compact it.
       uptr last = --add->size;
       Cell *c1 = &add->cells[last];
-      *c = *c1;
+      if (c != c1) {
+        *c = *c1;
+        atomic_store(&c1->addr, 0, memory_order_relaxed);
+      }
     }
     if (add && add->size == 0) {
       // FIXME(dvyukov): free add?





More information about the llvm-commits mailing list