aboutsummaryrefslogtreecommitdiff
path: root/third_party/base/allocator/partition_allocator/partition_page.cc
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/base/allocator/partition_allocator/partition_page.cc')
-rw-r--r--third_party/base/allocator/partition_allocator/partition_page.cc165
1 files changed, 0 insertions, 165 deletions
diff --git a/third_party/base/allocator/partition_allocator/partition_page.cc b/third_party/base/allocator/partition_allocator/partition_page.cc
deleted file mode 100644
index 8b507c31f..000000000
--- a/third_party/base/allocator/partition_allocator/partition_page.cc
+++ /dev/null
@@ -1,165 +0,0 @@
-// Copyright (c) 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "third_party/base/allocator/partition_allocator/partition_page.h"
-
-#include "third_party/base/allocator/partition_allocator/partition_direct_map_extent.h"
-#include "third_party/base/allocator/partition_allocator/partition_root_base.h"
-
-namespace pdfium {
-namespace base {
-namespace internal {
-
-namespace {
-
-ALWAYS_INLINE void PartitionDirectUnmap(PartitionPage* page) {
- PartitionRootBase* root = PartitionRootBase::FromPage(page);
- const PartitionDirectMapExtent* extent =
- PartitionDirectMapExtent::FromPage(page);
- size_t unmap_size = extent->map_size;
-
- // Maintain the doubly-linked list of all direct mappings.
- if (extent->prev_extent) {
- DCHECK(extent->prev_extent->next_extent == extent);
- extent->prev_extent->next_extent = extent->next_extent;
- } else {
- root->direct_map_list = extent->next_extent;
- }
- if (extent->next_extent) {
- DCHECK(extent->next_extent->prev_extent == extent);
- extent->next_extent->prev_extent = extent->prev_extent;
- }
-
- // Add on the size of the trailing guard page and preceeding partition
- // page.
- unmap_size += kPartitionPageSize + kSystemPageSize;
-
- size_t uncommitted_page_size = page->bucket->slot_size + kSystemPageSize;
- root->DecreaseCommittedPages(uncommitted_page_size);
- DCHECK(root->total_size_of_direct_mapped_pages >= uncommitted_page_size);
- root->total_size_of_direct_mapped_pages -= uncommitted_page_size;
-
- DCHECK(!(unmap_size & kPageAllocationGranularityOffsetMask));
-
- char* ptr = reinterpret_cast<char*>(PartitionPage::ToPointer(page));
- // Account for the mapping starting a partition page before the actual
- // allocation address.
- ptr -= kPartitionPageSize;
-
- FreePages(ptr, unmap_size);
-}
-
-ALWAYS_INLINE void PartitionRegisterEmptyPage(PartitionPage* page) {
- DCHECK(page->is_empty());
- PartitionRootBase* root = PartitionRootBase::FromPage(page);
-
- // If the page is already registered as empty, give it another life.
- if (page->empty_cache_index != -1) {
- DCHECK(page->empty_cache_index >= 0);
- DCHECK(static_cast<unsigned>(page->empty_cache_index) < kMaxFreeableSpans);
- DCHECK(root->global_empty_page_ring[page->empty_cache_index] == page);
- root->global_empty_page_ring[page->empty_cache_index] = nullptr;
- }
-
- int16_t current_index = root->global_empty_page_ring_index;
- PartitionPage* page_to_decommit = root->global_empty_page_ring[current_index];
- // The page might well have been re-activated, filled up, etc. before we get
- // around to looking at it here.
- if (page_to_decommit)
- page_to_decommit->DecommitIfPossible(root);
-
- // We put the empty slot span on our global list of "pages that were once
- // empty". thus providing it a bit of breathing room to get re-used before
- // we really free it. This improves performance, particularly on Mac OS X
- // which has subpar memory management performance.
- root->global_empty_page_ring[current_index] = page;
- page->empty_cache_index = current_index;
- ++current_index;
- if (current_index == kMaxFreeableSpans)
- current_index = 0;
- root->global_empty_page_ring_index = current_index;
-}
-
-} // namespace
-
-// static
-PartitionPage PartitionPage::sentinel_page_;
-
-PartitionPage* PartitionPage::get_sentinel_page() {
- return &sentinel_page_;
-}
-
-void PartitionPage::FreeSlowPath() {
- DCHECK(this != get_sentinel_page());
- if (LIKELY(num_allocated_slots == 0)) {
- // Page became fully unused.
- if (UNLIKELY(bucket->is_direct_mapped())) {
- PartitionDirectUnmap(this);
- return;
- }
- // If it's the current active page, change it. We bounce the page to
- // the empty list as a force towards defragmentation.
- if (LIKELY(this == bucket->active_pages_head))
- bucket->SetNewActivePage();
- DCHECK(bucket->active_pages_head != this);
-
- set_raw_size(0);
- DCHECK(!get_raw_size());
-
- PartitionRegisterEmptyPage(this);
- } else {
- DCHECK(!bucket->is_direct_mapped());
- // Ensure that the page is full. That's the only valid case if we
- // arrive here.
- 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(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(!next_page);
- if (LIKELY(bucket->active_pages_head != get_sentinel_page()))
- 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(num_allocated_slots == 0))
- FreeSlowPath();
- }
-}
-
-void PartitionPage::Decommit(PartitionRootBase* root) {
- DCHECK(is_empty());
- DCHECK(!bucket->is_direct_mapped());
- void* addr = PartitionPage::ToPointer(this);
- root->DecommitSystemPages(addr, bucket->get_bytes_per_span());
-
- // We actually leave the decommitted page in the active list. We'll sweep
- // it on to the decommitted page list when we next walk the active page
- // list.
- // Pulling this trick enables us to use a singly-linked page list for all
- // cases, which is critical in keeping the page metadata structure down to
- // 32 bytes in size.
- freelist_head = nullptr;
- num_unprovisioned_slots = 0;
- DCHECK(is_decommitted());
-}
-
-void PartitionPage::DecommitIfPossible(PartitionRootBase* root) {
- DCHECK(empty_cache_index >= 0);
- DCHECK(static_cast<unsigned>(empty_cache_index) < kMaxFreeableSpans);
- DCHECK(this == root->global_empty_page_ring[empty_cache_index]);
- empty_cache_index = -1;
- if (is_empty())
- Decommit(root);
-}
-
-} // namespace internal
-} // namespace base
-} // namespace pdfium