Commit 6e6f6d09 authored by Ulan Degenbaev's avatar Ulan Degenbaev Committed by Commit Bot

[heap] Implement LocalHeap::Current using thread_local

This is needed for write-barrier and persistent-handle code that does
not otherwise get an instance of LocalHeap

Bug: v8:10315
Change-Id: I480e31f32141510f2f9e678af3449d5841e3156e
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2284492
Commit-Queue: Ulan Degenbaev <ulan@chromium.org>
Reviewed-by: 's avatarDominik Inführ <dinfuehr@chromium.org>
Cr-Commit-Position: refs/heads/master@{#68720}
parent 2d5017a0
...@@ -14,6 +14,12 @@ ...@@ -14,6 +14,12 @@
namespace v8 { namespace v8 {
namespace internal { namespace internal {
namespace {
thread_local LocalHeap* current_local_heap = nullptr;
} // namespace
LocalHeap* LocalHeap::Current() { return current_local_heap; }
LocalHeap::LocalHeap(Heap* heap, LocalHeap::LocalHeap(Heap* heap,
std::unique_ptr<PersistentHandles> persistent_handles) std::unique_ptr<PersistentHandles> persistent_handles)
: heap_(heap), : heap_(heap),
...@@ -29,6 +35,8 @@ LocalHeap::LocalHeap(Heap* heap, ...@@ -29,6 +35,8 @@ LocalHeap::LocalHeap(Heap* heap,
if (persistent_handles_) { if (persistent_handles_) {
persistent_handles_->Attach(this); persistent_handles_->Attach(this);
} }
DCHECK_NULL(current_local_heap);
current_local_heap = this;
} }
LocalHeap::~LocalHeap() { LocalHeap::~LocalHeap() {
...@@ -39,6 +47,9 @@ LocalHeap::~LocalHeap() { ...@@ -39,6 +47,9 @@ LocalHeap::~LocalHeap() {
EnsureParkedBeforeDestruction(); EnsureParkedBeforeDestruction();
heap_->safepoint()->RemoveLocalHeap(this); heap_->safepoint()->RemoveLocalHeap(this);
DCHECK_EQ(current_local_heap, this);
current_local_heap = nullptr;
} }
Handle<Object> LocalHeap::NewPersistentHandle(Address value) { Handle<Object> LocalHeap::NewPersistentHandle(Address value) {
......
...@@ -21,12 +21,11 @@ class Safepoint; ...@@ -21,12 +21,11 @@ class Safepoint;
class LocalHandles; class LocalHandles;
class PersistentHandles; class PersistentHandles;
class LocalHeap { class V8_EXPORT_PRIVATE LocalHeap {
public: public:
V8_EXPORT_PRIVATE explicit LocalHeap( LocalHeap(Heap* heap,
Heap* heap,
std::unique_ptr<PersistentHandles> persistent_handles = nullptr); std::unique_ptr<PersistentHandles> persistent_handles = nullptr);
V8_EXPORT_PRIVATE ~LocalHeap(); ~LocalHeap();
// Invoked by main thread to signal this thread that it needs to halt in a // Invoked by main thread to signal this thread that it needs to halt in a
// safepoint. // safepoint.
...@@ -34,13 +33,12 @@ class LocalHeap { ...@@ -34,13 +33,12 @@ class LocalHeap {
// Frequently invoked by local thread to check whether safepoint was requested // Frequently invoked by local thread to check whether safepoint was requested
// from the main thread. // from the main thread.
V8_EXPORT_PRIVATE void Safepoint(); void Safepoint();
LocalHandles* handles() { return handles_.get(); } LocalHandles* handles() { return handles_.get(); }
V8_EXPORT_PRIVATE Handle<Object> NewPersistentHandle(Address value); Handle<Object> NewPersistentHandle(Address value);
V8_EXPORT_PRIVATE std::unique_ptr<PersistentHandles> std::unique_ptr<PersistentHandles> DetachPersistentHandles();
DetachPersistentHandles();
bool IsParked(); bool IsParked();
...@@ -59,6 +57,13 @@ class LocalHeap { ...@@ -59,6 +57,13 @@ class LocalHeap {
// iterable heap. // iterable heap.
void MakeLinearAllocationAreaIterable(); void MakeLinearAllocationAreaIterable();
// Fetches a pointer to the local heap from the thread local storage.
// It is intended to be used in handle and write barrier code where it is
// difficult to get a pointer to the current instance of local heap otherwise.
// The result may be a nullptr if there is no local heap instance associated
// with the current thread.
static LocalHeap* Current();
private: private:
enum class ThreadState { enum class ThreadState {
// Threads in this state need to be stopped in a safepoint. // Threads in this state need to be stopped in a safepoint.
...@@ -70,8 +75,8 @@ class LocalHeap { ...@@ -70,8 +75,8 @@ class LocalHeap {
Safepoint Safepoint
}; };
V8_EXPORT_PRIVATE void Park(); void Park();
V8_EXPORT_PRIVATE void Unpark(); void Unpark();
void EnsureParkedBeforeDestruction(); void EnsureParkedBeforeDestruction();
bool IsSafepointRequested(); bool IsSafepointRequested();
......
...@@ -16,22 +16,68 @@ using LocalHeapTest = TestWithIsolate; ...@@ -16,22 +16,68 @@ using LocalHeapTest = TestWithIsolate;
TEST_F(LocalHeapTest, Initialize) { TEST_F(LocalHeapTest, Initialize) {
Heap* heap = i_isolate()->heap(); Heap* heap = i_isolate()->heap();
CHECK(!heap->safepoint()->ContainsAnyLocalHeap());
{ {
LocalHeap lh1(heap); LocalHeap lh(heap);
CHECK(heap->safepoint()->ContainsLocalHeap(&lh1)); CHECK(heap->safepoint()->ContainsLocalHeap(&lh));
LocalHeap lh2(heap); }
CHECK(heap->safepoint()->ContainsLocalHeap(&lh2));
CHECK(!heap->safepoint()->ContainsAnyLocalHeap());
}
TEST_F(LocalHeapTest, Current) {
Heap* heap = i_isolate()->heap();
CHECK_NULL(LocalHeap::Current());
{ {
LocalHeap lh3(heap); LocalHeap lh(heap);
CHECK(heap->safepoint()->ContainsLocalHeap(&lh3)); CHECK_EQ(&lh, LocalHeap::Current());
} }
CHECK(heap->safepoint()->ContainsLocalHeap(&lh1)); CHECK_NULL(LocalHeap::Current());
CHECK(heap->safepoint()->ContainsLocalHeap(&lh2));
{
LocalHeap lh(heap);
CHECK_EQ(&lh, LocalHeap::Current());
} }
CHECK(!heap->safepoint()->ContainsAnyLocalHeap()); CHECK_NULL(LocalHeap::Current());
}
namespace {
class BackgroundThread final : public v8::base::Thread {
public:
explicit BackgroundThread(Heap* heap)
: v8::base::Thread(base::Thread::Options("BackgroundThread")),
heap_(heap) {}
void Run() override {
CHECK_NULL(LocalHeap::Current());
{
LocalHeap lh(heap_);
CHECK_EQ(&lh, LocalHeap::Current());
}
CHECK_NULL(LocalHeap::Current());
}
Heap* heap_;
};
} // anonymous namespace
TEST_F(LocalHeapTest, CurrentBackground) {
Heap* heap = i_isolate()->heap();
CHECK_NULL(LocalHeap::Current());
{
LocalHeap lh(heap);
auto thread = std::make_unique<BackgroundThread>(heap);
CHECK(thread->Start());
CHECK_EQ(&lh, LocalHeap::Current());
thread->Join();
CHECK_EQ(&lh, LocalHeap::Current());
}
CHECK_NULL(LocalHeap::Current());
} }
} // 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