summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKostya Kortchinsky <kostyak@google.com>2019-08-14 16:04:01 +0000
committerKostya Kortchinsky <kostyak@google.com>2019-08-14 16:04:01 +0000
commit2be59170d433be05204992838a1aadbc79d5e0d1 (patch)
tree774e32e604fd14c092ce248c9bdab32a12c962be
parent7fce867856934ae09bfd3d4dac0552249e1d03f2 (diff)
downloadbcm5719-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.h2
-rw-r--r--compiler-rt/lib/scudo/standalone/mutex.h8
-rw-r--r--compiler-rt/lib/scudo/standalone/primary32.h2
-rw-r--r--compiler-rt/lib/scudo/standalone/primary64.h1
-rw-r--r--compiler-rt/lib/scudo/standalone/stats.h2
-rw-r--r--compiler-rt/lib/scudo/standalone/tests/wrappers_c_test.cpp18
-rw-r--r--compiler-rt/lib/scudo/standalone/wrappers_c.inc9
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;
}
OpenPOWER on IntegriCloud