[heap] Fix global safepoint when waiting in event loop
When starting a global safepoint, it could happen that one isolate is waiting/blocking in the event loop, which prevents this isolate from reaching a safepoint. As a consequence we therefore deadlock when performing the safepoint. We can solve this by simply posting a task for each isolate that when run performs a safepoint check. This CL also renames IncludeMainThreadUnlessInitiator to ShouldIncludeMainThread. Bug: v8:11708, v8:12645 Change-Id: Ide956b3c39b350c2bb0279a7dd94ff79cb9d771b Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3555771 Reviewed-by: Anton Bikineev <bikineev@chromium.org> Commit-Queue: Dominik Inführ <dinfuehr@chromium.org> Cr-Commit-Position: refs/heads/main@{#79675}
This commit is contained in:
parent
007076e536
commit
3eb8671edb
@ -84,18 +84,43 @@ void IsolateSafepoint::TryInitiateGlobalSafepointScope(
|
||||
InitiateGlobalSafepointScopeRaw(initiator, client_data);
|
||||
}
|
||||
|
||||
class GlobalSafepointInterruptTask : public CancelableTask {
|
||||
public:
|
||||
explicit GlobalSafepointInterruptTask(Heap* heap)
|
||||
: CancelableTask(heap->isolate()), heap_(heap) {}
|
||||
|
||||
~GlobalSafepointInterruptTask() override = default;
|
||||
GlobalSafepointInterruptTask(const GlobalSafepointInterruptTask&) = delete;
|
||||
GlobalSafepointInterruptTask& operator=(const GlobalSafepointInterruptTask&) =
|
||||
delete;
|
||||
|
||||
private:
|
||||
// v8::internal::CancelableTask overrides.
|
||||
void RunInternal() override { heap_->main_thread_local_heap()->Safepoint(); }
|
||||
|
||||
Heap* heap_;
|
||||
};
|
||||
|
||||
void IsolateSafepoint::InitiateGlobalSafepointScopeRaw(
|
||||
Isolate* initiator, PerClientSafepointData* client_data) {
|
||||
CHECK_EQ(++active_safepoint_scopes_, 1);
|
||||
barrier_.Arm();
|
||||
|
||||
size_t running =
|
||||
SetSafepointRequestedFlags(IncludeMainThreadUnlessInitiator(initiator));
|
||||
SetSafepointRequestedFlags(ShouldIncludeMainThread(initiator));
|
||||
client_data->set_locked_and_running(running);
|
||||
|
||||
if (isolate() != initiator) {
|
||||
// An isolate might be waiting in the event loop. Post a task in order to
|
||||
// wake it up.
|
||||
V8::GetCurrentPlatform()
|
||||
->GetForegroundTaskRunner(reinterpret_cast<v8::Isolate*>(isolate()))
|
||||
->PostTask(std::make_unique<GlobalSafepointInterruptTask>(heap_));
|
||||
}
|
||||
}
|
||||
|
||||
IsolateSafepoint::IncludeMainThread
|
||||
IsolateSafepoint::IncludeMainThreadUnlessInitiator(Isolate* initiator) {
|
||||
IsolateSafepoint::IncludeMainThread IsolateSafepoint::ShouldIncludeMainThread(
|
||||
Isolate* initiator) {
|
||||
const bool is_initiator = isolate() == initiator;
|
||||
return is_initiator ? IncludeMainThread::kNo : IncludeMainThread::kYes;
|
||||
}
|
||||
@ -136,7 +161,7 @@ void IsolateSafepoint::LockMutex(LocalHeap* local_heap) {
|
||||
void IsolateSafepoint::LeaveGlobalSafepointScope(Isolate* initiator) {
|
||||
local_heaps_mutex_.AssertHeld();
|
||||
CHECK_EQ(--active_safepoint_scopes_, 0);
|
||||
ClearSafepointRequestedFlags(IncludeMainThreadUnlessInitiator(initiator));
|
||||
ClearSafepointRequestedFlags(ShouldIncludeMainThread(initiator));
|
||||
barrier_.Disarm();
|
||||
local_heaps_mutex_.Unlock();
|
||||
}
|
||||
|
@ -94,7 +94,7 @@ class IsolateSafepoint final {
|
||||
void WaitUntilRunningThreadsInSafepoint(
|
||||
const PerClientSafepointData* client_data);
|
||||
|
||||
IncludeMainThread IncludeMainThreadUnlessInitiator(Isolate* initiator);
|
||||
IncludeMainThread ShouldIncludeMainThread(Isolate* initiator);
|
||||
|
||||
void LockMutex(LocalHeap* local_heap);
|
||||
|
||||
|
@ -273,10 +273,6 @@
|
||||
# TODO(v8:10915): Fails with --future.
|
||||
'harmony/weakrefs/stress-finalizationregistry-dirty-enqueue': [SKIP],
|
||||
|
||||
# BUG(v8:12645)
|
||||
'shared-memory/shared-struct-workers': [SKIP],
|
||||
'shared-memory/shared-struct-atomics-workers': [SKIP],
|
||||
|
||||
# Needs deterministic test helpers for concurrent maglev tiering.
|
||||
# TODO(jgruber,v8:7700): Implement ASAP.
|
||||
'maglev/18': [SKIP],
|
||||
|
Loading…
Reference in New Issue
Block a user