[vm, isolates] Fix deletion of handles when not entered into an isolate group.

Handles may only be allocated/updated/deleted by a thread whose execution state prevents GC from running.

TEST=tsan
Change-Id: Id2853e30d326642acc572dbd1c03345aaefd0f45
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/398606
Commit-Queue: Ryan Macnak <rmacnak@google.com>
Reviewed-by: Alexander Aprelev <aam@google.com>
This commit is contained in:
Ryan Macnak
2024-12-03 23:24:48 +00:00
committed by Commit Queue
parent c5b442251e
commit 76c2573985
4 changed files with 20 additions and 30 deletions
+12 -9
View File
@@ -581,9 +581,6 @@ class IsolateSpawnState {
IsolateGroup* group);
~IsolateSpawnState();
Isolate* isolate() const { return isolate_; }
void set_isolate(Isolate* value) { isolate_ = value; }
Dart_Port parent_port() const { return parent_port_; }
Dart_Port origin_id() const { return origin_id_; }
Dart_Port on_exit_port() const { return on_exit_port_; }
@@ -608,7 +605,6 @@ class IsolateSpawnState {
IsolateGroup* isolate_group() const { return isolate_group_; }
private:
Isolate* isolate_ = nullptr;
Dart_Port parent_port_;
Dart_Port origin_id_ = ILLEGAL_PORT;
Dart_Port on_exit_port_;
@@ -880,12 +876,14 @@ class SpawnIsolateTask : public ThreadPool::Task {
return;
}
state_->set_isolate(child);
if (state_->origin_id() != ILLEGAL_PORT) {
// origin_id is set to parent isolate main port id when spawning via
// spawnFunction.
child->set_origin_id(state_->origin_id());
}
bool errors_are_fatal = state_->errors_are_fatal();
Dart_Port on_error_port = state_->on_error_port();
Dart_Port on_exit_port = state_->on_exit_port();
bool success = true;
{
@@ -895,18 +893,22 @@ class SpawnIsolateTask : public ThreadPool::Task {
HandleScope hs(thread);
success = EnqueueEntrypointInvocationAndNotifySpawner(thread);
// Destruction of [IsolateSpawnState] may cause destruction of [Message]
// which make need to delete persistent handles, so explicitly delete it
// now while we are in the right safepoint state.
state_ = nullptr;
}
if (!success) {
state_ = nullptr;
Dart_ShutdownIsolate();
return;
}
// All preconditions are met for this to always succeed.
char* error = nullptr;
if (!Dart_RunLoopAsync(state_->errors_are_fatal(), state_->on_error_port(),
state_->on_exit_port(), &error)) {
if (!Dart_RunLoopAsync(errors_are_fatal, on_error_port, on_exit_port,
&error)) {
FATAL("Dart_RunLoopAsync() failed: %s. Please file a Dart VM bug report.",
error);
}
@@ -1030,12 +1032,13 @@ class SpawnIsolateTask : public ThreadPool::Task {
// isolate group).
if (has_current_isolate) {
ASSERT(IsolateGroup::Current() == state_->isolate_group());
TransitionNativeToVM transition(Thread::Current());
state_ = nullptr;
} else if (state_->isolate_group() != nullptr) {
ASSERT(IsolateGroup::Current() == nullptr);
const bool kBypassSafepoint = false;
const bool result = Thread::EnterIsolateGroupAsHelper(
state_->isolate_group(), Thread::kUnknownTask, kBypassSafepoint);
state_->isolate_group(), Thread::kSpawnTask, kBypassSafepoint);
ASSERT(result);
state_ = nullptr;
Thread::ExitIsolateGroupAsHelper(kBypassSafepoint);
+7 -1
View File
@@ -178,7 +178,13 @@ class PersistentHandle {
ptr_ = static_cast<ObjectPtr>(reinterpret_cast<uword>(free_list));
ASSERT(!ptr_->IsHeapObject());
}
void FreeHandle(PersistentHandle* free_list) { SetNext(free_list); }
void FreeHandle(PersistentHandle* free_list) {
#if defined(DEBUG)
Thread* thread = Thread::Current();
ASSERT(thread->MayAllocateHandles());
#endif // DEBUG
SetNext(free_list);
}
ObjectPtr ptr_;
DISALLOW_ALLOCATION(); // Allocated through AllocateHandle methods.
-18
View File
@@ -253,24 +253,6 @@ ErrorPtr Thread::StealStickyError() {
return return_value;
}
const char* Thread::TaskKindToCString(TaskKind kind) {
switch (kind) {
case kUnknownTask:
return "kUnknownTask";
case kMutatorTask:
return "kMutatorTask";
case kCompilerTask:
return "kCompilerTask";
case kSweeperTask:
return "kSweeperTask";
case kMarkerTask:
return "kMarkerTask";
default:
UNREACHABLE();
return "";
}
}
void Thread::AssertNonMutatorInvariants() {
ASSERT(BypassSafepoints());
ASSERT(store_buffer_block_ == nullptr);
+1 -2
View File
@@ -365,9 +365,8 @@ class Thread : public ThreadState {
kScavengerTask,
kSampleBlockTask,
kIncrementalCompactorTask,
kSpawnTask,
};
// Converts a TaskKind to its corresponding C-String name.
static const char* TaskKindToCString(TaskKind kind);
~Thread();