diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_addrhashmap.h b/compiler-rt/lib/sanitizer_common/sanitizer_addrhashmap.h --- a/compiler-rt/lib/sanitizer_common/sanitizer_addrhashmap.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_addrhashmap.h @@ -89,6 +89,9 @@ bool create_; }; + typedef void (*ForEachCallback)(const uptr Key, const T &Val, void *Arg); + void ForEach(ForEachCallback Cb, void *Arg); + private: friend class Handle; Bucket *table_; @@ -98,6 +101,35 @@ uptr calcHash(uptr addr); }; +template +void AddrHashMap::ForEach(ForEachCallback Cb, void *Arg) { + for (int n = 0; n < kSize; n++) { + Bucket *bucket = &table_[n]; + + bucket->mtx.ReadLock(); + + for (uptr i = 0; i < kBucketSize; i++) { + Cell *c = &bucket->cells[i]; + uptr addr1 = atomic_load(&c->addr, memory_order_acquire); + if (addr1 != 0) + Cb(addr1, c->val, Arg); + } + + // Iterate over any additional cells. + if (AddBucket *add = + (AddBucket *)atomic_load(&bucket->add, memory_order_relaxed)) { + for (uptr i = 0; i < add->size; i++) { + Cell *c = &add->cells[i]; + uptr addr1 = atomic_load(&c->addr, memory_order_relaxed); + if (addr1 != 0) + Cb(addr1, c->val, Arg); + } + } + + bucket->mtx.ReadUnlock(); + } +} + template AddrHashMap::Handle::Handle(AddrHashMap *map, uptr addr) { map_ = map;