| Index: runtime/vm/thread.cc
|
| diff --git a/runtime/vm/thread.cc b/runtime/vm/thread.cc
|
| index 0828f4058dcb31970f475691fa2038398e08b48e..9f08a73e107e21bae928e2c1fd2cd879346c8885 100644
|
| --- a/runtime/vm/thread.cc
|
| +++ b/runtime/vm/thread.cc
|
| @@ -105,6 +105,16 @@ void Thread::CleanUp() {
|
| }
|
| #endif
|
|
|
| +#if defined(DEBUG)
|
| +#define REUSABLE_HANDLE_SCOPE_INIT(object) \
|
| + reusable_##object##_handle_scope_active_(false),
|
| +#else
|
| +#define REUSABLE_HANDLE_SCOPE_INIT(object)
|
| +#endif // defined(DEBUG)
|
| +
|
| +#define REUSABLE_HANDLE_INITIALIZERS(object) \
|
| + object##_handle_(NULL),
|
| +
|
|
|
| Thread::Thread(bool init_vm_constants)
|
| : id_(OSThread::GetCurrentThreadId()),
|
| @@ -114,7 +124,10 @@ Thread::Thread(bool init_vm_constants)
|
| heap_(NULL),
|
| store_buffer_block_(NULL),
|
| log_(new class Log()),
|
| - vm_tag_(0) {
|
| + vm_tag_(0),
|
| + REUSABLE_HANDLE_LIST(REUSABLE_HANDLE_INITIALIZERS)
|
| + REUSABLE_HANDLE_LIST(REUSABLE_HANDLE_SCOPE_INIT)
|
| + reusable_handles_() {
|
| ClearState();
|
|
|
| #define DEFAULT_INIT(type_name, member_name, init_expr, default_init_value) \
|
| @@ -162,6 +175,12 @@ RUNTIME_ENTRY_LIST(INIT_VALUE)
|
| name##_entry_point_ = k##name##RuntimeEntry.GetEntryPoint();
|
| LEAF_RUNTIME_ENTRY_LIST(INIT_VALUE)
|
| #undef INIT_VALUE
|
| +
|
| + // Setup the thread specific reusable handles.
|
| +#define REUSABLE_HANDLE_ALLOCATION(object) \
|
| + this->object##_handle_ = this->AllocateReusableHandle<object>();
|
| + REUSABLE_HANDLE_LIST(REUSABLE_HANDLE_ALLOCATION)
|
| +#undef REUSABLE_HANDLE_ALLOCATION
|
| }
|
|
|
|
|
| @@ -218,6 +237,9 @@ void Thread::ExitIsolate() {
|
| thread->isolate_ = NULL;
|
| ASSERT(Isolate::Current() == NULL);
|
| thread->heap_ = NULL;
|
| +#if defined(DEBUG)
|
| + ASSERT(!thread->IsAnyReusableHandleScopeActive());
|
| +#endif // DEBUG
|
| }
|
|
|
|
|
| @@ -318,6 +340,22 @@ Log* Thread::log() const {
|
| }
|
|
|
|
|
| +template<class C>
|
| +C* Thread::AllocateReusableHandle() {
|
| + C* handle = reinterpret_cast<C*>(reusable_handles_.AllocateScopedHandle());
|
| + C::initializeHandle(handle, C::null());
|
| + return handle;
|
| +}
|
| +
|
| +
|
| +void Thread::VisitObjectPointers(ObjectPointerVisitor* visitor) {
|
| + ASSERT(visitor != NULL);
|
| +
|
| + // Visit objects in thread specific handles area.
|
| + reusable_handles_.VisitObjectPointers(visitor);
|
| +}
|
| +
|
| +
|
| void Thread::SetThreadInterrupter(ThreadInterruptCallback callback,
|
| void* data) {
|
| ASSERT(Thread::Current() == this);
|
|
|