diff --git a/include/v8-locker.h b/include/v8-locker.h index b90fc5ed91..360022b7d9 100644 --- a/include/v8-locker.h +++ b/include/v8-locker.h @@ -64,7 +64,7 @@ class Isolate; * given thread. This can be useful if you have code that can be called either * from code that holds the lock or from code that does not. The Unlocker is * not recursive so you can not have several Unlockers on the stack at once, and - * you can not use an Unlocker in a thread that is not inside a Locker's scope. + * you cannot use an Unlocker in a thread that is not inside a Locker's scope. * * An unlocker will unlock several lockers if it has to and reinstate the * correct depth of locking on its destruction, e.g.: @@ -122,8 +122,13 @@ class V8_EXPORT Locker { static bool IsLocked(Isolate* isolate); /** - * Returns whether v8::Locker is being used by this V8 instance. + * Returns whether any v8::Locker has ever been used in this process. + * TODO(cbruni, chromium:1240851): Fix locking checks on a per-thread basis. + * The current implementation is quite confusing and leads to unexpected + * results if anybody uses v8::Locker in the current process. */ + static bool WasEverUsed(); + V8_DEPRECATE_SOON("Use WasEverUsed instead") static bool IsActive(); // Disallow copying and assigning. diff --git a/src/api/api.cc b/src/api/api.cc index 2f5f4192c3..851c22cc73 100644 --- a/src/api/api.cc +++ b/src/api/api.cc @@ -947,7 +947,7 @@ void HandleScope::Initialize(Isolate* isolate) { // We make an exception if the serializer is enabled, which means that the // Isolate is exclusively used to create a snapshot. Utils::ApiCheck( - !v8::Locker::IsActive() || + !v8::Locker::WasEverUsed() || internal_isolate->thread_manager()->IsLockedByCurrentThread() || internal_isolate->serializer_enabled(), "HandleScope::HandleScope", @@ -9036,7 +9036,7 @@ void Isolate::IsolateInBackgroundNotification() { void Isolate::MemoryPressureNotification(MemoryPressureLevel level) { i::Isolate* isolate = reinterpret_cast(this); bool on_isolate_thread = - v8::Locker::IsActive() + v8::Locker::WasEverUsed() ? isolate->thread_manager()->IsLockedByCurrentThread() : i::ThreadId::Current() == isolate->thread_id(); isolate->heap()->MemoryPressureNotification(level, on_isolate_thread); diff --git a/src/execution/v8threads.cc b/src/execution/v8threads.cc index 3138823f7b..9fb8f1c30c 100644 --- a/src/execution/v8threads.cc +++ b/src/execution/v8threads.cc @@ -20,7 +20,7 @@ namespace { // Track whether this V8 instance has ever called v8::Locker. This allows the // API code to verify that the lock is always held when V8 is being entered. -base::Atomic32 g_locker_was_ever_used_ = 0; +base::AtomicWord g_locker_was_ever_used_ = 0; } // namespace @@ -53,8 +53,12 @@ bool Locker::IsLocked(v8::Isolate* isolate) { return internal_isolate->thread_manager()->IsLockedByCurrentThread(); } -bool Locker::IsActive() { - return !!base::Relaxed_Load(&g_locker_was_ever_used_); +// static +bool Locker::IsActive() { return WasEverUsed(); } + +// static +bool Locker::WasEverUsed() { + return base::Relaxed_Load(&g_locker_was_ever_used_) != 0; } Locker::~Locker() { diff --git a/src/logging/log.cc b/src/logging/log.cc index 4339d4e809..5ef24c1535 100644 --- a/src/logging/log.cc +++ b/src/logging/log.cc @@ -944,9 +944,10 @@ class Ticker : public sampler::Sampler { void SampleStack(const v8::RegisterState& state) override { if (!profiler_) return; Isolate* isolate = reinterpret_cast(this->isolate()); - if (v8::Locker::IsActive() && (!isolate->thread_manager()->IsLockedByThread( - perThreadData_->thread_id()) || - perThreadData_->thread_state() != nullptr)) + if (v8::Locker::WasEverUsed() && + (!isolate->thread_manager()->IsLockedByThread( + perThreadData_->thread_id()) || + perThreadData_->thread_state() != nullptr)) return; TickSample sample; sample.Init(isolate, state, TickSample::kIncludeCEntryFrame, true); diff --git a/src/profiler/cpu-profiler.cc b/src/profiler/cpu-profiler.cc index cf4f549a39..829f2ab67f 100644 --- a/src/profiler/cpu-profiler.cc +++ b/src/profiler/cpu-profiler.cc @@ -40,9 +40,10 @@ class CpuSampler : public sampler::Sampler { void SampleStack(const v8::RegisterState& regs) override { Isolate* isolate = reinterpret_cast(this->isolate()); - if (v8::Locker::IsActive() && (!isolate->thread_manager()->IsLockedByThread( - perThreadData_->thread_id()) || - perThreadData_->thread_state() != nullptr)) { + if (v8::Locker::WasEverUsed() && + (!isolate->thread_manager()->IsLockedByThread( + perThreadData_->thread_id()) || + perThreadData_->thread_state() != nullptr)) { ProfilerStats::Instance()->AddReason( ProfilerStats::Reason::kIsolateNotLocked); return; diff --git a/test/cctest/cctest.cc b/test/cctest/cctest.cc index 7f04173489..1a8de4c040 100644 --- a/test/cctest/cctest.cc +++ b/test/cctest/cctest.cc @@ -122,7 +122,7 @@ void CcTest::Run() { DCHECK_EQ(active_isolates, i::Isolate::non_disposed_isolates()); #endif // DEBUG if (initialize_) { - if (v8::Locker::IsActive()) { + if (v8::Locker::WasEverUsed()) { v8::Locker locker(isolate_); EmptyMessageQueues(isolate_); } else {