Update PartitionAlloc from Chromium at r721710.
This merges in https://crrev.com/721710 to fix some nits.
Change-Id: I25be3f040b2bb03b321f140630f20ff48fcec31a
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/63311
Commit-Queue: Lei Zhang <thestig@chromium.org>
Reviewed-by: Chris Palmer <palmer@chromium.org>
Reviewed-by: Tom Sepez <tsepez@chromium.org>
diff --git a/third_party/base/allocator/partition_allocator/partition_alloc.cc b/third_party/base/allocator/partition_allocator/partition_alloc.cc
index a6acfc1..19ce17b 100644
--- a/third_party/base/allocator/partition_allocator/partition_alloc.cc
+++ b/third_party/base/allocator/partition_allocator/partition_alloc.cc
@@ -193,19 +193,19 @@
internal::PartitionRootBase::gOomHandlingFunction = oom_handling_function;
}
-void PartitionRoot::Init(size_t num_buckets, size_t max_allocation) {
+void PartitionRoot::Init(size_t bucket_count, size_t maximum_allocation) {
PartitionAllocBaseInit(this);
- this->num_buckets = num_buckets;
- this->max_allocation = max_allocation;
- for (size_t i = 0; i < this->num_buckets; ++i) {
- internal::PartitionBucket* bucket = &this->buckets()[i];
- bucket->Init(i == 0 ? kAllocationGranularity : (i << kBucketShift));
+ num_buckets = bucket_count;
+ max_allocation = maximum_allocation;
+ for (size_t i = 0; i < num_buckets; ++i) {
+ internal::PartitionBucket& bucket = buckets()[i];
+ bucket.Init(i == 0 ? kAllocationGranularity : (i << kBucketShift));
}
}
void PartitionRootGeneric::Init() {
- subtle::SpinLock::Guard guard(this->lock);
+ subtle::SpinLock::Guard guard(lock);
PartitionAllocBaseInit(this);
@@ -223,7 +223,7 @@
order_index_shift = 0;
else
order_index_shift = order - (kGenericNumBucketsPerOrderBits + 1);
- this->order_index_shifts[order] = order_index_shift;
+ order_index_shifts[order] = order_index_shift;
size_t sub_order_index_mask;
if (order == kBitsPerSizeT) {
// This avoids invoking undefined behavior for an excessive shift.
@@ -233,7 +233,7 @@
sub_order_index_mask = ((static_cast<size_t>(1) << order) - 1) >>
(kGenericNumBucketsPerOrderBits + 1);
}
- this->order_sub_index_masks[order] = sub_order_index_mask;
+ order_sub_index_masks[order] = sub_order_index_mask;
}
// Set up the actual usable buckets first.
@@ -246,7 +246,7 @@
size_t current_size = kGenericSmallestBucket;
size_t current_increment =
kGenericSmallestBucket >> kGenericNumBucketsPerOrderBits;
- internal::PartitionBucket* bucket = &this->buckets[0];
+ internal::PartitionBucket* bucket = &buckets[0];
for (i = 0; i < kGenericNumBucketedOrders; ++i) {
for (j = 0; j < kGenericNumBucketsPerOrder; ++j) {
bucket->Init(current_size);
@@ -259,16 +259,16 @@
current_increment <<= 1;
}
DCHECK(current_size == 1 << kGenericMaxBucketedOrder);
- DCHECK(bucket == &this->buckets[0] + kGenericNumBuckets);
+ DCHECK(bucket == &buckets[0] + kGenericNumBuckets);
// Then set up the fast size -> bucket lookup table.
- bucket = &this->buckets[0];
- internal::PartitionBucket** bucket_ptr = &this->bucket_lookups[0];
+ bucket = &buckets[0];
+ internal::PartitionBucket** bucket_ptr = &bucket_lookups[0];
for (order = 0; order <= kBitsPerSizeT; ++order) {
for (j = 0; j < kGenericNumBucketsPerOrder; ++j) {
if (order < kGenericMinBucketedOrder) {
// Use the bucket of the finest granularity for malloc(0) etc.
- *bucket_ptr++ = &this->buckets[0];
+ *bucket_ptr++ = &buckets[0];
} else if (order > kGenericMaxBucketedOrder) {
*bucket_ptr++ = internal::PartitionBucket::get_sentinel_bucket();
} else {
@@ -281,8 +281,8 @@
}
}
}
- DCHECK(bucket == &this->buckets[0] + kGenericNumBuckets);
- DCHECK(bucket_ptr == &this->bucket_lookups[0] +
+ DCHECK(bucket == &buckets[0] + kGenericNumBuckets);
+ DCHECK(bucket_ptr == &bucket_lookups[0] +
((kBitsPerSizeT + 1) * kGenericNumBucketsPerOrder));
// And there's one last bucket lookup that will be hit for e.g. malloc(-1),
// which tries to overflow to a non-existant order.
@@ -620,12 +620,12 @@
}
void PartitionRootGeneric::PurgeMemory(int flags) {
- subtle::SpinLock::Guard guard(this->lock);
+ subtle::SpinLock::Guard guard(lock);
if (flags & PartitionPurgeDecommitEmptyPages)
DecommitEmptyPages();
if (flags & PartitionPurgeDiscardUnusedSystemPages) {
for (size_t i = 0; i < kGenericNumBuckets; ++i) {
- internal::PartitionBucket* bucket = &this->buckets[i];
+ internal::PartitionBucket* bucket = &buckets[i];
if (bucket->slot_size >= kSystemPageSize)
PartitionPurgeBucket(bucket);
}
@@ -717,8 +717,8 @@
PartitionStatsDumper* dumper) {
PartitionMemoryStats stats = {0};
stats.total_mmapped_bytes =
- this->total_size_of_super_pages + this->total_size_of_direct_mapped_pages;
- stats.total_committed_bytes = this->total_size_of_committed_pages;
+ total_size_of_super_pages + total_size_of_direct_mapped_pages;
+ stats.total_committed_bytes = total_size_of_committed_pages;
size_t direct_mapped_allocations_total_size = 0;
@@ -735,10 +735,10 @@
PartitionBucketMemoryStats bucket_stats[kGenericNumBuckets];
size_t num_direct_mapped_allocations = 0;
{
- subtle::SpinLock::Guard guard(this->lock);
+ subtle::SpinLock::Guard guard(lock);
for (size_t i = 0; i < kGenericNumBuckets; ++i) {
- const internal::PartitionBucket* bucket = &this->buckets[i];
+ const internal::PartitionBucket* bucket = &buckets[i];
// Don't report the pseudo buckets that the generic allocator sets up in
// order to preserve a fast size->bucket map (see
// PartitionRootGeneric::Init() for details).
@@ -754,7 +754,7 @@
}
}
- for (internal::PartitionDirectMapExtent *extent = this->direct_map_list;
+ for (internal::PartitionDirectMapExtent* extent = direct_map_list;
extent && num_direct_mapped_allocations < kMaxReportableDirectMaps;
extent = extent->next_extent, ++num_direct_mapped_allocations) {
DCHECK(!extent->next_extent ||
@@ -800,9 +800,9 @@
bool is_light_dump,
PartitionStatsDumper* dumper) {
PartitionMemoryStats stats = {0};
- stats.total_mmapped_bytes = this->total_size_of_super_pages;
- stats.total_committed_bytes = this->total_size_of_committed_pages;
- DCHECK(!this->total_size_of_direct_mapped_pages);
+ stats.total_mmapped_bytes = total_size_of_super_pages;
+ stats.total_committed_bytes = total_size_of_committed_pages;
+ DCHECK(!total_size_of_direct_mapped_pages);
static constexpr size_t kMaxReportableBuckets = 4096 / sizeof(void*);
std::unique_ptr<PartitionBucketMemoryStats[]> memory_stats;
@@ -811,12 +811,12 @@
new PartitionBucketMemoryStats[kMaxReportableBuckets]);
}
- const size_t partition_num_buckets = this->num_buckets;
+ const size_t partition_num_buckets = num_buckets;
DCHECK(partition_num_buckets <= kMaxReportableBuckets);
for (size_t i = 0; i < partition_num_buckets; ++i) {
PartitionBucketMemoryStats bucket_stats = {0};
- PartitionDumpBucketStats(&bucket_stats, &this->buckets()[i]);
+ PartitionDumpBucketStats(&bucket_stats, &buckets()[i]);
if (bucket_stats.is_valid) {
stats.total_resident_bytes += bucket_stats.resident_bytes;
stats.total_active_bytes += bucket_stats.active_bytes;
diff --git a/third_party/base/allocator/partition_allocator/partition_alloc.h b/third_party/base/allocator/partition_allocator/partition_alloc.h
index bd6505c..e3ce36c 100644
--- a/third_party/base/allocator/partition_allocator/partition_alloc.h
+++ b/third_party/base/allocator/partition_allocator/partition_alloc.h
@@ -122,7 +122,7 @@
return reinterpret_cast<const internal::PartitionBucket*>(this + 1);
}
- void Init(size_t num_buckets, size_t max_allocation);
+ void Init(size_t bucket_count, size_t maximum_allocation);
ALWAYS_INLINE void* Alloc(size_t size, const char* type_name);
ALWAYS_INLINE void* AllocFlags(int flags, size_t size, const char* type_name);
@@ -318,11 +318,11 @@
}
size_t requested_size = size;
size = internal::PartitionCookieSizeAdjustAdd(size);
- DCHECK(this->initialized);
+ DCHECK(initialized);
size_t index = size >> kBucketShift;
- DCHECK(index < this->num_buckets);
+ DCHECK(index < num_buckets);
DCHECK(size == index << kBucketShift);
- internal::PartitionBucket* bucket = &this->buckets()[index];
+ internal::PartitionBucket* bucket = &buckets()[index];
result = AllocFromBucket(bucket, flags, size);
if (UNLIKELY(hooks_enabled)) {
PartitionAllocHooks::AllocationObserverHookIfEnabled(result, requested_size,
@@ -447,7 +447,7 @@
#if defined(MEMORY_TOOL_REPLACES_ALLOCATOR)
free(ptr);
#else
- DCHECK(this->initialized);
+ DCHECK(initialized);
if (UNLIKELY(!ptr))
return;
@@ -463,7 +463,7 @@
// TODO(palmer): See if we can afford to make this a CHECK.
DCHECK(IsValidPage(page));
{
- subtle::SpinLock::Guard guard(this->lock);
+ subtle::SpinLock::Guard guard(lock);
page->Free(ptr);
}
#endif
@@ -479,7 +479,7 @@
#if defined(MEMORY_TOOL_REPLACES_ALLOCATOR)
return size;
#else
- DCHECK(this->initialized);
+ DCHECK(initialized);
size = internal::PartitionCookieSizeAdjustAdd(size);
internal::PartitionBucket* bucket = PartitionGenericSizeToBucket(this, size);
if (LIKELY(!bucket->is_direct_mapped())) {
diff --git a/third_party/base/allocator/partition_allocator/partition_bucket.cc b/third_party/base/allocator/partition_allocator/partition_bucket.cc
index 54acfde..7b24c90 100644
--- a/third_party/base/allocator/partition_allocator/partition_bucket.cc
+++ b/third_party/base/allocator/partition_allocator/partition_bucket.cc
@@ -133,23 +133,23 @@
// to using fewer system pages.
double best_waste_ratio = 1.0f;
uint16_t best_pages = 0;
- if (this->slot_size > kMaxSystemPagesPerSlotSpan * kSystemPageSize) {
+ if (slot_size > kMaxSystemPagesPerSlotSpan * kSystemPageSize) {
// TODO(ajwong): Why is there a DCHECK here for this?
// http://crbug.com/776537
- DCHECK(!(this->slot_size % kSystemPageSize));
- best_pages = static_cast<uint16_t>(this->slot_size / kSystemPageSize);
+ DCHECK(!(slot_size % kSystemPageSize));
+ best_pages = static_cast<uint16_t>(slot_size / kSystemPageSize);
// TODO(ajwong): Should this be checking against
// kMaxSystemPagesPerSlotSpan or numeric_limits<uint8_t>::max?
// http://crbug.com/776537
CHECK(best_pages < (1 << 8));
return static_cast<uint8_t>(best_pages);
}
- DCHECK(this->slot_size <= kMaxSystemPagesPerSlotSpan * kSystemPageSize);
+ DCHECK(slot_size <= kMaxSystemPagesPerSlotSpan * kSystemPageSize);
for (uint16_t i = kNumSystemPagesPerPartitionPage - 1;
i <= kMaxSystemPagesPerSlotSpan; ++i) {
size_t page_size = kSystemPageSize * i;
- size_t num_slots = page_size / this->slot_size;
- size_t waste = page_size - (num_slots * this->slot_size);
+ size_t num_slots = page_size / slot_size;
+ size_t waste = page_size - (num_slots * slot_size);
// Leaving a page unfaulted is not free; the page will occupy an empty page
// table entry. Make a simple attempt to account for that.
//
@@ -344,12 +344,12 @@
// We should only get here when _every_ slot is either used or unprovisioned.
// (The third state is "on the freelist". If we have a non-empty freelist, we
// should not get here.)
- DCHECK(num_slots + page->num_allocated_slots == this->get_slots_per_span());
+ DCHECK(num_slots + page->num_allocated_slots == get_slots_per_span());
// Similarly, make explicitly sure that the freelist is empty.
DCHECK(!page->freelist_head);
DCHECK(page->num_allocated_slots >= 0);
- size_t size = this->slot_size;
+ size_t size = slot_size;
char* base = reinterpret_cast<char*>(PartitionPage::ToPointer(page));
char* return_object = base + (size * page->num_allocated_slots);
char* first_freelist_pointer = return_object + size;
@@ -405,7 +405,7 @@
}
bool PartitionBucket::SetNewActivePage() {
- PartitionPage* page = this->active_pages_head;
+ PartitionPage* page = active_pages_head;
if (page == PartitionPage::get_sentinel_page())
return false;
@@ -414,40 +414,40 @@
for (; page; page = next_page) {
next_page = page->next_page;
DCHECK(page->bucket == this);
- DCHECK(page != this->empty_pages_head);
- DCHECK(page != this->decommitted_pages_head);
+ DCHECK(page != empty_pages_head);
+ DCHECK(page != decommitted_pages_head);
if (LIKELY(page->is_active())) {
// This page is usable because it has freelist entries, or has
// unprovisioned slots we can create freelist entries from.
- this->active_pages_head = page;
+ active_pages_head = page;
return true;
}
// Deal with empty and decommitted pages.
if (LIKELY(page->is_empty())) {
- page->next_page = this->empty_pages_head;
- this->empty_pages_head = page;
+ page->next_page = empty_pages_head;
+ empty_pages_head = page;
} else if (LIKELY(page->is_decommitted())) {
- page->next_page = this->decommitted_pages_head;
- this->decommitted_pages_head = page;
+ page->next_page = decommitted_pages_head;
+ decommitted_pages_head = page;
} else {
DCHECK(page->is_full());
// If we get here, we found a full page. Skip over it too, and also
// tag it as full (via a negative value). We need it tagged so that
// free'ing can tell, and move it back into the active page list.
page->num_allocated_slots = -page->num_allocated_slots;
- ++this->num_full_pages;
+ ++num_full_pages;
// num_full_pages is a uint16_t for efficient packing so guard against
// overflow to be safe.
- if (UNLIKELY(!this->num_full_pages))
+ if (UNLIKELY(!num_full_pages))
OnFull();
// Not necessary but might help stop accidents.
page->next_page = nullptr;
}
}
- this->active_pages_head = PartitionPage::get_sentinel_page();
+ active_pages_head = PartitionPage::get_sentinel_page();
return false;
}
@@ -456,7 +456,7 @@
size_t size,
bool* is_already_zeroed) {
// The slow path is called when the freelist is empty.
- DCHECK(!this->active_pages_head->freelist_head);
+ DCHECK(!active_pages_head->freelist_head);
PartitionPage* new_page = nullptr;
*is_already_zeroed = false;
@@ -471,10 +471,10 @@
// false where it sweeps the active page list and may move things into
// the empty or decommitted lists which affects the subsequent conditional.
bool return_null = flags & PartitionAllocReturnNull;
- if (UNLIKELY(this->is_direct_mapped())) {
+ if (UNLIKELY(is_direct_mapped())) {
DCHECK(size > kGenericMaxBucketed);
DCHECK(this == get_sentinel_bucket());
- DCHECK(this->active_pages_head == PartitionPage::get_sentinel_page());
+ DCHECK(active_pages_head == PartitionPage::get_sentinel_page());
if (size > kGenericMaxDirectMapped) {
if (return_null)
return nullptr;
@@ -485,34 +485,33 @@
// Turn off the optimization to see if it helps https://crbug.com/892550.
*is_already_zeroed = true;
#endif
- } else if (LIKELY(this->SetNewActivePage())) {
+ } else if (LIKELY(SetNewActivePage())) {
// First, did we find an active page in the active pages list?
- new_page = this->active_pages_head;
+ new_page = active_pages_head;
DCHECK(new_page->is_active());
- } else if (LIKELY(this->empty_pages_head != nullptr) ||
- LIKELY(this->decommitted_pages_head != nullptr)) {
+ } else if (LIKELY(empty_pages_head != nullptr) ||
+ LIKELY(decommitted_pages_head != nullptr)) {
// Second, look in our lists of empty and decommitted pages.
// Check empty pages first, which are preferred, but beware that an
// empty page might have been decommitted.
- while (LIKELY((new_page = this->empty_pages_head) != nullptr)) {
+ while (LIKELY((new_page = empty_pages_head) != nullptr)) {
DCHECK(new_page->bucket == this);
DCHECK(new_page->is_empty() || new_page->is_decommitted());
- this->empty_pages_head = new_page->next_page;
+ empty_pages_head = new_page->next_page;
// Accept the empty page unless it got decommitted.
if (new_page->freelist_head) {
new_page->next_page = nullptr;
break;
}
DCHECK(new_page->is_decommitted());
- new_page->next_page = this->decommitted_pages_head;
- this->decommitted_pages_head = new_page;
+ new_page->next_page = decommitted_pages_head;
+ decommitted_pages_head = new_page;
}
- if (UNLIKELY(!new_page) &&
- LIKELY(this->decommitted_pages_head != nullptr)) {
- new_page = this->decommitted_pages_head;
+ if (UNLIKELY(!new_page) && LIKELY(decommitted_pages_head != nullptr)) {
+ new_page = decommitted_pages_head;
DCHECK(new_page->bucket == this);
DCHECK(new_page->is_decommitted());
- this->decommitted_pages_head = new_page->next_page;
+ decommitted_pages_head = new_page->next_page;
void* addr = PartitionPage::ToPointer(new_page);
root->RecommitSystemPages(addr, new_page->bucket->get_bytes_per_span());
new_page->Reset();
@@ -523,7 +522,7 @@
DCHECK(new_page);
} else {
// Third. If we get here, we need a brand new page.
- uint16_t num_partition_pages = this->get_pages_per_slot_span();
+ uint16_t num_partition_pages = get_pages_per_slot_span();
void* raw_pages = AllocNewSlotSpan(root, flags, num_partition_pages);
if (LIKELY(raw_pages != nullptr)) {
new_page = PartitionPage::FromPointerNoAlignmentCheck(raw_pages);
@@ -536,7 +535,7 @@
// Bail if we had a memory allocation failure.
if (UNLIKELY(!new_page)) {
- DCHECK(this->active_pages_head == PartitionPage::get_sentinel_page());
+ DCHECK(active_pages_head == PartitionPage::get_sentinel_page());
if (return_null)
return nullptr;
root->OutOfMemory();
diff --git a/third_party/base/allocator/partition_allocator/partition_page.cc b/third_party/base/allocator/partition_allocator/partition_page.cc
index 3f70048..8b507c3 100644
--- a/third_party/base/allocator/partition_allocator/partition_page.cc
+++ b/third_party/base/allocator/partition_allocator/partition_page.cc
@@ -92,7 +92,7 @@
void PartitionPage::FreeSlowPath() {
DCHECK(this != get_sentinel_page());
- if (LIKELY(this->num_allocated_slots == 0)) {
+ if (LIKELY(num_allocated_slots == 0)) {
// Page became fully unused.
if (UNLIKELY(bucket->is_direct_mapped())) {
PartitionDirectUnmap(this);
@@ -112,24 +112,24 @@
DCHECK(!bucket->is_direct_mapped());
// Ensure that the page is full. That's the only valid case if we
// arrive here.
- DCHECK(this->num_allocated_slots < 0);
+ DCHECK(num_allocated_slots < 0);
// A transition of num_allocated_slots from 0 to -1 is not legal, and
// likely indicates a double-free.
- CHECK(this->num_allocated_slots != -1);
- this->num_allocated_slots = -this->num_allocated_slots - 2;
- DCHECK(this->num_allocated_slots == bucket->get_slots_per_span() - 1);
+ CHECK(num_allocated_slots != -1);
+ num_allocated_slots = -num_allocated_slots - 2;
+ DCHECK(num_allocated_slots == bucket->get_slots_per_span() - 1);
// Fully used page became partially used. It must be put back on the
// non-full page list. Also make it the current page to increase the
// chances of it being filled up again. The old current page will be
// the next page.
- DCHECK(!this->next_page);
+ DCHECK(!next_page);
if (LIKELY(bucket->active_pages_head != get_sentinel_page()))
- this->next_page = bucket->active_pages_head;
+ next_page = bucket->active_pages_head;
bucket->active_pages_head = this;
--bucket->num_full_pages;
// Special case: for a partition page with just a single slot, it may
// now be empty and we want to run it through the empty logic.
- if (UNLIKELY(this->num_allocated_slots == 0))
+ if (UNLIKELY(num_allocated_slots == 0))
FreeSlowPath();
}
}
diff --git a/third_party/base/allocator/partition_allocator/partition_page.h b/third_party/base/allocator/partition_allocator/partition_page.h
index a4aa3ac..4bbb76b 100644
--- a/third_party/base/allocator/partition_allocator/partition_page.h
+++ b/third_party/base/allocator/partition_allocator/partition_page.h
@@ -203,7 +203,7 @@
ALWAYS_INLINE void PartitionPage::Free(void* ptr) {
#if DCHECK_IS_ON()
- size_t slot_size = this->bucket->slot_size;
+ size_t slot_size = bucket->slot_size;
const size_t raw_size = get_raw_size();
if (raw_size) {
slot_size = raw_size;
@@ -217,7 +217,7 @@
memset(ptr, kFreedByte, slot_size);
#endif
- DCHECK(this->num_allocated_slots);
+ DCHECK(num_allocated_slots);
// Catches an immediate double free.
CHECK(ptr != freelist_head);
// Look for double free one level deeper in debug.
@@ -227,8 +227,8 @@
static_cast<internal::PartitionFreelistEntry*>(ptr);
entry->next = internal::PartitionFreelistEntry::Encode(freelist_head);
freelist_head = entry;
- --this->num_allocated_slots;
- if (UNLIKELY(this->num_allocated_slots <= 0)) {
+ --num_allocated_slots;
+ if (UNLIKELY(num_allocated_slots <= 0)) {
FreeSlowPath();
} else {
// All single-slot allocations must go through the slow path to
@@ -279,7 +279,7 @@
}
ALWAYS_INLINE void PartitionPage::Reset() {
- DCHECK(this->is_decommitted());
+ DCHECK(is_decommitted());
num_unprovisioned_slots = bucket->get_slots_per_span();
DCHECK(num_unprovisioned_slots);