summaryrefslogtreecommitdiffstats
path: root/chromium/base/allocator/partition_allocator/partition_alloc.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/base/allocator/partition_allocator/partition_alloc.cc')
-rw-r--r--chromium/base/allocator/partition_allocator/partition_alloc.cc28
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);