diff options
author | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2021-03-12 09:13:00 +0100 |
---|---|---|
committer | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2021-03-16 09:58:26 +0000 |
commit | 03561cae90f1d99b5c54b1ef3be69f10e882b25e (patch) | |
tree | cc5f0958e823c044e7ae51cc0117fe51432abe5e /chromium/third_party/blink/renderer/platform/heap/impl/page_memory.h | |
parent | fa98118a45f7e169f8846086dc2c22c49a8ba310 (diff) | |
download | qtwebengine-chromium-03561cae90f1d99b5c54b1ef3be69f10e882b25e.tar.gz |
BASELINE: Update Chromium to 88.0.4324.208
Change-Id: I3ae87d23e4eff4b4a469685658740a213600c667
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
Diffstat (limited to 'chromium/third_party/blink/renderer/platform/heap/impl/page_memory.h')
-rw-r--r-- | chromium/third_party/blink/renderer/platform/heap/impl/page_memory.h | 186 |
1 files changed, 186 insertions, 0 deletions
diff --git a/chromium/third_party/blink/renderer/platform/heap/impl/page_memory.h b/chromium/third_party/blink/renderer/platform/heap/impl/page_memory.h new file mode 100644 index 00000000000..ee13b210d59 --- /dev/null +++ b/chromium/third_party/blink/renderer/platform/heap/impl/page_memory.h @@ -0,0 +1,186 @@ +// Copyright 2015 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. + +#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_PAGE_MEMORY_H_ +#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_PAGE_MEMORY_H_ + +#include "base/atomic_ref_count.h" +#include "base/containers/flat_map.h" +#include "third_party/blink/renderer/platform/heap/heap.h" +#include "third_party/blink/renderer/platform/heap/impl/heap_page.h" +#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h" +#include "third_party/blink/renderer/platform/wtf/assertions.h" + +namespace blink { + +class RegionTree; + +class MemoryRegion { + USING_FAST_MALLOC(MemoryRegion); + + public: + MemoryRegion(Address base, size_t size) : base_(base), size_(size) { + DCHECK_GT(size, 0u); + } + + bool Contains(ConstAddress addr) const { + return base_ <= addr && addr < (base_ + size_); + } + + bool Contains(const MemoryRegion& other) const { + return Contains(other.base_) && Contains(other.base_ + other.size_ - 1); + } + + void Release(); + WARN_UNUSED_RESULT bool Commit(); + void Decommit(); + + Address Base() const { return base_; } + size_t size() const { return size_; } + + private: + Address base_; + size_t size_; +}; + +// A PageMemoryRegion represents a chunk of reserved virtual address +// space containing a number of blink heap pages. On Windows, reserved +// virtual address space can only be given back to the system as a +// whole. The PageMemoryRegion allows us to do that by keeping track +// of the number of pages using it in order to be able to release all +// of the virtual address space when there are no more pages using it. +class PageMemoryRegion : public MemoryRegion { + public: + ~PageMemoryRegion(); + + void PageDeleted(Address); + + void MarkPageUsed(Address page) { + DCHECK(!in_use_[Index(page)]); + in_use_[Index(page)] = true; + } + + void MarkPageUnused(Address page) { in_use_[Index(page)] = false; } + + static PageMemoryRegion* AllocateLargePage(size_t size, + RegionTree* region_tree) { + return Allocate(size, 1, region_tree); + } + + static PageMemoryRegion* AllocateNormalPages(RegionTree* region_tree) { + return Allocate(kBlinkPageSize * kBlinkPagesPerRegion, kBlinkPagesPerRegion, + region_tree); + } + + BasePage* PageFromAddress(ConstAddress address) { + DCHECK(Contains(address)); + if (!in_use_[Index(address)]) + return nullptr; + if (is_large_page_) + return PageFromObject(Base()); + return PageFromObject(address); + } + + private: + PageMemoryRegion(Address base, size_t, unsigned num_pages, RegionTree*); + + unsigned Index(ConstAddress address) const { + DCHECK(Contains(address)); + if (is_large_page_) + return 0; + size_t offset = BlinkPageAddress(const_cast<Address>(address)) - Base(); + DCHECK_EQ(offset % kBlinkPageSize, 0u); + return static_cast<unsigned>(offset / kBlinkPageSize); + } + + static PageMemoryRegion* Allocate(size_t, unsigned num_pages, RegionTree*); + + const bool is_large_page_; + // A thread owns a page, but not a region. Represent the in-use + // bitmap such that thread non-interference comes for free. + bool in_use_[kBlinkPagesPerRegion]; + base::AtomicRefCount num_pages_; + RegionTree* const region_tree_; +}; + +// A RegionTree is a simple binary search tree of PageMemoryRegions sorted +// by base addresses. +class RegionTree { + USING_FAST_MALLOC(RegionTree); + + public: + void Add(PageMemoryRegion*); + void Remove(PageMemoryRegion*); + PageMemoryRegion* Lookup(ConstAddress); + + private: + // Using flat_map allows to improve locality to minimize cache misses and + // balance binary lookup. + base::flat_map<ConstAddress, PageMemoryRegion*> set_; +}; + +// Representation of the memory used for a Blink heap page. +// +// The representation keeps track of two memory regions: +// +// 1. The virtual memory reserved from the system in order to be able +// to free all the virtual memory reserved. Multiple PageMemory +// instances can share the same reserved memory region and +// therefore notify the reserved memory region on destruction so +// that the system memory can be given back when all PageMemory +// instances for that memory are gone. +// +// 2. The writable memory (a sub-region of the reserved virtual +// memory region) that is used for the actual heap page payload. +// +// Guard pages are created before and after the writable memory. +class PageMemory { + USING_FAST_MALLOC(PageMemory); + + public: + ~PageMemory() { + __lsan_unregister_root_region(writable_.Base(), writable_.size()); + reserved_->PageDeleted(WritableStart()); + } + + WARN_UNUSED_RESULT bool Commit() { + reserved_->MarkPageUsed(WritableStart()); + return writable_.Commit(); + } + + void Decommit() { + reserved_->MarkPageUnused(WritableStart()); + writable_.Decommit(); + } + + void MarkUnused() { reserved_->MarkPageUnused(WritableStart()); } + + PageMemoryRegion* Region() { return reserved_; } + + Address WritableStart() { return writable_.Base(); } + + static PageMemory* SetupPageMemoryInRegion(PageMemoryRegion*, + size_t page_offset, + size_t payload_size); + + // Allocate a virtual address space for one blink page with the + // following layout: + // + // [ guard os page | ... payload ... | guard os page ] + // ^---{ aligned to blink page size } + // + // The returned page memory region will be zeroed. + // + static PageMemory* Allocate(size_t payload_size, RegionTree*); + + private: + PageMemory(PageMemoryRegion* reserved, const MemoryRegion& writable); + + PageMemoryRegion* reserved_; + MemoryRegion writable_; +}; + +} // namespace blink + +#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_PAGE_MEMORY_H_ |