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