Commit fc637389 authored by Michael Lippautz's avatar Michael Lippautz Committed by V8 LUCI CQ

cppgc: Add mutex to PageBackend

This guards against concurrent usages of PageBackend::Lookup() from
HeapRegistry which can race with adding/removing pages.

This race only manifests in debug mode.

Change-Id: If34dbc255faeda085e522501ff2995693cd97b2e
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3129702
Commit-Queue: Michael Lippautz <mlippautz@chromium.org>
Reviewed-by: 's avatarOmer Katz <omerkatz@chromium.org>
Cr-Commit-Position: refs/heads/main@{#76590}
parent e08e941a
...@@ -193,6 +193,7 @@ PageBackend::PageBackend(PageAllocator& allocator, ...@@ -193,6 +193,7 @@ PageBackend::PageBackend(PageAllocator& allocator,
PageBackend::~PageBackend() = default; PageBackend::~PageBackend() = default;
Address PageBackend::AllocateNormalPageMemory(size_t bucket) { Address PageBackend::AllocateNormalPageMemory(size_t bucket) {
v8::base::MutexGuard guard(&mutex_);
std::pair<NormalPageMemoryRegion*, Address> result = page_pool_.Take(bucket); std::pair<NormalPageMemoryRegion*, Address> result = page_pool_.Take(bucket);
if (!result.first) { if (!result.first) {
auto pmr = auto pmr =
...@@ -203,13 +204,15 @@ Address PageBackend::AllocateNormalPageMemory(size_t bucket) { ...@@ -203,13 +204,15 @@ Address PageBackend::AllocateNormalPageMemory(size_t bucket) {
} }
page_memory_region_tree_.Add(pmr.get()); page_memory_region_tree_.Add(pmr.get());
normal_page_memory_regions_.push_back(std::move(pmr)); normal_page_memory_regions_.push_back(std::move(pmr));
return AllocateNormalPageMemory(bucket); result = page_pool_.Take(bucket);
DCHECK(result.first);
} }
result.first->Allocate(result.second); result.first->Allocate(result.second);
return result.second; return result.second;
} }
void PageBackend::FreeNormalPageMemory(size_t bucket, Address writeable_base) { void PageBackend::FreeNormalPageMemory(size_t bucket, Address writeable_base) {
v8::base::MutexGuard guard(&mutex_);
auto* pmr = static_cast<NormalPageMemoryRegion*>( auto* pmr = static_cast<NormalPageMemoryRegion*>(
page_memory_region_tree_.Lookup(writeable_base)); page_memory_region_tree_.Lookup(writeable_base));
pmr->Free(writeable_base); pmr->Free(writeable_base);
...@@ -217,6 +220,7 @@ void PageBackend::FreeNormalPageMemory(size_t bucket, Address writeable_base) { ...@@ -217,6 +220,7 @@ void PageBackend::FreeNormalPageMemory(size_t bucket, Address writeable_base) {
} }
Address PageBackend::AllocateLargePageMemory(size_t size) { Address PageBackend::AllocateLargePageMemory(size_t size) {
v8::base::MutexGuard guard(&mutex_);
auto pmr = auto pmr =
std::make_unique<LargePageMemoryRegion>(allocator_, oom_handler_, size); std::make_unique<LargePageMemoryRegion>(allocator_, oom_handler_, size);
const PageMemory pm = pmr->GetPageMemory(); const PageMemory pm = pmr->GetPageMemory();
...@@ -227,6 +231,7 @@ Address PageBackend::AllocateLargePageMemory(size_t size) { ...@@ -227,6 +231,7 @@ Address PageBackend::AllocateLargePageMemory(size_t size) {
} }
void PageBackend::FreeLargePageMemory(Address writeable_base) { void PageBackend::FreeLargePageMemory(Address writeable_base) {
v8::base::MutexGuard guard(&mutex_);
PageMemoryRegion* pmr = page_memory_region_tree_.Lookup(writeable_base); PageMemoryRegion* pmr = page_memory_region_tree_.Lookup(writeable_base);
page_memory_region_tree_.Remove(pmr); page_memory_region_tree_.Remove(pmr);
auto size = large_page_memory_regions_.erase(pmr); auto size = large_page_memory_regions_.erase(pmr);
......
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
#include "include/cppgc/platform.h" #include "include/cppgc/platform.h"
#include "src/base/macros.h" #include "src/base/macros.h"
#include "src/base/platform/mutex.h"
#include "src/heap/cppgc/globals.h" #include "src/heap/cppgc/globals.h"
namespace cppgc { namespace cppgc {
...@@ -227,6 +228,8 @@ class V8_EXPORT_PRIVATE PageBackend final { ...@@ -227,6 +228,8 @@ class V8_EXPORT_PRIVATE PageBackend final {
PageBackend& operator=(const PageBackend&) = delete; PageBackend& operator=(const PageBackend&) = delete;
private: private:
// Guards against concurrent uses of `Lookup()`.
mutable v8::base::Mutex mutex_;
PageAllocator& allocator_; PageAllocator& allocator_;
FatalOutOfMemoryHandler& oom_handler_; FatalOutOfMemoryHandler& oom_handler_;
NormalPageMemoryPool page_pool_; NormalPageMemoryPool page_pool_;
...@@ -273,6 +276,7 @@ PageMemoryRegion* PageMemoryRegionTree::Lookup(ConstAddress address) const { ...@@ -273,6 +276,7 @@ PageMemoryRegion* PageMemoryRegionTree::Lookup(ConstAddress address) const {
} }
Address PageBackend::Lookup(ConstAddress address) const { Address PageBackend::Lookup(ConstAddress address) const {
v8::base::MutexGuard guard(&mutex_);
PageMemoryRegion* pmr = page_memory_region_tree_.Lookup(address); PageMemoryRegion* pmr = page_memory_region_tree_.Lookup(address);
return pmr ? pmr->Lookup(address) : nullptr; return pmr ? pmr->Lookup(address) : nullptr;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment