[compiler-rt] 7ce67d3 - [scudo][tests] Store the allocator instance in a global rather than posix_memalign it
Leonard Chan via llvm-commits
llvm-commits at lists.llvm.org
Thu Aug 31 15:27:33 PDT 2023
Author: Leonard Chan
Date: 2023-08-31T22:27:14Z
New Revision: 7ce67d33107fd86b7fac985a593e14298944a3a8
URL: https://github.com/llvm/llvm-project/commit/7ce67d33107fd86b7fac985a593e14298944a3a8
DIFF: https://github.com/llvm/llvm-project/commit/7ce67d33107fd86b7fac985a593e14298944a3a8.diff
LOG: [scudo][tests] Store the allocator instance in a global rather than posix_memalign it
The combined scudo allocator object is over 4MB in size which gets created via
the posix_memalign on every test run. If the tests are sanitized with asan,
then the asan allocator will need to mmap this large object every single time a
test is run. Depending on where this is mapped, we might not be able to find a
large enough contiguous space for scudo's primary allocator to reserve an arena.
Such a case is more likely to occur on 39-bit vma for RISCV where the arena size
is roughly a quarter of the whole address space and fragmentation can be a big issue.
This helps reduce fragmentation by instead placing the allocator instance in a
global storage rather than doing an anonymous mmap.
Differential Revision: https://reviews.llvm.org/D158767
Added:
Modified:
compiler-rt/lib/scudo/standalone/tests/combined_test.cpp
Removed:
################################################################################
diff --git a/compiler-rt/lib/scudo/standalone/tests/combined_test.cpp b/compiler-rt/lib/scudo/standalone/tests/combined_test.cpp
index 6d381eab645115..fc118fcadc6b6c 100644
--- a/compiler-rt/lib/scudo/standalone/tests/combined_test.cpp
+++ b/compiler-rt/lib/scudo/standalone/tests/combined_test.cpp
@@ -78,14 +78,72 @@ template <typename Config> struct TestAllocator : scudo::Allocator<Config> {
}
~TestAllocator() { this->unmapTestOnly(); }
- void *operator new(size_t size) {
+ void *operator new(size_t size);
+ void operator delete(void *ptr);
+};
+
+constexpr size_t kMaxAlign = std::max({
+ alignof(scudo::Allocator<scudo::DefaultConfig>),
+#if SCUDO_CAN_USE_PRIMARY64
+ alignof(scudo::Allocator<scudo::FuchsiaConfig>),
+#endif
+ alignof(scudo::Allocator<scudo::AndroidSvelteConfig>),
+ alignof(scudo::Allocator<scudo::AndroidConfig>)
+});
+
+#if SCUDO_RISCV64
+// The allocator is over 4MB large. Rather than creating an instance of this on
+// the heap, keep it in a global storage to reduce fragmentation from having to
+// mmap this at the start of every test.
+struct TestAllocatorStorage {
+ static constexpr size_t kMaxSize = std::max({
+ sizeof(scudo::Allocator<scudo::DefaultConfig>),
+#if SCUDO_CAN_USE_PRIMARY64
+ sizeof(scudo::Allocator<scudo::FuchsiaConfig>),
+#endif
+ sizeof(scudo::Allocator<scudo::AndroidSvelteConfig>),
+ sizeof(scudo::Allocator<scudo::AndroidConfig>)
+ });
+
+ // To alleviate some problem, let's skip the thread safety analysis here.
+ static void *get(size_t size) NO_THREAD_SAFETY_ANALYSIS {
+ assert(size <= kMaxSize &&
+ "Allocation size doesn't fit in the allocator storage");
+ M.lock();
+ return AllocatorStorage;
+ }
+
+ static void release(void *ptr) NO_THREAD_SAFETY_ANALYSIS {
+ M.assertHeld();
+ M.unlock();
+ ASSERT_EQ(ptr, AllocatorStorage);
+ }
+
+ static scudo::HybridMutex M;
+ static uint8_t AllocatorStorage[kMaxSize];
+};
+scudo::HybridMutex TestAllocatorStorage::M;
+alignas(kMaxAlign) uint8_t TestAllocatorStorage::AllocatorStorage[kMaxSize];
+#else
+struct TestAllocatorStorage {
+ static void *get(size_t size) NO_THREAD_SAFETY_ANALYSIS {
void *p = nullptr;
- EXPECT_EQ(0, posix_memalign(&p, alignof(TestAllocator), size));
+ EXPECT_EQ(0, posix_memalign(&p, kMaxAlign, size));
return p;
}
-
- void operator delete(void *ptr) { free(ptr); }
+ static void release(void *ptr) NO_THREAD_SAFETY_ANALYSIS { free(ptr); }
};
+#endif
+
+template <typename Config>
+void *TestAllocator<Config>::operator new(size_t size) {
+ return TestAllocatorStorage::get(size);
+}
+
+template <typename Config>
+void TestAllocator<Config>::operator delete(void *ptr) {
+ TestAllocatorStorage::release(ptr);
+}
template <class TypeParam> struct ScudoCombinedTest : public Test {
ScudoCombinedTest() {
More information about the llvm-commits
mailing list