[compiler-rt] 746dd6a - [NFC][sanitizer] Add StackDepotTestOnlyUnmap

Vitaly Buka via llvm-commits llvm-commits at lists.llvm.org
Sat Oct 16 13:52:36 PDT 2021


Author: Vitaly Buka
Date: 2021-10-16T13:47:57-07:00
New Revision: 746dd6a700931988dd9021d3d04718f1929885a5

URL: https://github.com/llvm/llvm-project/commit/746dd6a700931988dd9021d3d04718f1929885a5
DIFF: https://github.com/llvm/llvm-project/commit/746dd6a700931988dd9021d3d04718f1929885a5.diff

LOG: [NFC][sanitizer] Add StackDepotTestOnlyUnmap

Added: 
    

Modified: 
    compiler-rt/lib/sanitizer_common/sanitizer_flat_map.h
    compiler-rt/lib/sanitizer_common/sanitizer_persistent_allocator.h
    compiler-rt/lib/sanitizer_common/sanitizer_stackdepot.cpp
    compiler-rt/lib/sanitizer_common/sanitizer_stackdepot.h
    compiler-rt/lib/sanitizer_common/sanitizer_stackdepotbase.h
    compiler-rt/lib/sanitizer_common/tests/sanitizer_stackdepot_test.cpp

Removed: 
    


################################################################################
diff  --git a/compiler-rt/lib/sanitizer_common/sanitizer_flat_map.h b/compiler-rt/lib/sanitizer_common/sanitizer_flat_map.h
index dcd1bfdf8128..a9055e1706ad 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_flat_map.h
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_flat_map.h
@@ -82,6 +82,7 @@ class TwoLevelMap {
       MapUnmapCallback().OnUnmap(reinterpret_cast<uptr>(p), MmapSize());
       UnmapOrDie(p, kSize2);
     }
+    Init();
   }
 
   uptr MemoryUsage() const {

diff  --git a/compiler-rt/lib/sanitizer_common/sanitizer_persistent_allocator.h b/compiler-rt/lib/sanitizer_common/sanitizer_persistent_allocator.h
index be7c34536ff5..e18b0030567f 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_persistent_allocator.h
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_persistent_allocator.h
@@ -26,6 +26,8 @@ class PersistentAllocator {
   T *alloc(uptr count = 1);
   uptr allocated() const { return atomic_load_relaxed(&mapped_size); }
 
+  void TestOnlyUnmap();
+
  private:
   T *tryAlloc(uptr count);
   T *refillAndAlloc(uptr count);
@@ -33,6 +35,13 @@ class PersistentAllocator {
   atomic_uintptr_t region_pos;  // Region allocator for Node's.
   atomic_uintptr_t region_end;
   atomic_uintptr_t mapped_size;
+
+  struct BlockInfo {
+    const BlockInfo *next;
+    uptr ptr;
+    uptr size;
+  };
+  const BlockInfo *curr;
 };
 
 template <typename T>
@@ -68,17 +77,34 @@ inline T *PersistentAllocator<T>::refillAndAlloc(uptr count) {
     if (s)
       return s;
     atomic_store(&region_pos, 0, memory_order_relaxed);
-    uptr size = count * sizeof(T);
-    uptr allocsz = 64 * 1024;
-    if (allocsz < size)
-      allocsz = size;
+    uptr size = count * sizeof(T) + sizeof(BlockInfo);
+    uptr allocsz = RoundUpTo(Max<uptr>(size, 64u * 1024u), GetPageSizeCached());
     uptr mem = (uptr)MmapOrDie(allocsz, "stack depot");
+    BlockInfo *new_block = (BlockInfo *)(mem + allocsz) - 1;
+    new_block->next = curr;
+    new_block->ptr = mem;
+    new_block->size = allocsz;
+    curr = new_block;
+
     atomic_fetch_add(&mapped_size, allocsz, memory_order_relaxed);
+
+    allocsz -= sizeof(BlockInfo);
     atomic_store(&region_end, mem + allocsz, memory_order_release);
     atomic_store(&region_pos, mem, memory_order_release);
   }
 }
 
+template <typename T>
+void PersistentAllocator<T>::TestOnlyUnmap() {
+  while (curr) {
+    uptr mem = curr->ptr;
+    uptr allocsz = curr->size;
+    curr = curr->next;
+    UnmapOrDie((void *)mem, allocsz);
+  }
+  internal_memset(this, 0, sizeof(*this));
+}
+
 } // namespace __sanitizer
 
 #endif // SANITIZER_PERSISTENT_ALLOCATOR_H

