[compiler-rt] afd170b - [sanitizer] Consolidate some LowLevelAllocators to one

Leonard Chan via llvm-commits llvm-commits at lists.llvm.org
Mon Aug 28 16:13:44 PDT 2023


Author: Leonard Chan
Date: 2023-08-28T23:12:37Z
New Revision: afd170bdd983006b281e7b3d5a2d4571d3e36352

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

LOG: [sanitizer] Consolidate some LowLevelAllocators to one

This removes and replaces usage of a few LowLevelAllocators with a single one
provided by sanitizer_common. Functionally, there should be no difference
between using different allocators vs the same one. This works really well
with D158783 which controls the size of each allocator mmap to significantly
reduce fragmentation.

This doesn't remove them all, mainly the ones used by asan and the flag parser.

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

Added: 
    

Modified: 
    compiler-rt/lib/asan/asan_globals.cpp
    compiler-rt/lib/asan/asan_thread.cpp
    compiler-rt/lib/msan/msan.cpp
    compiler-rt/lib/sanitizer_common/sanitizer_allocator.cpp
    compiler-rt/lib/sanitizer_common/sanitizer_common.h
    compiler-rt/lib/sanitizer_common/sanitizer_flag_parser.cpp
    compiler-rt/lib/sanitizer_common/sanitizer_flag_parser.h
    compiler-rt/lib/sanitizer_common/sanitizer_flags.cpp

Removed: 
    


################################################################################
diff  --git a/compiler-rt/lib/asan/asan_globals.cpp b/compiler-rt/lib/asan/asan_globals.cpp
index 4d391cb2a88549..7a72e91528e073 100644
--- a/compiler-rt/lib/asan/asan_globals.cpp
+++ b/compiler-rt/lib/asan/asan_globals.cpp
@@ -36,7 +36,6 @@ struct ListOfGlobals {
 };
 
 static Mutex mu_for_globals;
-static LowLevelAllocator allocator_for_globals;
 static ListOfGlobals *list_of_all_globals;
 
 static const int kDynamicInitGlobalsInitialCapacity = 512;
@@ -225,13 +224,13 @@ static void RegisterGlobal(const Global *g) {
   }
   if (CanPoisonMemory())
     PoisonRedZones(*g);
