From 1532f8ff924bc4c9bf9dc73fb2b3b123e528a129 Mon Sep 17 00:00:00 2001 From: Shu-yu Guo Date: Mon, 28 Jun 2021 17:05:07 -0700 Subject: [PATCH] [heap] Tie process-wide CodeRange lifetime to any remaining Heaps MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently the process-wide CodeRange, once created, lives until process shutdown. This CL changes it to be alive as long as there is a Heap, when the last Heap is gone it gets destroyed and will be recreated the next time a Heap is created. This behavior is shared with SingleCopyReadOnlyArtifacts. Bug: v8:11929 Cq-Include-Trybots: luci.v8.try:v8_linux64_tsan_rel_ng Change-Id: I8a545926c3a4122991f9682bd3fd90e72697ea5a Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2989103 Reviewed-by: Dominik Inführ Commit-Queue: Shu-yu Guo Cr-Commit-Position: refs/heads/master@{#75522} --- src/heap/code-range.cc | 25 ++++++++++++++++--------- src/heap/code-range.h | 2 +- src/heap/heap.cc | 10 ++-------- 3 files changed, 19 insertions(+), 18 deletions(-) diff --git a/src/heap/code-range.cc b/src/heap/code-range.cc index 738c12710c..b45413e740 100644 --- a/src/heap/code-range.cc +++ b/src/heap/code-range.cc @@ -14,8 +14,11 @@ namespace internal { namespace { -DEFINE_LAZY_LEAKY_OBJECT_GETTER(std::shared_ptr, - GetProcessWideCodeRangeCage) +// Weak pointer holding the process-wide CodeRange, if one has been created. All +// Heaps hold a std::shared_ptr to this, so this is destroyed when no Heaps +// remain. +base::LazyInstance>::type process_wide_code_range_ = + LAZY_INSTANCE_INITIALIZER; DEFINE_LAZY_LEAKY_OBJECT_GETTER(CodeRangeAddressHint, GetCodeRangeAddressHint) @@ -153,19 +156,23 @@ uint8_t* CodeRange::RemapEmbeddedBuiltins(Isolate* isolate, } // static -void CodeRange::InitializeProcessWideCodeRangeOnce( +std::shared_ptr CodeRange::EnsureProcessWideCodeRange( v8::PageAllocator* page_allocator, size_t requested_size) { - *GetProcessWideCodeRangeCage() = std::make_shared(); - if (!GetProcessWideCodeRange()->InitReservation(page_allocator, - requested_size)) { - V8::FatalProcessOutOfMemory( - nullptr, "Failed to reserve virtual memory for CodeRange"); + std::shared_ptr code_range = process_wide_code_range_.Get().lock(); + if (!code_range) { + code_range = std::make_shared(); + if (!code_range->InitReservation(page_allocator, requested_size)) { + V8::FatalProcessOutOfMemory( + nullptr, "Failed to reserve virtual memory for CodeRange"); + } + *process_wide_code_range_.Pointer() = code_range; } + return code_range; } // static std::shared_ptr CodeRange::GetProcessWideCodeRange() { - return *GetProcessWideCodeRangeCage(); + return process_wide_code_range_.Get().lock(); } } // namespace internal diff --git a/src/heap/code-range.h b/src/heap/code-range.h index b1bc6020b5..689d3688d2 100644 --- a/src/heap/code-range.h +++ b/src/heap/code-range.h @@ -120,7 +120,7 @@ class CodeRange final : public VirtualMemoryCage { const uint8_t* embedded_blob_code, size_t embedded_blob_code_size); - static void InitializeProcessWideCodeRangeOnce( + static std::shared_ptr EnsureProcessWideCodeRange( v8::PageAllocator* page_allocator, size_t requested_size); // If InitializeProcessWideCodeRangeOnce has been called, returns the diff --git a/src/heap/heap.cc b/src/heap/heap.cc index c4e5abd477..f94d985f6d 100644 --- a/src/heap/heap.cc +++ b/src/heap/heap.cc @@ -5355,10 +5355,6 @@ HeapObject Heap::AllocateRawWithRetryOrFailSlowPath( FatalProcessOutOfMemory("CALL_AND_RETRY_LAST"); } -namespace { -V8_DECLARE_ONCE(initialize_shared_code_range_once); -} // namespace - void Heap::SetUp() { #ifdef V8_ENABLE_ALLOCATION_TIMEOUT allocation_timeout_ = NextAllocationTimeout(); @@ -5391,10 +5387,8 @@ void Heap::SetUp() { // When sharing a pointer cage among Isolates, also share the // CodeRange. isolate_->page_allocator() is the process-wide pointer // compression cage's PageAllocator. - base::CallOnce(&initialize_shared_code_range_once, - &CodeRange::InitializeProcessWideCodeRangeOnce, - isolate_->page_allocator(), requested_size); - code_range_ = CodeRange::GetProcessWideCodeRange(); + code_range_ = CodeRange::EnsureProcessWideCodeRange( + isolate_->page_allocator(), requested_size); } else { code_range_ = std::make_shared(); if (!code_range_->InitReservation(isolate_->page_allocator(),