diff  --git a/compiler-rt/lib/sanitizer_common/sanitizer_stackdepot.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_stackdepot.cpp
index 7b9bb37f282a..f6a243765082 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_stackdepot.cpp
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_stackdepot.cpp
@@ -36,7 +36,7 @@ struct StackDepotNode {
   bool eq(hash_type hash, const args_type &args) const {
     return hash == stack_hash;
   }
-  static uptr allocated() { return traceAllocator.allocated(); }
+  static uptr allocated();
   static hash_type hash(const args_type &args) {
     MurMur2Hash64Builder H(args.size * sizeof(uptr));
     for (uptr i = 0; i < args.size; i++) H.add(args.trace[i]);
@@ -75,6 +75,10 @@ static StackDepot theDepot;
 static TwoLevelMap<uptr *, StackDepot::kNodesSize1, StackDepot::kNodesSize2>
     tracePtrs;
 
+uptr StackDepotNode::allocated() {
+  return traceAllocator.allocated() + tracePtrs.MemoryUsage();
+}
+
 void StackDepotNode::store(u32 id, const args_type &args, hash_type hash) {
   CHECK_EQ(args.tag & (~kUseCountMask >> kUseCountBits), args.tag);
   atomic_store(&tag_and_use_count, args.tag << kUseCountBits,
@@ -125,4 +129,10 @@ StackDepotHandle StackDepotNode::get_handle(u32 id) {
   return StackDepotHandle(&theDepot.nodes[id], id);
 }
 
+void StackDepotTestOnlyUnmap() {
+  theDepot.TestOnlyUnmap();
+  tracePtrs.TestOnlyUnmap();
+  traceAllocator.TestOnlyUnmap();
+}
+
 } // namespace __sanitizer

diff  --git a/compiler-rt/lib/sanitizer_common/sanitizer_stackdepot.h b/compiler-rt/lib/sanitizer_common/sanitizer_stackdepot.h
index bbfb7f87220c..56d655d9404c 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_stackdepot.h
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_stackdepot.h
@@ -43,6 +43,8 @@ void StackDepotLockAll();
 void StackDepotUnlockAll();
 void StackDepotPrintAll();
 
+void StackDepotTestOnlyUnmap();
+
 } // namespace __sanitizer
 
 #endif // SANITIZER_STACKDEPOT_H

diff  --git a/compiler-rt/lib/sanitizer_common/sanitizer_stackdepotbase.h b/compiler-rt/lib/sanitizer_common/sanitizer_stackdepotbase.h
index d19e54200514..96d1ddc87fd0 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_stackdepotbase.h
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_stackdepotbase.h
@@ -56,6 +56,11 @@ class StackDepotBase {
   void UnlockAll();
   void PrintAll();
 
+  void TestOnlyUnmap() {
+    nodes.TestOnlyUnmap();
+    internal_memset(this, 0, sizeof(*this));
+  }
+
  private:
   friend Node;
   u32 find(u32 s, args_type args, hash_type hash) const;

diff  --git a/compiler-rt/lib/sanitizer_common/tests/sanitizer_stackdepot_test.cpp b/compiler-rt/lib/sanitizer_common/tests/sanitizer_stackdepot_test.cpp
index 113c41eaa1b5..df9cadad9776 100644
--- a/compiler-rt/lib/sanitizer_common/tests/sanitizer_stackdepot_test.cpp
+++ b/compiler-rt/lib/sanitizer_common/tests/sanitizer_stackdepot_test.cpp
@@ -26,10 +26,12 @@ namespace __sanitizer {
 
 class StackDepotTest : public testing::Test {
  protected:
+  void SetUp() override { StackDepotTestOnlyUnmap(); }
   void TearDown() override {
     StackDepotStats stack_depot_stats = StackDepotGetStats();
     Printf("StackDepot: %zd ids; %zdM allocated\n",
            stack_depot_stats.n_uniq_ids, stack_depot_stats.allocated >> 20);
+    StackDepotTestOnlyUnmap();
   }
 };
 
@@ -159,43 +161,37 @@ static std::string PrintStackDepotBenchmarkParams(
 
 class StackDepotBenchmark
     : public StackDepotTest,
-      public testing::WithParamInterface<StackDepotBenchmarkParams> {
- protected:
-  void Run() {
-    auto Param = GetParam();
-    std::atomic<unsigned int> here = {};
-
-    auto thread = [&](int idx) {
-      here++;
-      while (here < Param.UniqueThreads) std::this_thread::yield();
-
-      std::vector<uptr> frames(64);
-      for (int r = 0; r < Param.RepeatPerThread; ++r) {
-        std::iota(frames.begin(), frames.end(), idx + 1);
-        for (int i = 0; i < Param.UniqueStacksPerThread; ++i) {
-          StackTrace s(frames.data(), frames.size());
-          auto h = StackDepotPut_WithHandle(s);
-          if (Param.UseCount)
-            h.inc_use_count_unsafe();
-          std::next_permutation(frames.begin(), frames.end());
-        };
-      }
-    };
-
-    std::vector<std::thread> threads;
-    for (int i = 0; i < Param.Threads; ++i)
-      threads.emplace_back(thread, Param.UniqueThreads * i);
-    for (auto& t : threads) t.join();
-  }
-};
+      public testing::WithParamInterface<StackDepotBenchmarkParams> {};
 
 // Test which can be used as a simple benchmark. It's disabled to avoid slowing
 // down check-sanitizer.
 // Usage: Sanitizer-<ARCH>-Test --gtest_also_run_disabled_tests \
 //   '--gtest_filter=*Benchmark*'
 TEST_P(StackDepotBenchmark, DISABLED_Benchmark) {
-  // Call in subprocess to avoid reuse of the depot.
-  EXPECT_EXIT((Run(), exit(0)), ::testing::ExitedWithCode(0), "");
+  auto Param = GetParam();
+  std::atomic<unsigned int> here = {};
+
+  auto thread = [&](int idx) {
+    here++;
+    while (here < Param.UniqueThreads) std::this_thread::yield();
+
+    std::vector<uptr> frames(64);
+    for (int r = 0; r < Param.RepeatPerThread; ++r) {
+      std::iota(frames.begin(), frames.end(), idx + 1);
+      for (int i = 0; i < Param.UniqueStacksPerThread; ++i) {
+        StackTrace s(frames.data(), frames.size());
+        auto h = StackDepotPut_WithHandle(s);
+        if (Param.UseCount)
+          h.inc_use_count_unsafe();
+        std::next_permutation(frames.begin(), frames.end());
+      };
+    }
+  };
+
+  std::vector<std::thread> threads;
+  for (int i = 0; i < Param.Threads; ++i)
+    threads.emplace_back(thread, Param.UniqueThreads * i);
+  for (auto& t : threads) t.join();
 }
 
 INSTANTIATE_TEST_SUITE_P(StackDepotBenchmarkSuite, StackDepotBenchmark,


        


More information about the llvm-commits mailing list