From 3a713ae5fa64a0b2043bd6748b87d4ba7f7c2fce Mon Sep 17 00:00:00 2001 From: Igor Kudrin Date: Tue, 10 Dec 2019 21:44:17 +0700 Subject: [PATCH] [SanitizerCommon] Reduce wasting memory in LowLevelAllocator. MmapOrDie allocates memory multiple to page size. LowLevelAllocator should use all that memory for the internal buffer because there are chances that subsequent requests may be small enough to fit in that space. Differential Revision: https://reviews.llvm.org/D71275 --- compiler-rt/lib/sanitizer_common/sanitizer_allocator.cpp | 2 +- .../lib/sanitizer_common/tests/sanitizer_allocator_test.cpp | 11 +++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_allocator.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_allocator.cpp index 8d07906..906d4af 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_allocator.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_allocator.cpp @@ -213,7 +213,7 @@ void *LowLevelAllocator::Allocate(uptr size) { // Align allocation size. size = RoundUpTo(size, low_level_alloc_min_alignment); if (allocated_end_ - allocated_current_ < (sptr)size) { - uptr size_to_allocate = Max(size, GetPageSizeCached()); + uptr size_to_allocate = RoundUpTo(size, GetPageSizeCached()); allocated_current_ = (char*)MmapOrDie(size_to_allocate, __func__); allocated_end_ = allocated_current_ + size_to_allocate; diff --git a/compiler-rt/lib/sanitizer_common/tests/sanitizer_allocator_test.cpp b/compiler-rt/lib/sanitizer_common/tests/sanitizer_allocator_test.cpp index 782011b..ff1f7f9 100644 --- a/compiler-rt/lib/sanitizer_common/tests/sanitizer_allocator_test.cpp +++ b/compiler-rt/lib/sanitizer_common/tests/sanitizer_allocator_test.cpp @@ -1404,4 +1404,15 @@ TEST(SanitizerCommon, ThreadedTwoLevelByteMap) { EXPECT_EQ((uptr)TestMapUnmapCallback::unmap_count, m.size1()); } +TEST(SanitizerCommon, LowLevelAllocatorShouldRoundUpSizeOnAlloc) { + // When allocating a memory block slightly bigger than a memory page and + // LowLevelAllocator calls MmapOrDie for the internal buffer, it should round + // the size up to the page size, so that subsequent calls to the allocator + // can use the remaining space in the last allocated page. + static LowLevelAllocator allocator; + char *ptr1 = (char *)allocator.Allocate(GetPageSizeCached() + 16); + char *ptr2 = (char *)allocator.Allocate(16); + EXPECT_EQ(ptr2, ptr1 + GetPageSizeCached() + 16); +} + #endif // #if !SANITIZER_DEBUG -- 2.7.4