diff options
| author | Kostya Kortchinsky <kostyak@google.com> | 2019-08-14 16:04:01 +0000 |
|---|---|---|
| committer | Kostya Kortchinsky <kostyak@google.com> | 2019-08-14 16:04:01 +0000 |
| commit | 2be59170d433be05204992838a1aadbc79d5e0d1 (patch) | |
| tree | 774e32e604fd14c092ce248c9bdab32a12c962be | |
| parent | 7fce867856934ae09bfd3d4dac0552249e1d03f2 (diff) | |
| download | bcm5719-llvm-2be59170d433be05204992838a1aadbc79d5e0d1.tar.gz bcm5719-llvm-2be59170d433be05204992838a1aadbc79d5e0d1.zip | |
[scudo][standalone] Add more stats to mallinfo
Summary:
Android requires additional stats in mallinfo. While we can provide
right away the number of bytes mapped (Primary+Secondary), there was
no way to get the number of free bytes (only makes sense for the
Primary since the Secondary unmaps everything on deallocation).
An approximation could be `StatMapped - StatAllocated`, but since we
are mapping in `1<<17` increments for the 64-bit Primary, it's fairly
inaccurate.
So we introduce `StatFree` (note it's `Free`, not `Freed`!), which
keeps track of the amount of Primary blocks currently unallocated.
Reviewers: cferris, eugenis, vitalybuka, hctim, morehouse
Reviewed By: morehouse
Subscribers: delcypher, #sanitizers, llvm-commits
Tags: #llvm, #sanitizers
Differential Revision: https://reviews.llvm.org/D66112
llvm-svn: 368866
| -rw-r--r-- | compiler-rt/lib/scudo/standalone/local_cache.h | 2 | ||||
| -rw-r--r-- | compiler-rt/lib/scudo/standalone/mutex.h | 8 | ||||
| -rw-r--r-- | compiler-rt/lib/scudo/standalone/primary32.h | 2 | ||||
| -rw-r--r-- | compiler-rt/lib/scudo/standalone/primary64.h | 1 | ||||
| -rw-r--r-- | compiler-rt/lib/scudo/standalone/stats.h | 2 | ||||
| -rw-r--r-- | compiler-rt/lib/scudo/standalone/tests/wrappers_c_test.cpp | 18 | ||||
| -rw-r--r-- | compiler-rt/lib/scudo/standalone/wrappers_c.inc | 9 |
7 files changed, 36 insertions, 6 deletions
diff --git a/compiler-rt/lib/scudo/standalone/local_cache.h b/compiler-rt/lib/scudo/standalone/local_cache.h index f1c74cf5b59..b08abd3e5d9 100644 --- a/compiler-rt/lib/scudo/standalone/local_cache.h +++ b/compiler-rt/lib/scudo/standalone/local_cache.h @@ -83,6 +83,7 @@ template <class SizeClassAllocator> struct SizeClassAllocatorLocalCache { // performance. It definitely decreases performance on Android though. // if (!SCUDO_ANDROID) PREFETCH(P); Stats.add(StatAllocated, ClassSize); + Stats.sub(StatFree, ClassSize); return P; } @@ -98,6 +99,7 @@ template <class SizeClassAllocator> struct SizeClassAllocatorLocalCache { const uptr ClassSize = C->ClassSize; C->Chunks[C->Count++] = P; Stats.sub(StatAllocated, ClassSize); + Stats.add(StatFree, ClassSize); } void drain() { diff --git a/compiler-rt/lib/scudo/standalone/mutex.h b/compiler-rt/lib/scudo/standalone/mutex.h index 8cad4195c7c..b26b2df0662 100644 --- a/compiler-rt/lib/scudo/standalone/mutex.h +++ b/compiler-rt/lib/scudo/standalone/mutex.h @@ -27,10 +27,10 @@ public: NOINLINE void lock() { if (LIKELY(tryLock())) return; - // The compiler may try to fully unroll the loop, ending up in a - // NumberOfTries*NumberOfYields block of pauses mixed with tryLocks. This - // is large, ugly and unneeded, a compact loop is better for our purpose - // here. Use a pragma to tell the compiler not to unroll the loop. + // The compiler may try to fully unroll the loop, ending up in a + // NumberOfTries*NumberOfYields block of pauses mixed with tryLocks. This + // is large, ugly and unneeded, a compact loop is better for our purpose + // here. Use a pragma to tell the compiler not to unroll the loop. #ifdef __clang__ #pragma nounroll #endif diff --git a/compiler-rt/lib/scudo/standalone/primary32.h b/compiler-rt/lib/scudo/standalone/primary32.h index 10f921a8d9e..79a11bfc1b8 100644 --- a/compiler-rt/lib/scudo/standalone/primary32.h +++ b/compiler-rt/lib/scudo/standalone/primary32.h @@ -318,6 +318,8 @@ private: } DCHECK(B); DCHECK_GT(B->getCount(), 0); + + C->getStats().add(StatFree, AllocatedUser); Sci->AllocatedUser += AllocatedUser; if (Sci->CanRelease) Sci->ReleaseInfo.LastReleaseAtNs = getMonotonicTime(); diff --git a/compiler-rt/lib/scudo/standalone/primary64.h b/compiler-rt/lib/scudo/standalone/primary64.h index 0149edc899d..fd3709ecb80 100644 --- a/compiler-rt/lib/scudo/standalone/primary64.h +++ b/compiler-rt/lib/scudo/standalone/primary64.h @@ -309,6 +309,7 @@ private: DCHECK(B); DCHECK_GT(B->getCount(), 0); + C->getStats().add(StatFree, AllocatedUser); Region->AllocatedUser += AllocatedUser; Region->Exhausted = false; if (Region->CanRelease) diff --git a/compiler-rt/lib/scudo/standalone/stats.h b/compiler-rt/lib/scudo/standalone/stats.h index 12436756226..16ef5b89b85 100644 --- a/compiler-rt/lib/scudo/standalone/stats.h +++ b/compiler-rt/lib/scudo/standalone/stats.h @@ -17,7 +17,7 @@ namespace scudo { // Memory allocator statistics -enum StatType { StatAllocated, StatMapped, StatCount }; +enum StatType { StatAllocated, StatFree, StatMapped, StatCount }; typedef uptr StatCounters[StatCount]; diff --git a/compiler-rt/lib/scudo/standalone/tests/wrappers_c_test.cpp b/compiler-rt/lib/scudo/standalone/tests/wrappers_c_test.cpp index 4f3c9aea605..5498c165c02 100644 --- a/compiler-rt/lib/scudo/standalone/tests/wrappers_c_test.cpp +++ b/compiler-rt/lib/scudo/standalone/tests/wrappers_c_test.cpp @@ -191,7 +191,7 @@ TEST(ScudoWrappersCTest, Realloc) { #define M_PURGE -101 #endif -TEST(ScudoWrappersCTest, Mallopt) { +TEST(ScudoWrappersCTest, MallOpt) { errno = 0; EXPECT_EQ(mallopt(-1000, 1), 0); // mallopt doesn't set errno. @@ -223,3 +223,19 @@ TEST(ScudoWrappersCTest, OtherAlloc) { EXPECT_EQ(valloc(SIZE_MAX), nullptr); } + +TEST(ScudoWrappersCTest, MallInfo) { + const size_t BypassQuarantineSize = 1024U; + + struct mallinfo MI = mallinfo(); + size_t Allocated = MI.uordblks; + void *P = malloc(BypassQuarantineSize); + EXPECT_NE(P, nullptr); + MI = mallinfo(); + EXPECT_GE(static_cast<size_t>(MI.uordblks), Allocated + BypassQuarantineSize); + EXPECT_GT(static_cast<size_t>(MI.hblkhd), 0U); + size_t Free = MI.fordblks; + free(P); + MI = mallinfo(); + EXPECT_GE(static_cast<size_t>(MI.fordblks), Free + BypassQuarantineSize); +} diff --git a/compiler-rt/lib/scudo/standalone/wrappers_c.inc b/compiler-rt/lib/scudo/standalone/wrappers_c.inc index 2beddc72480..cb2202dcedf 100644 --- a/compiler-rt/lib/scudo/standalone/wrappers_c.inc +++ b/compiler-rt/lib/scudo/standalone/wrappers_c.inc @@ -38,8 +38,17 @@ INTERFACE WEAK struct SCUDO_MALLINFO SCUDO_PREFIX(mallinfo)(void) { struct SCUDO_MALLINFO Info = {}; scudo::StatCounters Stats; SCUDO_ALLOCATOR.getStats(Stats); + // Space allocated in mmapped regions (bytes) + Info.hblkhd = static_cast<__scudo_mallinfo_data_t>(Stats[scudo::StatMapped]); + // Maximum total allocated space (bytes) + Info.usmblks = Info.hblkhd; + // Space in freed fastbin blocks (bytes) + Info.fsmblks = static_cast<__scudo_mallinfo_data_t>(Stats[scudo::StatFree]); + // Total allocated space (bytes) Info.uordblks = static_cast<__scudo_mallinfo_data_t>(Stats[scudo::StatAllocated]); + // Total free space (bytes) + Info.fordblks = Info.fsmblks; return Info; } |