-  ListOfGlobals *l = new(allocator_for_globals) ListOfGlobals;
+  ListOfGlobals *l = new (GetGlobalLowLevelAllocator()) ListOfGlobals;
   l->g = g;
   l->next = list_of_all_globals;
   list_of_all_globals = l;
   if (g->has_dynamic_init) {
     if (!dynamic_init_globals) {
-      dynamic_init_globals = new (allocator_for_globals) VectorOfGlobals;
+      dynamic_init_globals = new (GetGlobalLowLevelAllocator()) VectorOfGlobals;
       dynamic_init_globals->reserve(kDynamicInitGlobalsInitialCapacity);
     }
     DynInitGlobal dyn_global = { *g, false };
@@ -367,7 +366,7 @@ void __asan_register_globals(__asan_global *globals, uptr n) {
   Lock lock(&mu_for_globals);
   if (!global_registration_site_vector) {
     global_registration_site_vector =
-        new (allocator_for_globals) GlobalRegistrationSiteVector;
+        new (GetGlobalLowLevelAllocator()) GlobalRegistrationSiteVector;
     global_registration_site_vector->reserve(128);
   }
   GlobalRegistrationSite site = {stack_id, &globals[0], &globals[n - 1]};

diff  --git a/compiler-rt/lib/asan/asan_thread.cpp b/compiler-rt/lib/asan/asan_thread.cpp
index 95aeccd070b551..8798968947e82e 100644
--- a/compiler-rt/lib/asan/asan_thread.cpp
+++ b/compiler-rt/lib/asan/asan_thread.cpp
@@ -44,11 +44,10 @@ static ThreadRegistry *asan_thread_registry;
 static ThreadArgRetval *thread_data;
 
 static Mutex mu_for_thread_context;
-static LowLevelAllocator allocator_for_thread_context;
 
 static ThreadContextBase *GetAsanThreadContext(u32 tid) {
   Lock lock(&mu_for_thread_context);
-  return new (allocator_for_thread_context) AsanThreadContext(tid);
+  return new (GetGlobalLowLevelAllocator()) AsanThreadContext(tid);
 }
 
 static void InitThreads() {

diff  --git a/compiler-rt/lib/msan/msan.cpp b/compiler-rt/lib/msan/msan.cpp
index 987c5560825d93..c4f47dea110432 100644
--- a/compiler-rt/lib/msan/msan.cpp
+++ b/compiler-rt/lib/msan/msan.cpp
@@ -138,8 +138,8 @@ static void RegisterMsanFlags(FlagParser *parser, Flags *f) {
 #include "msan_flags.inc"
 #undef MSAN_FLAG
 
-  FlagHandlerKeepGoing *fh_keep_going =
-      new (FlagParser::Alloc) FlagHandlerKeepGoing(&f->halt_on_error);
+  FlagHandlerKeepGoing *fh_keep_going = new (GetGlobalLowLevelAllocator())
+      FlagHandlerKeepGoing(&f->halt_on_error);
   parser->RegisterHandler("keep_going", fh_keep_going,
                           "deprecated, use halt_on_error");
 }

diff  --git a/compiler-rt/lib/sanitizer_common/sanitizer_allocator.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_allocator.cpp
index 08c14ed2cb6b9d..0513ae36fbc721 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_allocator.cpp
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_allocator.cpp
@@ -143,6 +143,9 @@ constexpr uptr kMinRoundedSize = 65536;
 static uptr low_level_alloc_min_alignment = kLowLevelAllocatorDefaultAlignment;
 static LowLevelAllocateCallback low_level_alloc_callback;
 
+static LowLevelAllocator Alloc;
+LowLevelAllocator &GetGlobalLowLevelAllocator() { return Alloc; }
+
 void *LowLevelAllocator::Allocate(uptr size) {
   // Align allocation size.
   size = RoundUpTo(size, low_level_alloc_min_alignment);

diff  --git a/compiler-rt/lib/sanitizer_common/sanitizer_common.h b/compiler-rt/lib/sanitizer_common/sanitizer_common.h
index e7e4b8cb506db0..eda1ead664de8f 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_common.h
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_common.h
@@ -208,6 +208,11 @@ void ParseUnixMemoryProfile(fill_profile_f cb, uptr *stats, char *smaps,
 // Simple low-level (mmap-based) allocator for internal use. Doesn't have
 // constructor, so all instances of LowLevelAllocator should be
 // linker initialized.
+//
+// NOTE: Users should instead use the singleton provided via
+// `GetGlobalLowLevelAllocator()` rather than create a new one. This way, the
+// number of mmap fragments can be reduced and use the same contiguous mmap
+// provided by this singleton.
 class LowLevelAllocator {
  public:
   // Requires an external lock.
@@ -224,6 +229,8 @@ typedef void (*LowLevelAllocateCallback)(uptr ptr, uptr size);
 // Passing NULL removes the callback.
 void SetLowLevelAllocateCallback(LowLevelAllocateCallback callback);
 
+LowLevelAllocator &GetGlobalLowLevelAllocator();
+
 // IO
 void CatastrophicErrorWrite(const char *buffer, uptr length);
 void RawWrite(const char *buffer);

diff  --git a/compiler-rt/lib/sanitizer_common/sanitizer_flag_parser.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_flag_parser.cpp
index c620da7f220af6..ca37df348580ae 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_flag_parser.cpp
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_flag_parser.cpp
@@ -19,8 +19,6 @@
 
 namespace __sanitizer {
 
-LowLevelAllocator FlagParser::Alloc;
-
 class UnknownFlags {
   static const int kMaxUnknownFlags = 20;
   const char *unknown_flags_[kMaxUnknownFlags];
@@ -49,7 +47,7 @@ void ReportUnrecognizedFlags() {
 
 char *FlagParser::ll_strndup(const char *s, uptr n) {
   uptr len = internal_strnlen(s, n);
-  char *s2 = (char*)Alloc.Allocate(len + 1);
+  char *s2 = (char *)GetGlobalLowLevelAllocator().Allocate(len + 1);
   internal_memcpy(s2, s, len);
   s2[len] = 0;
   return s2;
@@ -185,7 +183,8 @@ void FlagParser::RegisterHandler(const char *name, FlagHandlerBase *handler,
 }
 
 FlagParser::FlagParser() : n_flags_(0), buf_(nullptr), pos_(0) {
-  flags_ = (Flag *)Alloc.Allocate(sizeof(Flag) * kMaxFlags);
+  flags_ =
+      (Flag *)GetGlobalLowLevelAllocator().Allocate(sizeof(Flag) * kMaxFlags);
 }
 
 }  // namespace __sanitizer

diff  --git a/compiler-rt/lib/sanitizer_common/sanitizer_flag_parser.h b/compiler-rt/lib/sanitizer_common/sanitizer_flag_parser.h
index ae49294dde95c9..dccdee4da2bd02 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_flag_parser.h
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_flag_parser.h
@@ -178,8 +178,6 @@ class FlagParser {
   bool ParseFile(const char *path, bool ignore_missing);
   void PrintFlagDescriptions();
 
-  static LowLevelAllocator Alloc;
-
  private:
   void fatal_error(const char *err);
   bool is_space(char c);
@@ -193,7 +191,7 @@ class FlagParser {
 template <typename T>
 static void RegisterFlag(FlagParser *parser, const char *name, const char *desc,
                          T *var) {
-  FlagHandler<T> *fh = new (FlagParser::Alloc) FlagHandler<T>(var);
+  FlagHandler<T> *fh = new (GetGlobalLowLevelAllocator()) FlagHandler<T>(var);
   parser->RegisterHandler(name, fh, desc);
 }
 

diff  --git a/compiler-rt/lib/sanitizer_common/sanitizer_flags.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_flags.cpp
index d52e96a7c381eb..849a122386a413 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_flags.cpp
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_flags.cpp
@@ -108,11 +108,11 @@ class FlagHandlerInclude final : public FlagHandlerBase {
 };
 
 void RegisterIncludeFlags(FlagParser *parser, CommonFlags *cf) {
-  FlagHandlerInclude *fh_include = new (FlagParser::Alloc)
+  FlagHandlerInclude *fh_include = new (GetGlobalLowLevelAllocator())
       FlagHandlerInclude(parser, /*ignore_missing*/ false);
   parser->RegisterHandler("include", fh_include,
                           "read more options from the given file");
-  FlagHandlerInclude *fh_include_if_exists = new (FlagParser::Alloc)
+  FlagHandlerInclude *fh_include_if_exists = new (GetGlobalLowLevelAllocator())
       FlagHandlerInclude(parser, /*ignore_missing*/ true);
   parser->RegisterHandler(
       "include_if_exists", fh_include_if_exists,


        


More information about the llvm-commits mailing list