Index: runtime/vm/thread.cc |
diff --git a/runtime/vm/thread.cc b/runtime/vm/thread.cc |
index c220913101ce0ce6c7ca9523598c376ba17a73a2..adfc4b4ee2bc7baf4f2ab0827e9ed654314a26e9 100644 |
--- a/runtime/vm/thread.cc |
+++ b/runtime/vm/thread.cc |
@@ -41,6 +41,7 @@ Thread::~Thread() { |
Thread::Thread(Isolate* isolate) |
: BaseThread(false), |
os_thread_(NULL), |
+ thread_lock_(new Monitor()), |
isolate_(NULL), |
heap_(NULL), |
zone_(NULL), |
@@ -63,6 +64,8 @@ Thread::Thread(Isolate* isolate) |
pending_functions_(GrowableObjectArray::null()), |
REUSABLE_HANDLE_LIST(REUSABLE_HANDLE_INITIALIZERS) |
REUSABLE_HANDLE_LIST(REUSABLE_HANDLE_SCOPE_INIT) |
+ safepoint_state_(0), |
+ execution_state_(kThreadInVM), |
next_(NULL) { |
#define DEFAULT_INIT(type_name, member_name, init_expr, default_init_value) \ |
member_name = default_init_value; |
@@ -174,13 +177,8 @@ RawGrowableObjectArray* Thread::pending_functions() { |
bool Thread::EnterIsolate(Isolate* isolate) { |
const bool kIsMutatorThread = true; |
- const bool kDontBypassSafepoints = false; |
- ThreadRegistry* tr = isolate->thread_registry(); |
- Thread* thread = tr->Schedule( |
- isolate, kIsMutatorThread, kDontBypassSafepoints); |
+ Thread* thread = isolate->ScheduleThread(kIsMutatorThread); |
if (thread != NULL) { |
- isolate->MakeCurrentThreadMutator(thread); |
- thread->set_vm_tag(VMTag::kVMTagId); |
ASSERT(thread->store_buffer_block_ == NULL); |
thread->StoreBufferAcquire(); |
return true; |
@@ -191,33 +189,29 @@ bool Thread::EnterIsolate(Isolate* isolate) { |
void Thread::ExitIsolate() { |
Thread* thread = Thread::Current(); |
- ASSERT(thread != NULL); |
- ASSERT(thread->IsMutatorThread()); |
-#if defined(DEBUG) |
- ASSERT(!thread->IsAnyReusableHandleScopeActive()); |
-#endif // DEBUG |
+ ASSERT(thread != NULL && thread->IsMutatorThread()); |
+ DEBUG_ASSERT(!thread->IsAnyReusableHandleScopeActive()); |
+ |
+ Isolate* isolate = thread->isolate(); |
+ ASSERT(isolate != NULL); |
+ ASSERT(thread->execution_state() == Thread::kThreadInVM); |
// Clear since GC will not visit the thread once it is unscheduled. |
thread->ClearReusableHandles(); |
thread->StoreBufferRelease(); |
- Isolate* isolate = thread->isolate(); |
- ASSERT(isolate != NULL); |
if (isolate->is_runnable()) { |
thread->set_vm_tag(VMTag::kIdleTagId); |
} else { |
thread->set_vm_tag(VMTag::kLoadWaitTagId); |
} |
const bool kIsMutatorThread = true; |
- const bool kDontBypassSafepoints = false; |
- ThreadRegistry* tr = isolate->thread_registry(); |
- tr->Unschedule(thread, kIsMutatorThread, kDontBypassSafepoints); |
- isolate->ClearMutatorThread(); |
+ isolate->UnscheduleThread(thread, kIsMutatorThread); |
} |
bool Thread::EnterIsolateAsHelper(Isolate* isolate, bool bypass_safepoint) { |
const bool kIsNotMutatorThread = false; |
- ThreadRegistry* tr = isolate->thread_registry(); |
- Thread* thread = tr->Schedule(isolate, kIsNotMutatorThread, bypass_safepoint); |
+ Thread* thread = isolate->ScheduleThread(kIsNotMutatorThread, |
+ bypass_safepoint); |
if (thread != NULL) { |
ASSERT(thread->store_buffer_block_ == NULL); |
// TODO(koda): Use StoreBufferAcquire once we properly flush |
@@ -236,18 +230,19 @@ void Thread::ExitIsolateAsHelper(bool bypass_safepoint) { |
Thread* thread = Thread::Current(); |
ASSERT(thread != NULL); |
ASSERT(!thread->IsMutatorThread()); |
+ ASSERT(thread->execution_state() == Thread::kThreadInVM); |
thread->StoreBufferRelease(); |
Isolate* isolate = thread->isolate(); |
ASSERT(isolate != NULL); |
const bool kIsNotMutatorThread = false; |
- ThreadRegistry* tr = isolate->thread_registry(); |
- tr->Unschedule(thread, kIsNotMutatorThread, bypass_safepoint); |
+ isolate->UnscheduleThread(thread, kIsNotMutatorThread, bypass_safepoint); |
} |
void Thread::PrepareForGC() { |
- ASSERT(isolate()->thread_registry()->AtSafepoint()); |
+ ASSERT(IsAtSafepoint()); |
// Prevent scheduling another GC by ignoring the threshold. |
+ ASSERT(store_buffer_block_ != NULL); |
StoreBufferRelease(StoreBuffer::kIgnoreThreshold); |
// Make sure to get an *empty* block; the isolate needs all entries |
// at GC time. |
@@ -299,9 +294,7 @@ bool Thread::CanCollectGarbage() const { |
// We have non mutator threads grow the heap instead of triggering |
// a garbage collection when they are at a safepoint (e.g: background |
// compiler thread finalizing and installing code at a safepoint). |
- // Note: This code will change once the new Safepoint logic is in place. |
- return (IsMutatorThread() || |
- (isolate_ != NULL && !isolate_->thread_registry()->AtSafepoint())); |
+ return (IsMutatorThread() || IsAtSafepoint()); |
} |
@@ -454,6 +447,21 @@ void Thread::UnwindScopes(uword stack_marker) { |
} |
+void Thread::EnterSafepointUsingLock() { |
+ isolate()->safepoint_handler()->EnterSafepointUsingLock(this); |
+} |
+ |
+ |
+void Thread::ExitSafepointUsingLock() { |
+ isolate()->safepoint_handler()->ExitSafepointUsingLock(this); |
+} |
+ |
+ |
+void Thread::BlockForSafepoint() { |
+ isolate()->safepoint_handler()->BlockForSafepoint(this); |
+} |
+ |
+ |
DisableThreadInterruptsScope::DisableThreadInterruptsScope(Thread* thread) |
: StackResource(thread) { |
if (thread != NULL) { |