diff options
Diffstat (limited to 'chromium/base/allocator/partition_allocator/partition_alloc.cc')
-rw-r--r-- | chromium/base/allocator/partition_allocator/partition_alloc.cc | 28 |
1 files changed, 18 insertions, 10 deletions
diff --git a/chromium/base/allocator/partition_allocator/partition_alloc.cc b/chromium/base/allocator/partition_allocator/partition_alloc.cc index 4b6d55fdf35..297a6bbe76e 100644 --- a/chromium/base/allocator/partition_allocator/partition_alloc.cc +++ b/chromium/base/allocator/partition_allocator/partition_alloc.cc @@ -493,14 +493,14 @@ static size_t PartitionPurgePage(internal::PartitionPage* page, bool discard) { size_t slot_index = (reinterpret_cast<char*>(entry) - ptr) / slot_size; DCHECK(slot_index < num_slots); slot_usage[slot_index] = 0; - entry = internal::PartitionFreelistEntry::Transform(entry->next); + entry = internal::EncodedPartitionFreelistEntry::Decode(entry->next); #if !defined(OS_WIN) // If we have a slot where the masked freelist entry is 0, we can actually // discard that freelist entry because touching a discarded page is // guaranteed to return original content or 0. (Note that this optimization // won't fire on big-endian machines because the masking function is // negation.) - if (!internal::PartitionFreelistEntry::Transform(entry)) + if (!internal::PartitionFreelistEntry::Encode(entry)) last_slot = slot_index; #endif } @@ -534,25 +534,33 @@ static size_t PartitionPurgePage(internal::PartitionPage* page, bool discard) { DCHECK(truncated_slots > 0); size_t num_new_entries = 0; page->num_unprovisioned_slots += static_cast<uint16_t>(truncated_slots); + // Rewrite the freelist. - internal::PartitionFreelistEntry** entry_ptr = &page->freelist_head; + internal::PartitionFreelistEntry* head = nullptr; + internal::PartitionFreelistEntry* back = head; for (size_t slot_index = 0; slot_index < num_slots; ++slot_index) { if (slot_usage[slot_index]) continue; + auto* entry = reinterpret_cast<internal::PartitionFreelistEntry*>( ptr + (slot_size * slot_index)); - *entry_ptr = internal::PartitionFreelistEntry::Transform(entry); - entry_ptr = reinterpret_cast<internal::PartitionFreelistEntry**>(entry); + if (!head) { + head = entry; + back = entry; + } else { + back->next = internal::PartitionFreelistEntry::Encode(entry); + back = entry; + } num_new_entries++; #if !defined(OS_WIN) last_slot = slot_index; #endif } - // Terminate the freelist chain. - *entry_ptr = nullptr; - // The freelist head is stored unmasked. - page->freelist_head = - internal::PartitionFreelistEntry::Transform(page->freelist_head); + + page->freelist_head = head; + if (back) + back->next = internal::PartitionFreelistEntry::Encode(nullptr); + DCHECK(num_new_entries == num_slots - page->num_allocated_slots); // Discard the memory. DiscardSystemPages(begin_ptr, unprovisioned_bytes); |