[vm/concurrency] Ensure CreateWithinExistingIsolateGroup is re-setting the cached isolate_group pointer in the mutator thread

When moving the newly spawned isolate from the spawnee group to the main
group we have to ensure to update the cached
`Isolate::mutator_thread_->isolate_group_` pointer (which we do not
reset when descheduling mutator threads (for other threads we do)).

This will fix the ASAN crash in this test:

  tools/test.py -n dartk-asan-linux-release-x64 lib_2/isolate/mandel_isolate_test

Fixes https://github.com/dart-lang/sdk/issues/40756

Change-Id: I5a897098106e6748cf4e58bd5d2799ce28b130a8
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/136971
Reviewed-by: Alexander Aprelev <aam@google.com>
Commit-Queue: Martin Kustermann <kustermann@google.com>
This commit is contained in:
Martin Kustermann 2020-02-28 15:43:51 +00:00 committed by commit-bot@chromium.org
parent 001db5d669
commit 54b730b3df
3 changed files with 20 additions and 1 deletions

View file

@ -1319,6 +1319,16 @@ Isolate* CreateWithinExistingIsolateGroup(IsolateGroup* group,
group->RegisterIsolateLocked(isolate);
isolate->class_table()->shared_class_table_ = group->class_table();
// Even though the mutator thread was descheduled, it will still
// retain its [Thread] structure with valid isolate/isolate_group
// pointers.
// If GC happens before the mutator gets scheduled again, we have to
// ensure the isolate group change is reflected in the threads
// structure.
ASSERT(isolate->mutator_thread() != nullptr);
ASSERT(isolate->mutator_thread()->isolate_group() == spawning_group);
isolate->mutator_thread()->isolate_group_ = group;
// Allow other old space GC tasks to run again.
{
auto old_space = group->heap()->old_space();

View file

@ -433,7 +433,8 @@ void IsolateGroup::UnscheduleThreadLocked(MonitorLocker* ml,
// All other threads are not allowed to unschedule themselves and schedule
// again later on.
if (!is_mutator) {
thread->isolate_ = nullptr;
ASSERT(thread->isolate_ == nullptr);
thread->isolate_group_ = nullptr;
}
thread->heap_ = nullptr;
thread->set_os_thread(nullptr);
@ -3415,6 +3416,11 @@ void Isolate::UnscheduleThread(Thread* thread,
ASSERT(mutator_thread_ == thread);
ASSERT(mutator_thread_ == scheduled_mutator_thread_);
scheduled_mutator_thread_ = nullptr;
} else {
// We only reset the isolate pointer for non-mutator threads, since mutator
// threads can still be visited during GC even if unscheduled.
// See also IsolateGroup::UnscheduleThreadLocked`
thread->isolate_ = nullptr;
}
thread->field_table_values_ = nullptr;
group()->UnscheduleThreadLocked(&ml, thread, is_mutator, bypass_safepoint);

View file

@ -1031,6 +1031,9 @@ class Thread : public ThreadState {
friend class CompilerState;
friend class compiler::target::Thread;
friend class FieldTable;
friend Isolate* CreateWithinExistingIsolateGroup(IsolateGroup*,
const char*,
char**);
DISALLOW_COPY_AND_ASSIGN(Thread);
};