Commit 143ad476 authored by Dominik Inführ's avatar Dominik Inführ Committed by Commit Bot

[heap] Move list of local heaps to safepoint

Track list of all local heaps in the Safepoint class instead of the
Heap.

Bug: v8:10315
Change-Id: I1a1c847502ab5e8f368d4cc12d3cbaf3672af7cc
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2106197Reviewed-by: 's avatarUlan Degenbaev <ulan@chromium.org>
Commit-Queue: Dominik Inführ <dinfuehr@chromium.org>
Cr-Commit-Position: refs/heads/master@{#66745}
parent 7c2ae383
...@@ -202,7 +202,6 @@ Heap::Heap() ...@@ -202,7 +202,6 @@ Heap::Heap()
: isolate_(isolate()), : isolate_(isolate()),
memory_pressure_level_(MemoryPressureLevel::kNone), memory_pressure_level_(MemoryPressureLevel::kNone),
global_pretenuring_feedback_(kInitialFeedbackCapacity), global_pretenuring_feedback_(kInitialFeedbackCapacity),
local_heaps_head_(nullptr),
safepoint_(new Safepoint(this)), safepoint_(new Safepoint(this)),
external_string_table_(this) { external_string_table_(this) {
// Ensure old_generation_size_ is a multiple of kPageSize. // Ensure old_generation_size_ is a multiple of kPageSize.
...@@ -3878,40 +3877,6 @@ void Heap::AppendArrayBufferExtension(JSArrayBuffer object, ...@@ -3878,40 +3877,6 @@ void Heap::AppendArrayBufferExtension(JSArrayBuffer object,
array_buffer_sweeper_->Append(object, extension); array_buffer_sweeper_->Append(object, extension);
} }
void Heap::AddLocalHeap(LocalHeap* local_heap) {
base::MutexGuard guard(&local_heaps_mutex_);
if (local_heaps_head_) local_heaps_head_->prev_ = local_heap;
local_heap->prev_ = nullptr;
local_heap->next_ = local_heaps_head_;
local_heaps_head_ = local_heap;
}
void Heap::RemoveLocalHeap(LocalHeap* local_heap) {
base::MutexGuard guard(&local_heaps_mutex_);
if (local_heap->next_) local_heap->next_->prev_ = local_heap->prev_;
if (local_heap->prev_)
local_heap->prev_->next_ = local_heap->next_;
else
local_heaps_head_ = local_heap->next_;
}
bool Heap::ContainsLocalHeap(LocalHeap* local_heap) {
base::MutexGuard guard(&local_heaps_mutex_);
LocalHeap* current = local_heaps_head_;
while (current) {
if (current == local_heap) return true;
current = current->next_;
}
return false;
}
bool Heap::ContainsAnyLocalHeap() {
base::MutexGuard guard(&local_heaps_mutex_);
return local_heaps_head_ != nullptr;
}
void Heap::AutomaticallyRestoreInitialHeapLimit(double threshold_percent) { void Heap::AutomaticallyRestoreInitialHeapLimit(double threshold_percent) {
initial_max_old_generation_size_threshold_ = initial_max_old_generation_size_threshold_ =
initial_max_old_generation_size_ * threshold_percent; initial_max_old_generation_size_ * threshold_percent;
......
...@@ -620,11 +620,6 @@ class Heap { ...@@ -620,11 +620,6 @@ class Heap {
void AppendArrayBufferExtension(JSArrayBuffer object, void AppendArrayBufferExtension(JSArrayBuffer object,
ArrayBufferExtension* extension); ArrayBufferExtension* extension);
void AddLocalHeap(LocalHeap* local_heap);
void RemoveLocalHeap(LocalHeap* local_heap);
V8_EXPORT_PRIVATE bool ContainsLocalHeap(LocalHeap* local_heap);
V8_EXPORT_PRIVATE bool ContainsAnyLocalHeap();
Safepoint* safepoint() { return safepoint_.get(); } Safepoint* safepoint() { return safepoint_.get(); }
V8_EXPORT_PRIVATE double MonotonicallyIncreasingTimeInMs(); V8_EXPORT_PRIVATE double MonotonicallyIncreasingTimeInMs();
...@@ -2171,9 +2166,6 @@ class Heap { ...@@ -2171,9 +2166,6 @@ class Heap {
GCCallbackFlags current_gc_callback_flags_ = GCCallbackFlags current_gc_callback_flags_ =
GCCallbackFlags::kNoGCCallbackFlags; GCCallbackFlags::kNoGCCallbackFlags;
base::Mutex local_heaps_mutex_;
LocalHeap* local_heaps_head_;
std::unique_ptr<Safepoint> safepoint_; std::unique_ptr<Safepoint> safepoint_;
bool is_current_gc_forced_ = false; bool is_current_gc_forced_ = false;
...@@ -2243,7 +2235,6 @@ class Heap { ...@@ -2243,7 +2235,6 @@ class Heap {
friend class Page; friend class Page;
friend class PagedSpace; friend class PagedSpace;
friend class ReadOnlyRoots; friend class ReadOnlyRoots;
friend class Safepoint;
friend class Scavenger; friend class Scavenger;
friend class ScavengerCollector; friend class ScavengerCollector;
friend class Space; friend class Space;
......
...@@ -15,14 +15,14 @@ LocalHeap::LocalHeap(Heap* heap) ...@@ -15,14 +15,14 @@ LocalHeap::LocalHeap(Heap* heap)
safepoint_requested_(false), safepoint_requested_(false),
prev_(nullptr), prev_(nullptr),
next_(nullptr) { next_(nullptr) {
heap_->AddLocalHeap(this); heap_->safepoint()->AddLocalHeap(this);
} }
LocalHeap::~LocalHeap() { LocalHeap::~LocalHeap() {
// Park thread since removing the local heap could block. // Park thread since removing the local heap could block.
EnsureParkedBeforeDestruction(); EnsureParkedBeforeDestruction();
heap_->RemoveLocalHeap(this); heap_->safepoint()->RemoveLocalHeap(this);
} }
void LocalHeap::Park() { void LocalHeap::Park() {
......
...@@ -9,19 +9,19 @@ ...@@ -9,19 +9,19 @@
namespace v8 { namespace v8 {
namespace internal { namespace internal {
Safepoint::Safepoint(Heap* heap) : heap_(heap) {} Safepoint::Safepoint(Heap* heap) : heap_(heap), local_heaps_head_(nullptr) {}
void Safepoint::StopThreads() { void Safepoint::StopThreads() {
heap_->local_heaps_mutex_.Lock(); local_heaps_mutex_.Lock();
barrier_.Arm(); barrier_.Arm();
for (LocalHeap* current = heap_->local_heaps_head_; current; for (LocalHeap* current = local_heaps_head_; current;
current = current->next_) { current = current->next_) {
current->RequestSafepoint(); current->RequestSafepoint();
} }
for (LocalHeap* current = heap_->local_heaps_head_; current; for (LocalHeap* current = local_heaps_head_; current;
current = current->next_) { current = current->next_) {
current->state_mutex_.Lock(); current->state_mutex_.Lock();
...@@ -32,14 +32,14 @@ void Safepoint::StopThreads() { ...@@ -32,14 +32,14 @@ void Safepoint::StopThreads() {
} }
void Safepoint::ResumeThreads() { void Safepoint::ResumeThreads() {
for (LocalHeap* current = heap_->local_heaps_head_; current; for (LocalHeap* current = local_heaps_head_; current;
current = current->next_) { current = current->next_) {
current->state_mutex_.Unlock(); current->state_mutex_.Unlock();
} }
barrier_.Disarm(); barrier_.Disarm();
heap_->local_heaps_mutex_.Unlock(); local_heaps_mutex_.Unlock();
} }
void Safepoint::EnterFromThread(LocalHeap* local_heap) { void Safepoint::EnterFromThread(LocalHeap* local_heap) {
...@@ -83,5 +83,39 @@ SafepointScope::SafepointScope(Heap* heap) : safepoint_(heap->safepoint()) { ...@@ -83,5 +83,39 @@ SafepointScope::SafepointScope(Heap* heap) : safepoint_(heap->safepoint()) {
SafepointScope::~SafepointScope() { safepoint_->ResumeThreads(); } SafepointScope::~SafepointScope() { safepoint_->ResumeThreads(); }
void Safepoint::AddLocalHeap(LocalHeap* local_heap) {
base::MutexGuard guard(&local_heaps_mutex_);
if (local_heaps_head_) local_heaps_head_->prev_ = local_heap;
local_heap->prev_ = nullptr;
local_heap->next_ = local_heaps_head_;
local_heaps_head_ = local_heap;
}
void Safepoint::RemoveLocalHeap(LocalHeap* local_heap) {
base::MutexGuard guard(&local_heaps_mutex_);
if (local_heap->next_) local_heap->next_->prev_ = local_heap->prev_;
if (local_heap->prev_)
local_heap->prev_->next_ = local_heap->next_;
else
local_heaps_head_ = local_heap->next_;
}
bool Safepoint::ContainsLocalHeap(LocalHeap* local_heap) {
base::MutexGuard guard(&local_heaps_mutex_);
LocalHeap* current = local_heaps_head_;
while (current) {
if (current == local_heap) return true;
current = current->next_;
}
return false;
}
bool Safepoint::ContainsAnyLocalHeap() {
base::MutexGuard guard(&local_heaps_mutex_);
return local_heaps_head_ != nullptr;
}
} // namespace internal } // namespace internal
} // namespace v8 } // namespace v8
...@@ -21,6 +21,9 @@ class Safepoint { ...@@ -21,6 +21,9 @@ class Safepoint {
// Enter the safepoint from a thread // Enter the safepoint from a thread
void EnterFromThread(LocalHeap* local_heap); void EnterFromThread(LocalHeap* local_heap);
V8_EXPORT_PRIVATE bool ContainsLocalHeap(LocalHeap* local_heap);
V8_EXPORT_PRIVATE bool ContainsAnyLocalHeap();
private: private:
class Barrier { class Barrier {
base::Mutex mutex_; base::Mutex mutex_;
...@@ -38,10 +41,17 @@ class Safepoint { ...@@ -38,10 +41,17 @@ class Safepoint {
void StopThreads(); void StopThreads();
void ResumeThreads(); void ResumeThreads();
void AddLocalHeap(LocalHeap* local_heap);
void RemoveLocalHeap(LocalHeap* local_heap);
Barrier barrier_; Barrier barrier_;
Heap* heap_; Heap* heap_;
base::Mutex local_heaps_mutex_;
LocalHeap* local_heaps_head_;
friend class SafepointScope; friend class SafepointScope;
friend class LocalHeap;
}; };
class SafepointScope { class SafepointScope {
......
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
#include "src/heap/local-heap.h" #include "src/heap/local-heap.h"
#include "src/heap/heap.h" #include "src/heap/heap.h"
#include "src/heap/safepoint.h"
#include "test/unittests/test-utils.h" #include "test/unittests/test-utils.h"
#include "testing/gtest/include/gtest/gtest.h" #include "testing/gtest/include/gtest/gtest.h"
...@@ -17,20 +18,20 @@ TEST_F(LocalHeapTest, Initialize) { ...@@ -17,20 +18,20 @@ TEST_F(LocalHeapTest, Initialize) {
{ {
LocalHeap lh1(heap); LocalHeap lh1(heap);
CHECK(heap->ContainsLocalHeap(&lh1)); CHECK(heap->safepoint()->ContainsLocalHeap(&lh1));
LocalHeap lh2(heap); LocalHeap lh2(heap);
CHECK(heap->ContainsLocalHeap(&lh2)); CHECK(heap->safepoint()->ContainsLocalHeap(&lh2));
{ {
LocalHeap lh3(heap); LocalHeap lh3(heap);
CHECK(heap->ContainsLocalHeap(&lh3)); CHECK(heap->safepoint()->ContainsLocalHeap(&lh3));
} }
CHECK(heap->ContainsLocalHeap(&lh1)); CHECK(heap->safepoint()->ContainsLocalHeap(&lh1));
CHECK(heap->ContainsLocalHeap(&lh2)); CHECK(heap->safepoint()->ContainsLocalHeap(&lh2));
} }
CHECK(!heap->ContainsAnyLocalHeap()); CHECK(!heap->safepoint()->ContainsAnyLocalHeap());
} }
} // namespace internal } // namespace internal
......
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