[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:
Dominik Inführ 2020-03-17 08:18:09 +01:00 committed by Commit Bot
parent 7c2ae383a1
commit 143ad476ef
6 changed files with 59 additions and 58 deletions

View File

@ -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;

View File

@ -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;

View File

@ -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() {

View File

@ -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

View File

@ -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 {

View File

@ -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