diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_allocator_primary64.h b/compiler-rt/lib/sanitizer_common/sanitizer_allocator_primary64.h index b142ee0131b2bf..952b0697636257 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_allocator_primary64.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_allocator_primary64.h @@ -49,6 +49,11 @@ class MemoryMapper { explicit MemoryMapper(const Allocator &allocator) : allocator_(allocator) {} + ~MemoryMapper() { + if (buffer_) + UnmapOrDie(buffer_, buffer_size_); + } + bool GetAndResetStats(uptr &ranges, uptr &bytes) { ranges = released_ranges_count_; released_ranges_count_ = 0; @@ -57,10 +62,20 @@ class MemoryMapper { return ranges != 0; } - u64 *MapPackedCounterArrayBuffer(uptr count) { - buffer_.clear(); - buffer_.resize(count); - return buffer_.data(); + void *MapPackedCounterArrayBuffer(uptr buffer_size) { + // TODO(alekseyshl): The idea to explore is to check if we have enough + // space between num_freed_chunks*sizeof(CompactPtrT) and + // mapped_free_array to fit buffer_size bytes and use that space instead + // of mapping a temporary one. + if (buffer_size_ < buffer_size) { + if (buffer_) + UnmapOrDie(buffer_, buffer_size_); + buffer_ = MmapOrDieOnFatalError(buffer_size, "ReleaseToOSPageCounters"); + buffer_size_ = buffer_size; + } else { + internal_memset(buffer_, 0, buffer_size); + } + return buffer_; } // Releases [from, to) range of pages back to OS. @@ -77,7 +92,8 @@ class MemoryMapper { const Allocator &allocator_; uptr released_ranges_count_ = 0; uptr released_bytes_ = 0; - InternalMmapVector buffer_; + void *buffer_ = nullptr; + uptr buffer_size_ = 0; }; template @@ -424,8 +440,11 @@ class SizeClassAllocator64 { packing_ratio_log = Log2(packing_ratio); bit_offset_mask = packing_ratio - 1; - buffer = mapper->MapPackedCounterArrayBuffer( - RoundUpTo(n, 1ULL << packing_ratio_log) >> packing_ratio_log); + buffer_size = + (RoundUpTo(n, 1ULL << packing_ratio_log) >> packing_ratio_log) * + sizeof(*buffer); + buffer = reinterpret_cast( + mapper->MapPackedCounterArrayBuffer(buffer_size)); } bool IsAllocated() const { @@ -462,6 +481,8 @@ class SizeClassAllocator64 { u64 counter_mask; u64 packing_ratio_log; u64 bit_offset_mask; + + u64 buffer_size; u64* buffer; }; 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 552387258e1bfe..2e1f59c11def93 100644 --- a/compiler-rt/lib/sanitizer_common/tests/sanitizer_allocator_test.cpp +++ b/compiler-rt/lib/sanitizer_common/tests/sanitizer_allocator_test.cpp @@ -1149,12 +1149,15 @@ TEST(SanitizerCommon, SizeClassAllocator64PopulateFreeListOOM) { class NoMemoryMapper { public: - uptr last_request_buffer_size = 0; + uptr last_request_buffer_size; - u64 *MapPackedCounterArrayBuffer(uptr buffer_size) { - last_request_buffer_size = buffer_size * sizeof(u64); + NoMemoryMapper() : last_request_buffer_size(0) {} + + void *MapPackedCounterArrayBuffer(uptr buffer_size) { + last_request_buffer_size = buffer_size; return nullptr; } + void UnmapPackedCounterArrayBuffer(void *buffer, uptr buffer_size) {} }; class RedZoneMemoryMapper { @@ -1165,17 +1168,19 @@ class RedZoneMemoryMapper { MprotectNoAccess(reinterpret_cast(buffer), page_size); MprotectNoAccess(reinterpret_cast(buffer) + page_size * 2, page_size); } - ~RedZoneMemoryMapper() { UnmapOrDie(buffer, 3 * GetPageSize()); } + ~RedZoneMemoryMapper() { + UnmapOrDie(buffer, 3 * GetPageSize()); + } - u64 *MapPackedCounterArrayBuffer(uptr buffer_size) { - buffer_size *= sizeof(u64); + void *MapPackedCounterArrayBuffer(uptr buffer_size) { const auto page_size = GetPageSize(); CHECK_EQ(buffer_size, page_size); - u64 *p = - reinterpret_cast(reinterpret_cast(buffer) + page_size); + void *p = + reinterpret_cast(reinterpret_cast(buffer) + page_size); memset(p, 0, page_size); return p; } + void UnmapPackedCounterArrayBuffer(void *buffer, uptr buffer_size) {} private: void *buffer;