diff options
Diffstat (limited to 'chromium/base/allocator/partition_allocator/partition_page.h')
-rw-r--r-- | chromium/base/allocator/partition_allocator/partition_page.h | 35 |
1 files changed, 30 insertions, 5 deletions
diff --git a/chromium/base/allocator/partition_allocator/partition_page.h b/chromium/base/allocator/partition_allocator/partition_page.h index 5a0e70f9711..d2e580bdda8 100644 --- a/chromium/base/allocator/partition_allocator/partition_page.h +++ b/chromium/base/allocator/partition_allocator/partition_page.h @@ -11,8 +11,27 @@ #include "base/allocator/partition_allocator/partition_bucket.h" #include "base/allocator/partition_allocator/partition_cookie.h" #include "base/allocator/partition_allocator/partition_freelist_entry.h" +#include "base/allocator/partition_allocator/random.h" #include "base/logging.h" +namespace { + +// Returns true if we've hit the end of a random-length period. We don't want to +// invoke `RandomValue` too often, because we call this function in a hot spot +// (`Free`), and `RandomValue` incurs the cost of atomics. +#if !DCHECK_IS_ON() +bool RandomPeriod() { + static thread_local uint8_t counter = 0; + if (UNLIKELY(counter == 0)) { + counter = base::RandomValue(); + } + counter--; + return counter == 0; +} +#endif + +} // namespace + namespace base { namespace internal { @@ -201,29 +220,35 @@ ALWAYS_INLINE size_t PartitionPage::get_raw_size() const { } ALWAYS_INLINE void PartitionPage::Free(void* ptr) { -#if DCHECK_IS_ON() size_t slot_size = this->bucket->slot_size; const size_t raw_size = get_raw_size(); if (raw_size) { slot_size = raw_size; } +#if DCHECK_IS_ON() // If these asserts fire, you probably corrupted memory. PartitionCookieCheckValue(ptr); PartitionCookieCheckValue(reinterpret_cast<char*>(ptr) + slot_size - kCookieSize); memset(ptr, kFreedByte, slot_size); +#else + // `memset` only once in a while. + if (UNLIKELY(RandomPeriod())) { + memset(ptr, kFreedByte, slot_size); + } #endif DCHECK(this->num_allocated_slots); - CHECK(ptr != freelist_head); // Catches an immediate double free. + // Catches an immediate double free. + CHECK(ptr != freelist_head); // Look for double free one level deeper in debug. - DCHECK(!freelist_head || ptr != internal::PartitionFreelistEntry::Transform( - freelist_head->next)); + DCHECK(!freelist_head || + ptr != EncodedPartitionFreelistEntry::Decode(freelist_head->next)); internal::PartitionFreelistEntry* entry = static_cast<internal::PartitionFreelistEntry*>(ptr); - entry->next = internal::PartitionFreelistEntry::Transform(freelist_head); + entry->next = internal::PartitionFreelistEntry::Encode(freelist_head); freelist_head = entry; --this->num_allocated_slots; if (UNLIKELY(this->num_allocated_slots <= 0)) { |