mirror of
https://github.com/dart-lang/sdk
synced 2024-10-14 15:57:17 +00:00
[vm] Remove Thread::{Enter,Exit}IsolateAsHelper
For every isolate there should be only one mutator with a unique [Thread] object. We change existing tests that use this functionality to instead use `Thread::{Enter,Exit}IsolateGroupAsHelper`. It also results in a net removal of code. TEST=ci Change-Id: Ic326e868a98ddedbab5b8c429252d38ea71bbf04 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/295940 Commit-Queue: Martin Kustermann <kustermann@google.com> Reviewed-by: Ryan Macnak <rmacnak@google.com>
This commit is contained in:
parent
fb43937e20
commit
779e51efc1
|
@ -2653,14 +2653,16 @@ static void TestDirectAccess(Dart_Handle lib,
|
|||
|
||||
class BackgroundGCTask : public ThreadPool::Task {
|
||||
public:
|
||||
BackgroundGCTask(Isolate* isolate, Monitor* monitor, bool* done)
|
||||
: isolate_(isolate), monitor_(monitor), done_(done) {}
|
||||
BackgroundGCTask(IsolateGroup* isolate_group, Monitor* monitor, bool* done)
|
||||
: isolate_group_(isolate_group), monitor_(monitor), done_(done) {}
|
||||
virtual void Run() {
|
||||
Thread::EnterIsolateAsHelper(isolate_, Thread::kUnknownTask);
|
||||
const bool kBypassSafepoint = false;
|
||||
Thread::EnterIsolateGroupAsHelper(isolate_group_, Thread::kUnknownTask,
|
||||
kBypassSafepoint);
|
||||
for (intptr_t i = 0; i < 10; i++) {
|
||||
GCTestHelper::CollectAllGarbage();
|
||||
}
|
||||
Thread::ExitIsolateAsHelper();
|
||||
Thread::ExitIsolateGroupAsHelper(kBypassSafepoint);
|
||||
{
|
||||
MonitorLocker ml(monitor_);
|
||||
*done_ = true;
|
||||
|
@ -2669,7 +2671,7 @@ class BackgroundGCTask : public ThreadPool::Task {
|
|||
}
|
||||
|
||||
private:
|
||||
Isolate* isolate_;
|
||||
IsolateGroup* isolate_group_;
|
||||
Monitor* monitor_;
|
||||
bool* done_;
|
||||
};
|
||||
|
@ -2704,7 +2706,7 @@ static void TestTypedDataDirectAccess1() {
|
|||
|
||||
Monitor monitor;
|
||||
bool done = false;
|
||||
Dart::thread_pool()->Run<BackgroundGCTask>(Isolate::Current(), &monitor,
|
||||
Dart::thread_pool()->Run<BackgroundGCTask>(IsolateGroup::Current(), &monitor,
|
||||
&done);
|
||||
|
||||
for (intptr_t i = 0; i < 10; i++) {
|
||||
|
|
|
@ -793,13 +793,17 @@ ISOLATE_UNIT_TEST_CASE(ArrayTruncationRaces) {
|
|||
|
||||
class ConcurrentForceGrowthScopeTask : public ThreadPool::Task {
|
||||
public:
|
||||
ConcurrentForceGrowthScopeTask(Isolate* isolate,
|
||||
ConcurrentForceGrowthScopeTask(IsolateGroup* isolate_group,
|
||||
Monitor* monitor,
|
||||
intptr_t* done_count)
|
||||
: isolate_(isolate), monitor_(monitor), done_count_(done_count) {}
|
||||
: isolate_group_(isolate_group),
|
||||
monitor_(monitor),
|
||||
done_count_(done_count) {}
|
||||
|
||||
virtual void Run() {
|
||||
Thread::EnterIsolateAsHelper(isolate_, Thread::kUnknownTask);
|
||||
const bool kBypassSafepoint = false;
|
||||
Thread::EnterIsolateGroupAsHelper(isolate_group_, Thread::kUnknownTask,
|
||||
kBypassSafepoint);
|
||||
{
|
||||
Thread* thread = Thread::Current();
|
||||
StackZone stack_zone(thread);
|
||||
|
@ -819,7 +823,7 @@ class ConcurrentForceGrowthScopeTask : public ThreadPool::Task {
|
|||
accumulate.Add(element);
|
||||
}
|
||||
}
|
||||
Thread::ExitIsolateAsHelper();
|
||||
Thread::ExitIsolateGroupAsHelper(kBypassSafepoint);
|
||||
// Notify the main thread that this thread has exited.
|
||||
{
|
||||
MonitorLocker ml(monitor_);
|
||||
|
@ -829,7 +833,7 @@ class ConcurrentForceGrowthScopeTask : public ThreadPool::Task {
|
|||
}
|
||||
|
||||
private:
|
||||
Isolate* isolate_;
|
||||
IsolateGroup* isolate_group_;
|
||||
Monitor* monitor_;
|
||||
intptr_t* done_count_;
|
||||
};
|
||||
|
@ -841,7 +845,7 @@ ISOLATE_UNIT_TEST_CASE(ConcurrentForceGrowthScope) {
|
|||
|
||||
for (intptr_t i = 0; i < task_count; i++) {
|
||||
Dart::thread_pool()->Run<ConcurrentForceGrowthScopeTask>(
|
||||
thread->isolate(), &monitor, &done_count);
|
||||
thread->isolate_group(), &monitor, &done_count);
|
||||
}
|
||||
|
||||
{
|
||||
|
|
|
@ -3654,12 +3654,8 @@ Monitor* IsolateGroup::threads_lock() const {
|
|||
return thread_registry_->threads_lock();
|
||||
}
|
||||
|
||||
Thread* Isolate::ScheduleThread(bool is_mutator,
|
||||
bool is_nested_reenter,
|
||||
bool bypass_safepoint) {
|
||||
if (is_mutator) {
|
||||
group()->IncreaseMutatorCount(this, is_nested_reenter);
|
||||
}
|
||||
Thread* Isolate::ScheduleThread(bool is_nested_reenter) {
|
||||
group()->IncreaseMutatorCount(this, is_nested_reenter);
|
||||
|
||||
// We are about to associate the thread with an isolate group and it would
|
||||
// not be possible to correctly track no_safepoint_scope_depth for the
|
||||
|
@ -3669,7 +3665,7 @@ Thread* Isolate::ScheduleThread(bool is_mutator,
|
|||
MonitorLocker ml(group()->threads_lock(), false);
|
||||
|
||||
// Check to make sure we don't already have a mutator thread.
|
||||
if (is_mutator && scheduled_mutator_thread_ != nullptr) {
|
||||
if (scheduled_mutator_thread_ != nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
@ -3680,7 +3676,7 @@ Thread* Isolate::ScheduleThread(bool is_mutator,
|
|||
|
||||
// We lazily create a [Thread] structure for the mutator thread, but we'll
|
||||
// reuse it until the death of the isolate.
|
||||
Thread* existing_mutator_thread = is_mutator ? mutator_thread_ : nullptr;
|
||||
Thread* existing_mutator_thread = mutator_thread_;
|
||||
if (existing_mutator_thread != nullptr) {
|
||||
ASSERT(existing_mutator_thread->is_mutator_thread_);
|
||||
}
|
||||
|
@ -3689,23 +3685,19 @@ Thread* Isolate::ScheduleThread(bool is_mutator,
|
|||
// with it (this is done while we are holding the thread registry lock).
|
||||
Thread* thread =
|
||||
group()->ScheduleThreadLocked(&ml, existing_mutator_thread, is_vm_isolate,
|
||||
is_mutator, bypass_safepoint);
|
||||
if (is_mutator) {
|
||||
ASSERT(mutator_thread_ == nullptr || mutator_thread_ == thread);
|
||||
mutator_thread_ = thread;
|
||||
scheduled_mutator_thread_ = thread;
|
||||
thread->is_mutator_thread_ = true;
|
||||
thread->field_table_values_ = field_table_->table();
|
||||
}
|
||||
/*is_mutator=*/true,
|
||||
/*bypass_safepoint=*/false);
|
||||
ASSERT(mutator_thread_ == nullptr || mutator_thread_ == thread);
|
||||
mutator_thread_ = thread;
|
||||
scheduled_mutator_thread_ = thread;
|
||||
thread->is_mutator_thread_ = true;
|
||||
thread->field_table_values_ = field_table_->table();
|
||||
thread->isolate_ = this;
|
||||
|
||||
return thread;
|
||||
}
|
||||
|
||||
void Isolate::UnscheduleThread(Thread* thread,
|
||||
bool is_mutator,
|
||||
bool is_nested_exit,
|
||||
bool bypass_safepoint) {
|
||||
void Isolate::UnscheduleThread(Thread* thread, bool is_nested_exit) {
|
||||
{
|
||||
// Disassociate the 'Thread' structure and unschedule the thread
|
||||
// from this isolate.
|
||||
|
@ -3716,26 +3708,18 @@ void Isolate::UnscheduleThread(Thread* thread,
|
|||
// no_safepoint_scope_depth increments/decrements.
|
||||
MonitorLocker ml(group()->threads_lock(), false);
|
||||
|
||||
if (is_mutator) {
|
||||
if (thread->sticky_error() != Error::null()) {
|
||||
ASSERT(sticky_error_ == Error::null());
|
||||
sticky_error_ = thread->StealStickyError();
|
||||
}
|
||||
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;
|
||||
if (thread->sticky_error() != Error::null()) {
|
||||
ASSERT(sticky_error_ == Error::null());
|
||||
sticky_error_ = thread->StealStickyError();
|
||||
}
|
||||
ASSERT(mutator_thread_ == thread);
|
||||
ASSERT(mutator_thread_ == scheduled_mutator_thread_);
|
||||
scheduled_mutator_thread_ = nullptr;
|
||||
thread->field_table_values_ = nullptr;
|
||||
group()->UnscheduleThreadLocked(&ml, thread, is_mutator, bypass_safepoint);
|
||||
}
|
||||
if (is_mutator) {
|
||||
group()->DecreaseMutatorCount(this, is_nested_exit);
|
||||
group()->UnscheduleThreadLocked(&ml, thread, /*is_mutator=*/true,
|
||||
/*bypass_safepoint=*/false);
|
||||
}
|
||||
group()->DecreaseMutatorCount(this, is_nested_exit);
|
||||
}
|
||||
|
||||
#if !defined(PRODUCT)
|
||||
|
|
|
@ -1537,13 +1537,8 @@ class Isolate : public BaseIsolate, public IntrusiveDListEntry<Isolate> {
|
|||
const GrowableObjectArray& value);
|
||||
#endif // !defined(PRODUCT)
|
||||
|
||||
Thread* ScheduleThread(bool is_mutator,
|
||||
bool is_nested_reenter,
|
||||
bool bypass_safepoint);
|
||||
void UnscheduleThread(Thread* thread,
|
||||
bool is_mutator,
|
||||
bool is_nested_exit,
|
||||
bool bypass_safepoint);
|
||||
Thread* ScheduleThread(bool is_nested_reenter);
|
||||
void UnscheduleThread(Thread* thread, bool is_nested_exit);
|
||||
|
||||
// DEPRECATED: Use Thread's methods instead. During migration, these default
|
||||
// to using the mutator thread (which must also be the current thread).
|
||||
|
|
|
@ -113,7 +113,9 @@ class InterruptChecker : public ThreadPool::Task {
|
|||
: thread_(thread), barrier_(barrier) {}
|
||||
|
||||
virtual void Run() {
|
||||
Thread::EnterIsolateAsHelper(thread_->isolate(), Thread::kUnknownTask);
|
||||
const bool kBypassSafepoint = false;
|
||||
Thread::EnterIsolateGroupAsHelper(thread_->isolate_group(),
|
||||
Thread::kUnknownTask, kBypassSafepoint);
|
||||
// Tell main thread that we are ready.
|
||||
barrier_->Sync();
|
||||
for (intptr_t i = 0; i < kIterations; ++i) {
|
||||
|
@ -129,7 +131,7 @@ class InterruptChecker : public ThreadPool::Task {
|
|||
// Tell main thread that we observed the interrupt.
|
||||
barrier_->Sync();
|
||||
}
|
||||
Thread::ExitIsolateAsHelper();
|
||||
Thread::ExitIsolateGroupAsHelper(kBypassSafepoint);
|
||||
barrier_->Sync();
|
||||
barrier_->Release();
|
||||
}
|
||||
|
|
|
@ -300,15 +300,18 @@ DART_EXPORT void* Dart_ExecuteInternalCommand(const char* command, void* arg) {
|
|||
reinterpret_cast<RunInSafepointAndRWCodeArgs*>(arg);
|
||||
Isolate* const isolate = args->isolate;
|
||||
CHECK_ISOLATE(isolate);
|
||||
Thread::EnterIsolateAsHelper(isolate, Thread::TaskKind::kUnknownTask);
|
||||
auto isolate_group = isolate->group();
|
||||
const bool kBypassSafepoint = false;
|
||||
Thread::EnterIsolateGroupAsHelper(isolate_group, Thread::kUnknownTask,
|
||||
kBypassSafepoint);
|
||||
Thread* const thread = Thread::Current();
|
||||
{
|
||||
GcSafepointOperationScope scope(thread);
|
||||
args->isolate->group()->heap()->WriteProtectCode(/*read_only=*/false);
|
||||
isolate_group->heap()->WriteProtectCode(/*read_only=*/false);
|
||||
(*args->callback)();
|
||||
args->isolate->group()->heap()->WriteProtectCode(/*read_only=*/true);
|
||||
isolate_group->heap()->WriteProtectCode(/*read_only=*/true);
|
||||
}
|
||||
Thread::ExitIsolateAsHelper();
|
||||
Thread::ExitIsolateGroupAsHelper(kBypassSafepoint);
|
||||
return nullptr;
|
||||
|
||||
} else {
|
||||
|
|
|
@ -1790,9 +1790,9 @@ class StreamableSampleFilter : public SampleFilter {
|
|||
}
|
||||
};
|
||||
|
||||
void Profiler::ProcessCompletedBlocks(Thread* thread) {
|
||||
void Profiler::ProcessCompletedBlocks(Isolate* isolate) {
|
||||
if (!Service::profiler_stream.enabled()) return;
|
||||
Isolate* isolate = thread->isolate();
|
||||
auto thread = Thread::Current();
|
||||
if (Isolate::IsSystemIsolate(isolate)) return;
|
||||
|
||||
TIMELINE_DURATION(thread, Isolate, "Profiler::ProcessCompletedBlocks")
|
||||
|
@ -1809,7 +1809,7 @@ void Profiler::ProcessCompletedBlocks(Thread* thread) {
|
|||
|
||||
void Profiler::IsolateShutdown(Thread* thread) {
|
||||
FlushSampleBlocks(thread->isolate());
|
||||
ProcessCompletedBlocks(thread);
|
||||
ProcessCompletedBlocks(thread->isolate());
|
||||
}
|
||||
|
||||
class SampleBlockProcessorVisitor : public IsolateVisitor {
|
||||
|
@ -1819,9 +1819,11 @@ class SampleBlockProcessorVisitor : public IsolateVisitor {
|
|||
|
||||
void VisitIsolate(Isolate* isolate) {
|
||||
if (isolate->TakeHasCompletedBlocks()) {
|
||||
Thread::EnterIsolateAsHelper(isolate, Thread::kSampleBlockTask);
|
||||
Profiler::ProcessCompletedBlocks(Thread::Current());
|
||||
Thread::ExitIsolateAsHelper();
|
||||
const bool kBypassSafepoint = false;
|
||||
Thread::EnterIsolateGroupAsHelper(
|
||||
isolate->group(), Thread::kSampleBlockTask, kBypassSafepoint);
|
||||
Profiler::ProcessCompletedBlocks(isolate);
|
||||
Thread::ExitIsolateGroupAsHelper(kBypassSafepoint);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
@ -94,7 +94,7 @@ class Profiler : public AllStatic {
|
|||
}
|
||||
inline static intptr_t Size();
|
||||
|
||||
static void ProcessCompletedBlocks(Thread* thread);
|
||||
static void ProcessCompletedBlocks(Isolate* isolate);
|
||||
static void IsolateShutdown(Thread* thread);
|
||||
|
||||
private:
|
||||
|
|
|
@ -272,15 +272,11 @@ const char* Thread::TaskKindToCString(TaskKind kind) {
|
|||
}
|
||||
|
||||
bool Thread::EnterIsolate(Isolate* isolate, bool is_nested_reenter) {
|
||||
const bool kIsMutatorThread = true;
|
||||
const bool kBypassSafepoint = false;
|
||||
|
||||
is_nested_reenter = is_nested_reenter ||
|
||||
(isolate->mutator_thread() != nullptr &&
|
||||
isolate->mutator_thread()->top_exit_frame_info() != 0);
|
||||
|
||||
Thread* thread = isolate->ScheduleThread(kIsMutatorThread, is_nested_reenter,
|
||||
kBypassSafepoint);
|
||||
Thread* thread = isolate->ScheduleThread(is_nested_reenter);
|
||||
if (thread != nullptr) {
|
||||
ASSERT(thread->store_buffer_block_ == nullptr);
|
||||
ASSERT(thread->isolate() == isolate);
|
||||
|
@ -304,48 +300,10 @@ void Thread::ExitIsolate(bool is_nested_exit) {
|
|||
Isolate* isolate = thread->isolate();
|
||||
thread->set_vm_tag(isolate->is_runnable() ? VMTag::kIdleTagId
|
||||
: VMTag::kLoadWaitTagId);
|
||||
const bool kIsMutatorThread = true;
|
||||
const bool kBypassSafepoint = false;
|
||||
is_nested_exit =
|
||||
is_nested_exit || (isolate->mutator_thread() != nullptr &&
|
||||
isolate->mutator_thread()->top_exit_frame_info() != 0);
|
||||
isolate->UnscheduleThread(thread, kIsMutatorThread, is_nested_exit,
|
||||
kBypassSafepoint);
|
||||
}
|
||||
|
||||
bool Thread::EnterIsolateAsHelper(Isolate* isolate,
|
||||
TaskKind kind,
|
||||
bool bypass_safepoint) {
|
||||
ASSERT(kind != kMutatorTask);
|
||||
const bool kIsMutatorThread = false;
|
||||
const bool kIsNestedReenter = false;
|
||||
Thread* thread = isolate->ScheduleThread(kIsMutatorThread, kIsNestedReenter,
|
||||
bypass_safepoint);
|
||||
if (thread != nullptr) {
|
||||
ASSERT(!thread->IsMutatorThread());
|
||||
ASSERT(thread->isolate() == isolate);
|
||||
ASSERT(thread->isolate_group() == isolate->group());
|
||||
thread->FinishEntering(kind);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void Thread::ExitIsolateAsHelper(bool bypass_safepoint) {
|
||||
Thread* thread = Thread::Current();
|
||||
ASSERT(thread != nullptr);
|
||||
ASSERT(!thread->IsMutatorThread());
|
||||
ASSERT(thread->isolate() != nullptr);
|
||||
ASSERT(thread->isolate_group() != nullptr);
|
||||
|
||||
thread->PrepareLeaving();
|
||||
|
||||
Isolate* isolate = thread->isolate();
|
||||
ASSERT(isolate != nullptr);
|
||||
const bool kIsMutatorThread = false;
|
||||
const bool kIsNestedExit = false;
|
||||
isolate->UnscheduleThread(thread, kIsMutatorThread, kIsNestedExit,
|
||||
bypass_safepoint);
|
||||
isolate->UnscheduleThread(thread, is_nested_exit);
|
||||
}
|
||||
|
||||
bool Thread::EnterIsolateGroupAsHelper(IsolateGroup* isolate_group,
|
||||
|
@ -452,7 +410,7 @@ ErrorPtr Thread::HandleInterrupts() {
|
|||
|
||||
#if !defined(PRODUCT)
|
||||
if (isolate()->TakeHasCompletedBlocks()) {
|
||||
Profiler::ProcessCompletedBlocks(this);
|
||||
Profiler::ProcessCompletedBlocks(isolate());
|
||||
}
|
||||
#endif // !defined(PRODUCT)
|
||||
|
||||
|
|
|
@ -362,15 +362,6 @@ class Thread : public ThreadState {
|
|||
// Makes the current thread exit its isolate.
|
||||
static void ExitIsolate(bool is_nested_exit = false);
|
||||
|
||||
// A VM thread other than the main mutator thread can enter an isolate as a
|
||||
// "helper" to gain limited concurrent access to the isolate. One example is
|
||||
// SweeperTask (which uses the class table, which is copy-on-write).
|
||||
// TODO(koda): Properly synchronize heap access to expand allowed operations.
|
||||
static bool EnterIsolateAsHelper(Isolate* isolate,
|
||||
TaskKind kind,
|
||||
bool bypass_safepoint = false);
|
||||
static void ExitIsolateAsHelper(bool bypass_safepoint = false);
|
||||
|
||||
static bool EnterIsolateGroupAsHelper(IsolateGroup* isolate_group,
|
||||
TaskKind kind,
|
||||
bool bypass_safepoint);
|
||||
|
|
|
@ -112,13 +112,18 @@ class ObjectCounter : public ObjectPointerVisitor {
|
|||
|
||||
class TaskWithZoneAllocation : public ThreadPool::Task {
|
||||
public:
|
||||
TaskWithZoneAllocation(Isolate* isolate,
|
||||
TaskWithZoneAllocation(IsolateGroup* isolate_group,
|
||||
Monitor* monitor,
|
||||
bool* done,
|
||||
intptr_t id)
|
||||
: isolate_(isolate), monitor_(monitor), done_(done), id_(id) {}
|
||||
: isolate_group_(isolate_group),
|
||||
monitor_(monitor),
|
||||
done_(done),
|
||||
id_(id) {}
|
||||
virtual void Run() {
|
||||
Thread::EnterIsolateAsHelper(isolate_, Thread::kUnknownTask);
|
||||
const bool kBypassSafepoint = false;
|
||||
Thread::EnterIsolateGroupAsHelper(isolate_group_, Thread::kUnknownTask,
|
||||
kBypassSafepoint);
|
||||
{
|
||||
Thread* thread = Thread::Current();
|
||||
// Create a zone (which is also a stack resource) and exercise it a bit.
|
||||
|
@ -140,7 +145,7 @@ class TaskWithZoneAllocation : public ThreadPool::Task {
|
|||
EXPECT(smi.Value() == unique_smi);
|
||||
{
|
||||
HeapIterationScope iteration(thread);
|
||||
ObjectCounter counter(isolate_->group(), &smi);
|
||||
ObjectCounter counter(isolate_group_, &smi);
|
||||
// Ensure that our particular zone is visited.
|
||||
iteration.IterateStackPointers(&counter,
|
||||
ValidationPolicy::kValidateFrames);
|
||||
|
@ -157,7 +162,7 @@ class TaskWithZoneAllocation : public ThreadPool::Task {
|
|||
EXPECT(unique_str.Equals(unique_chars));
|
||||
{
|
||||
HeapIterationScope iteration(thread);
|
||||
ObjectCounter str_counter(isolate_->group(), &unique_str);
|
||||
ObjectCounter str_counter(isolate_group_, &unique_str);
|
||||
// Ensure that our particular zone is visited.
|
||||
iteration.IterateStackPointers(&str_counter,
|
||||
ValidationPolicy::kValidateFrames);
|
||||
|
@ -165,7 +170,7 @@ class TaskWithZoneAllocation : public ThreadPool::Task {
|
|||
EXPECT_EQ(1, str_counter.count());
|
||||
}
|
||||
}
|
||||
Thread::ExitIsolateAsHelper();
|
||||
Thread::ExitIsolateGroupAsHelper(kBypassSafepoint);
|
||||
{
|
||||
MonitorLocker ml(monitor_);
|
||||
*done_ = true;
|
||||
|
@ -174,7 +179,7 @@ class TaskWithZoneAllocation : public ThreadPool::Task {
|
|||
}
|
||||
|
||||
private:
|
||||
Isolate* isolate_;
|
||||
IsolateGroup* isolate_group_;
|
||||
Monitor* monitor_;
|
||||
bool* done_;
|
||||
intptr_t id_;
|
||||
|
@ -184,10 +189,11 @@ ISOLATE_UNIT_TEST_CASE(ManyTasksWithZones) {
|
|||
const int kTaskCount = 100;
|
||||
Monitor sync[kTaskCount];
|
||||
bool done[kTaskCount];
|
||||
Isolate* isolate = thread->isolate();
|
||||
auto isolate = thread->isolate();
|
||||
auto isolate_group = thread->isolate_group();
|
||||
for (int i = 0; i < kTaskCount; i++) {
|
||||
done[i] = false;
|
||||
Dart::thread_pool()->Run<TaskWithZoneAllocation>(isolate, &sync[i],
|
||||
Dart::thread_pool()->Run<TaskWithZoneAllocation>(isolate_group, &sync[i],
|
||||
&done[i], i);
|
||||
}
|
||||
bool in_isolate = true;
|
||||
|
@ -220,14 +226,14 @@ ISOLATE_UNIT_TEST_CASE(ManyTasksWithZones) {
|
|||
class SimpleTaskWithZoneAllocation : public ThreadPool::Task {
|
||||
public:
|
||||
SimpleTaskWithZoneAllocation(intptr_t id,
|
||||
Isolate* isolate,
|
||||
IsolateGroup* isolate_group,
|
||||
Thread** thread_ptr,
|
||||
Monitor* sync,
|
||||
Monitor* monitor,
|
||||
intptr_t* done_count,
|
||||
bool* wait)
|
||||
: id_(id),
|
||||
isolate_(isolate),
|
||||
isolate_group_(isolate_group),
|
||||
thread_ptr_(thread_ptr),
|
||||
sync_(sync),
|
||||
monitor_(monitor),
|
||||
|
@ -235,13 +241,15 @@ class SimpleTaskWithZoneAllocation : public ThreadPool::Task {
|
|||
wait_(wait) {}
|
||||
|
||||
virtual void Run() {
|
||||
Thread::EnterIsolateAsHelper(isolate_, Thread::kUnknownTask);
|
||||
const bool kBypassSafepoint = false;
|
||||
Thread::EnterIsolateGroupAsHelper(isolate_group_, Thread::kUnknownTask,
|
||||
kBypassSafepoint);
|
||||
{
|
||||
Thread* thread = Thread::Current();
|
||||
*thread_ptr_ = thread;
|
||||
CreateStackZones(id_);
|
||||
}
|
||||
Thread::ExitIsolateAsHelper();
|
||||
Thread::ExitIsolateGroupAsHelper(kBypassSafepoint);
|
||||
// Notify the main thread that this thread has exited.
|
||||
{
|
||||
MonitorLocker ml(monitor_);
|
||||
|
@ -288,7 +296,7 @@ class SimpleTaskWithZoneAllocation : public ThreadPool::Task {
|
|||
}
|
||||
|
||||
intptr_t id_;
|
||||
Isolate* isolate_;
|
||||
IsolateGroup* isolate_group_;
|
||||
Thread** thread_ptr_;
|
||||
Monitor* sync_;
|
||||
Monitor* monitor_;
|
||||
|
@ -301,7 +309,7 @@ ISOLATE_UNIT_TEST_CASE(ManySimpleTasksWithZones) {
|
|||
Monitor monitor;
|
||||
Monitor sync;
|
||||
Thread* threads[kTaskCount];
|
||||
Isolate* isolate = Thread::Current()->isolate();
|
||||
auto isolate_group = thread->isolate_group();
|
||||
intptr_t done_count = 0;
|
||||
bool wait = true;
|
||||
|
||||
|
@ -311,7 +319,8 @@ ISOLATE_UNIT_TEST_CASE(ManySimpleTasksWithZones) {
|
|||
|
||||
for (intptr_t i = 0; i < kTaskCount; i++) {
|
||||
Dart::thread_pool()->Run<SimpleTaskWithZoneAllocation>(
|
||||
(i + 1), isolate, &threads[i], &sync, &monitor, &done_count, &wait);
|
||||
(i + 1), isolate_group, &threads[i], &sync, &monitor, &done_count,
|
||||
&wait);
|
||||
}
|
||||
// Wait until all spawned tasks finish their memory operations.
|
||||
{
|
||||
|
@ -371,12 +380,12 @@ class ICDataTestTask : public ThreadPool::Task {
|
|||
public:
|
||||
static constexpr intptr_t kTaskCount = 1;
|
||||
|
||||
ICDataTestTask(Isolate* isolate,
|
||||
ICDataTestTask(IsolateGroup* isolate_group,
|
||||
const Array& ic_datas,
|
||||
Monitor* monitor,
|
||||
intptr_t* exited,
|
||||
std::atomic<bool>* done)
|
||||
: isolate_(isolate),
|
||||
: isolate_group_(isolate_group),
|
||||
ic_datas_(ic_datas),
|
||||
len_(ic_datas.Length()),
|
||||
monitor_(monitor),
|
||||
|
@ -384,7 +393,9 @@ class ICDataTestTask : public ThreadPool::Task {
|
|||
done_(done) {}
|
||||
|
||||
virtual void Run() {
|
||||
Thread::EnterIsolateAsHelper(isolate_, Thread::kUnknownTask);
|
||||
const bool kBypassSafepoint = false;
|
||||
Thread::EnterIsolateGroupAsHelper(isolate_group_, Thread::kUnknownTask,
|
||||
kBypassSafepoint);
|
||||
|
||||
Thread* thread = Thread::Current();
|
||||
|
||||
|
@ -414,7 +425,7 @@ class ICDataTestTask : public ThreadPool::Task {
|
|||
}
|
||||
}
|
||||
|
||||
Thread::ExitIsolateAsHelper();
|
||||
Thread::ExitIsolateGroupAsHelper(kBypassSafepoint);
|
||||
{
|
||||
MonitorLocker ml(monitor_);
|
||||
++*exited_;
|
||||
|
@ -423,7 +434,7 @@ class ICDataTestTask : public ThreadPool::Task {
|
|||
}
|
||||
|
||||
private:
|
||||
Isolate* isolate_;
|
||||
IsolateGroup* isolate_group_;
|
||||
const Array& ic_datas_;
|
||||
const intptr_t len_;
|
||||
Monitor* monitor_;
|
||||
|
@ -450,8 +461,8 @@ static Function* CreateFunction(const char* name) {
|
|||
// Test that checks that other threads only see a fully initialized ICData
|
||||
// whenever ICData is updated.
|
||||
ISOLATE_UNIT_TEST_CASE(ICDataTest) {
|
||||
Isolate* isolate = thread->isolate();
|
||||
USE(isolate);
|
||||
auto isolate_group = thread->isolate_group();
|
||||
USE(isolate_group);
|
||||
Monitor monitor;
|
||||
intptr_t exited = 0;
|
||||
std::atomic<bool> done = {false};
|
||||
|
@ -472,7 +483,7 @@ ISOLATE_UNIT_TEST_CASE(ICDataTest) {
|
|||
}
|
||||
|
||||
for (int i = 0; i < ICDataTestTask::kTaskCount; i++) {
|
||||
Dart::thread_pool()->Run<ICDataTestTask>(isolate, ic_datas, &monitor,
|
||||
Dart::thread_pool()->Run<ICDataTestTask>(isolate_group, ic_datas, &monitor,
|
||||
&exited, &done);
|
||||
}
|
||||
|
||||
|
@ -524,7 +535,9 @@ class SafepointTestTask : public ThreadPool::Task {
|
|||
local_done_(false) {}
|
||||
|
||||
virtual void Run() {
|
||||
Thread::EnterIsolateAsHelper(isolate_, Thread::kUnknownTask);
|
||||
const bool kBypassSafepoint = false;
|
||||
Thread::EnterIsolateGroupAsHelper(isolate_->group(), Thread::kUnknownTask,
|
||||
kBypassSafepoint);
|
||||
{
|
||||
MonitorLocker ml(monitor_);
|
||||
++*expected_count_;
|
||||
|
@ -573,7 +586,7 @@ class SafepointTestTask : public ThreadPool::Task {
|
|||
}
|
||||
}
|
||||
}
|
||||
Thread::ExitIsolateAsHelper();
|
||||
Thread::ExitIsolateGroupAsHelper(kBypassSafepoint);
|
||||
{
|
||||
MonitorLocker ml(monitor_);
|
||||
++*exited_;
|
||||
|
@ -837,20 +850,24 @@ ISOLATE_UNIT_TEST_CASE(RecursiveSafepointTest2) {
|
|||
|
||||
class AllocAndGCTask : public ThreadPool::Task {
|
||||
public:
|
||||
AllocAndGCTask(Isolate* isolate, Monitor* done_monitor, bool* done)
|
||||
: isolate_(isolate), done_monitor_(done_monitor), done_(done) {}
|
||||
AllocAndGCTask(IsolateGroup* isolate_group, Monitor* done_monitor, bool* done)
|
||||
: isolate_group_(isolate_group),
|
||||
done_monitor_(done_monitor),
|
||||
done_(done) {}
|
||||
|
||||
virtual void Run() {
|
||||
Thread::EnterIsolateAsHelper(isolate_, Thread::kUnknownTask);
|
||||
const bool kBypassSafepoint = false;
|
||||
Thread::EnterIsolateGroupAsHelper(isolate_group_, Thread::kUnknownTask,
|
||||
kBypassSafepoint);
|
||||
{
|
||||
Thread* thread = Thread::Current();
|
||||
StackZone stack_zone(thread);
|
||||
Zone* zone = stack_zone.GetZone();
|
||||
String& old_str = String::Handle(zone, String::New("old", Heap::kOld));
|
||||
isolate_->group()->heap()->CollectAllGarbage();
|
||||
isolate_group_->heap()->CollectAllGarbage();
|
||||
EXPECT(old_str.Equals("old"));
|
||||
}
|
||||
Thread::ExitIsolateAsHelper();
|
||||
Thread::ExitIsolateGroupAsHelper(kBypassSafepoint);
|
||||
// Tell main thread that we are ready.
|
||||
{
|
||||
MonitorLocker ml(done_monitor_);
|
||||
|
@ -861,7 +878,7 @@ class AllocAndGCTask : public ThreadPool::Task {
|
|||
}
|
||||
|
||||
private:
|
||||
Isolate* isolate_;
|
||||
IsolateGroup* isolate_group_;
|
||||
Monitor* done_monitor_;
|
||||
bool* done_;
|
||||
};
|
||||
|
@ -869,8 +886,8 @@ class AllocAndGCTask : public ThreadPool::Task {
|
|||
ISOLATE_UNIT_TEST_CASE(HelperAllocAndGC) {
|
||||
Monitor done_monitor;
|
||||
bool done = false;
|
||||
Isolate* isolate = thread->isolate();
|
||||
Dart::thread_pool()->Run<AllocAndGCTask>(isolate, &done_monitor, &done);
|
||||
auto isolate_group = thread->isolate_group();
|
||||
Dart::thread_pool()->Run<AllocAndGCTask>(isolate_group, &done_monitor, &done);
|
||||
{
|
||||
while (true) {
|
||||
TransitionVMToBlocked transition(thread);
|
||||
|
@ -884,11 +901,17 @@ ISOLATE_UNIT_TEST_CASE(HelperAllocAndGC) {
|
|||
|
||||
class AllocateGlobsOfMemoryTask : public ThreadPool::Task {
|
||||
public:
|
||||
AllocateGlobsOfMemoryTask(Isolate* isolate, Monitor* done_monitor, bool* done)
|
||||
: isolate_(isolate), done_monitor_(done_monitor), done_(done) {}
|
||||
AllocateGlobsOfMemoryTask(IsolateGroup* isolate_group,
|
||||
Monitor* done_monitor,
|
||||
bool* done)
|
||||
: isolate_group_(isolate_group),
|
||||
done_monitor_(done_monitor),
|
||||
done_(done) {}
|
||||
|
||||
virtual void Run() {
|
||||
Thread::EnterIsolateAsHelper(isolate_, Thread::kUnknownTask);
|
||||
const bool kBypassSafepoint = false;
|
||||
Thread::EnterIsolateGroupAsHelper(isolate_group_, Thread::kUnknownTask,
|
||||
kBypassSafepoint);
|
||||
{
|
||||
Thread* thread = Thread::Current();
|
||||
StackZone stack_zone(thread);
|
||||
|
@ -898,7 +921,7 @@ class AllocateGlobsOfMemoryTask : public ThreadPool::Task {
|
|||
String::Handle(zone, String::New("abc"));
|
||||
}
|
||||
}
|
||||
Thread::ExitIsolateAsHelper();
|
||||
Thread::ExitIsolateGroupAsHelper(kBypassSafepoint);
|
||||
// Tell main thread that we are ready.
|
||||
{
|
||||
MonitorLocker ml(done_monitor_);
|
||||
|
@ -909,7 +932,7 @@ class AllocateGlobsOfMemoryTask : public ThreadPool::Task {
|
|||
}
|
||||
|
||||
private:
|
||||
Isolate* isolate_;
|
||||
IsolateGroup* isolate_group_;
|
||||
Monitor* done_monitor_;
|
||||
bool* done_;
|
||||
};
|
||||
|
@ -918,11 +941,11 @@ ISOLATE_UNIT_TEST_CASE(ExerciseTLABs) {
|
|||
const int NUMBER_TEST_THREADS = 10;
|
||||
Monitor done_monitor[NUMBER_TEST_THREADS];
|
||||
bool done[NUMBER_TEST_THREADS];
|
||||
Isolate* isolate = thread->isolate();
|
||||
auto isolate_group = thread->isolate_group();
|
||||
for (int i = 0; i < NUMBER_TEST_THREADS; i++) {
|
||||
done[i] = false;
|
||||
Dart::thread_pool()->Run<AllocateGlobsOfMemoryTask>(
|
||||
isolate, &done_monitor[i], &done[i]);
|
||||
isolate_group, &done_monitor[i], &done[i]);
|
||||
}
|
||||
|
||||
for (int i = 0; i < NUMBER_TEST_THREADS; i++) {
|
||||
|
|
Loading…
Reference in a new issue