diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_allocator.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_allocator.cpp --- a/compiler-rt/lib/sanitizer_common/sanitizer_allocator.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_allocator.cpp @@ -213,7 +213,7 @@ // 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 --- 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 @@ 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