| OLD | NEW |
| 1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #include "vm/thread.h" | 5 #include "vm/thread.h" |
| 6 | 6 |
| 7 #include "vm/growable_array.h" | 7 #include "vm/growable_array.h" |
| 8 #include "vm/isolate.h" | 8 #include "vm/isolate.h" |
| 9 #include "vm/lockers.h" | 9 #include "vm/lockers.h" |
| 10 #include "vm/log.h" | 10 #include "vm/log.h" |
| (...skipping 205 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 216 thread->Schedule(isolate); | 216 thread->Schedule(isolate); |
| 217 // TODO(koda): Migrate profiler interface to use Thread. | 217 // TODO(koda): Migrate profiler interface to use Thread. |
| 218 Profiler::BeginExecution(isolate); | 218 Profiler::BeginExecution(isolate); |
| 219 } | 219 } |
| 220 | 220 |
| 221 | 221 |
| 222 void Thread::ExitIsolate() { | 222 void Thread::ExitIsolate() { |
| 223 Thread* thread = Thread::Current(); | 223 Thread* thread = Thread::Current(); |
| 224 // TODO(koda): Audit callers; they should know whether they're in an isolate. | 224 // TODO(koda): Audit callers; they should know whether they're in an isolate. |
| 225 if (thread == NULL || thread->isolate() == NULL) return; | 225 if (thread == NULL || thread->isolate() == NULL) return; |
| 226 #if defined(DEBUG) |
| 227 ASSERT(!thread->IsAnyReusableHandleScopeActive()); |
| 228 #endif // DEBUG |
| 229 // Clear since GC will not visit the thread once it is unscheduled. |
| 230 thread->ClearReusableHandles(); |
| 226 Isolate* isolate = thread->isolate(); | 231 Isolate* isolate = thread->isolate(); |
| 227 Profiler::EndExecution(isolate); | 232 Profiler::EndExecution(isolate); |
| 228 thread->Unschedule(); | 233 thread->Unschedule(); |
| 229 // TODO(koda): Move store_buffer_block_ into State. | 234 // TODO(koda): Move store_buffer_block_ into State. |
| 230 thread->StoreBufferRelease(); | 235 thread->StoreBufferRelease(); |
| 231 if (isolate->is_runnable()) { | 236 if (isolate->is_runnable()) { |
| 232 thread->set_vm_tag(VMTag::kIdleTagId); | 237 thread->set_vm_tag(VMTag::kIdleTagId); |
| 233 } else { | 238 } else { |
| 234 thread->set_vm_tag(VMTag::kLoadWaitTagId); | 239 thread->set_vm_tag(VMTag::kLoadWaitTagId); |
| 235 } | 240 } |
| 236 isolate->ClearMutatorThread(); | 241 isolate->ClearMutatorThread(); |
| 237 thread->isolate_ = NULL; | 242 thread->isolate_ = NULL; |
| 238 ASSERT(Isolate::Current() == NULL); | 243 ASSERT(Isolate::Current() == NULL); |
| 239 thread->heap_ = NULL; | 244 thread->heap_ = NULL; |
| 240 #if defined(DEBUG) | |
| 241 ASSERT(!thread->IsAnyReusableHandleScopeActive()); | |
| 242 #endif // DEBUG | |
| 243 } | 245 } |
| 244 | 246 |
| 245 | 247 |
| 246 void Thread::EnterIsolateAsHelper(Isolate* isolate, bool bypass_safepoint) { | 248 void Thread::EnterIsolateAsHelper(Isolate* isolate, bool bypass_safepoint) { |
| 247 Thread* thread = Thread::Current(); | 249 Thread* thread = Thread::Current(); |
| 248 ASSERT(thread != NULL); | 250 ASSERT(thread != NULL); |
| 249 ASSERT(thread->isolate() == NULL); | 251 ASSERT(thread->isolate() == NULL); |
| 250 thread->isolate_ = isolate; | 252 thread->isolate_ = isolate; |
| 251 ASSERT(thread->store_buffer_block_ == NULL); | 253 ASSERT(thread->store_buffer_block_ == NULL); |
| 252 // TODO(koda): Use StoreBufferAcquire once we properly flush before Scavenge. | 254 // TODO(koda): Use StoreBufferAcquire once we properly flush before Scavenge. |
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 341 | 343 |
| 342 | 344 |
| 343 template<class C> | 345 template<class C> |
| 344 C* Thread::AllocateReusableHandle() { | 346 C* Thread::AllocateReusableHandle() { |
| 345 C* handle = reinterpret_cast<C*>(reusable_handles_.AllocateScopedHandle()); | 347 C* handle = reinterpret_cast<C*>(reusable_handles_.AllocateScopedHandle()); |
| 346 C::initializeHandle(handle, C::null()); | 348 C::initializeHandle(handle, C::null()); |
| 347 return handle; | 349 return handle; |
| 348 } | 350 } |
| 349 | 351 |
| 350 | 352 |
| 353 void Thread::ClearReusableHandles() { |
| 354 #define CLEAR_REUSABLE_HANDLE(object) \ |
| 355 *object##_handle_ = object::null(); |
| 356 REUSABLE_HANDLE_LIST(CLEAR_REUSABLE_HANDLE) |
| 357 #undef CLEAR_REUSABLE_HANDLE |
| 358 } |
| 359 |
| 360 |
| 351 void Thread::VisitObjectPointers(ObjectPointerVisitor* visitor) { | 361 void Thread::VisitObjectPointers(ObjectPointerVisitor* visitor) { |
| 352 ASSERT(visitor != NULL); | 362 ASSERT(visitor != NULL); |
| 353 | 363 |
| 354 // Visit objects in thread specific handles area. | 364 // Visit objects in thread specific handles area. |
| 355 reusable_handles_.VisitObjectPointers(visitor); | 365 reusable_handles_.VisitObjectPointers(visitor); |
| 356 } | 366 } |
| 357 | 367 |
| 358 | 368 |
| 359 void Thread::SetThreadInterrupter(ThreadInterruptCallback callback, | 369 void Thread::SetThreadInterrupter(ThreadInterruptCallback callback, |
| 360 void* data) { | 370 void* data) { |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 415 return Thread::name##_entry_point_offset(); \ | 425 return Thread::name##_entry_point_offset(); \ |
| 416 } | 426 } |
| 417 LEAF_RUNTIME_ENTRY_LIST(COMPUTE_OFFSET) | 427 LEAF_RUNTIME_ENTRY_LIST(COMPUTE_OFFSET) |
| 418 #undef COMPUTE_OFFSET | 428 #undef COMPUTE_OFFSET |
| 419 | 429 |
| 420 UNREACHABLE(); | 430 UNREACHABLE(); |
| 421 return -1; | 431 return -1; |
| 422 } | 432 } |
| 423 | 433 |
| 424 } // namespace dart | 434 } // namespace dart |
| OLD | NEW |