Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(53)

Side by Side Diff: runtime/vm/thread.cc

Issue 1293253005: Completely remove InterruptableThreadState and Fix ThreadRegistry leak (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 5 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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/object.h" 10 #include "vm/object.h"
11 #include "vm/os_thread.h" 11 #include "vm/os_thread.h"
12 #include "vm/profiler.h" 12 #include "vm/profiler.h"
13 #include "vm/stub_code.h" 13 #include "vm/stub_code.h"
14 #include "vm/thread_interrupter.h" 14 #include "vm/thread_interrupter.h"
15 #include "vm/thread_registry.h" 15 #include "vm/thread_registry.h"
16 16
17 namespace dart { 17 namespace dart {
18 18
19 // The single thread local key which stores all the thread local data 19 // The single thread local key which stores all the thread local data
20 // for a thread. 20 // for a thread.
21 ThreadLocalKey Thread::thread_key_ = OSThread::kUnsetThreadLocalKey; 21 ThreadLocalKey Thread::thread_key_ = OSThread::kUnsetThreadLocalKey;
22 22
23 23
24 // Remove |thread| from all isolate's thread registry.
koda 2015/08/20 14:55:53 (I'm not a native speaker, but shouldn't this be e
Cutch 2015/08/20 20:40:19 Done.
25 class ThreadPruner : public IsolateVisitor {
26 public:
27 explicit ThreadPruner(Thread* thread)
28 : thread_(thread) {
29 ASSERT(thread_ != NULL);
30 }
31
32 void VisitIsolate(Isolate* isolate) {
33 ThreadRegistry* registry = isolate->thread_registry();
34 ASSERT(registry != NULL);
35 registry->PruneThread(thread_);
36 }
37 private:
38 Thread* thread_;
39 };
40
41
24 static void DeleteThread(void* thread) { 42 static void DeleteThread(void* thread) {
25 delete reinterpret_cast<Thread*>(thread); 43 delete reinterpret_cast<Thread*>(thread);
26 } 44 }
27 45
28 46
29 Thread::~Thread() { 47 Thread::~Thread() {
30 // We should cleanly exit any isolate before destruction. 48 // We should cleanly exit any isolate before destruction.
31 ASSERT(isolate_ == NULL); 49 ASSERT(isolate_ == NULL);
50 // Clear |this| from all isolate's thread registry.
51 ThreadPruner pruner(this);
52 Isolate::VisitIsolates(&pruner);
32 } 53 }
33 54
34 55
35 void Thread::InitOnceBeforeIsolate() { 56 void Thread::InitOnceBeforeIsolate() {
36 ASSERT(thread_key_ == OSThread::kUnsetThreadLocalKey); 57 ASSERT(thread_key_ == OSThread::kUnsetThreadLocalKey);
37 thread_key_ = OSThread::CreateThreadLocal(DeleteThread); 58 thread_key_ = OSThread::CreateThreadLocal(DeleteThread);
38 ASSERT(thread_key_ != OSThread::kUnsetThreadLocalKey); 59 ASSERT(thread_key_ != OSThread::kUnsetThreadLocalKey);
39 ASSERT(Thread::Current() == NULL); 60 ASSERT(Thread::Current() == NULL);
40 // Postpone initialization of VM constants for this first thread. 61 // Postpone initialization of VM constants for this first thread.
41 SetCurrent(new Thread(false)); 62 SetCurrent(new Thread(false));
(...skipping 25 matching lines...) Expand all
67 Thread* current = Current(); 88 Thread* current = Current();
68 if (current != NULL) { 89 if (current != NULL) {
69 delete current; 90 delete current;
70 } 91 }
71 SetCurrent(NULL); 92 SetCurrent(NULL);
72 } 93 }
73 #endif 94 #endif
74 95
75 96
76 Thread::Thread(bool init_vm_constants) 97 Thread::Thread(bool init_vm_constants)
77 : isolate_(NULL), 98 : id_(OSThread::GetCurrentThreadId()),
koda 2015/08/20 14:55:53 This should be in the same place as the call to Se
Cutch 2015/08/20 20:40:19 As discussed. I've moved the SetCurrent call into
99 isolate_(NULL),
78 store_buffer_block_(NULL) { 100 store_buffer_block_(NULL) {
79 ClearState(); 101 ClearState();
80 #define DEFAULT_INIT(type_name, member_name, init_expr, default_init_value) \ 102 #define DEFAULT_INIT(type_name, member_name, init_expr, default_init_value) \
81 member_name = default_init_value; 103 member_name = default_init_value;
82 CACHED_CONSTANTS_LIST(DEFAULT_INIT) 104 CACHED_CONSTANTS_LIST(DEFAULT_INIT)
83 #undef DEFAULT_INIT 105 #undef DEFAULT_INIT
84 if (init_vm_constants) { 106 if (init_vm_constants) {
85 InitVMConstants(); 107 InitVMConstants();
86 } 108 }
87 } 109 }
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
124 ASSERT(thread->isolate() == NULL); 146 ASSERT(thread->isolate() == NULL);
125 ASSERT(!isolate->HasMutatorThread()); 147 ASSERT(!isolate->HasMutatorThread());
126 thread->isolate_ = isolate; 148 thread->isolate_ = isolate;
127 isolate->MakeCurrentThreadMutator(thread); 149 isolate->MakeCurrentThreadMutator(thread);
128 isolate->set_vm_tag(VMTag::kVMTagId); 150 isolate->set_vm_tag(VMTag::kVMTagId);
129 ASSERT(thread->store_buffer_block_ == NULL); 151 ASSERT(thread->store_buffer_block_ == NULL);
130 thread->StoreBufferAcquire(); 152 thread->StoreBufferAcquire();
131 ASSERT(isolate->heap() != NULL); 153 ASSERT(isolate->heap() != NULL);
132 thread->heap_ = isolate->heap(); 154 thread->heap_ = isolate->heap();
133 thread->Schedule(isolate); 155 thread->Schedule(isolate);
134 ASSERT(thread->thread_state() == NULL);
135 InterruptableThreadState* thread_state =
136 ThreadInterrupter::GetCurrentThreadState();
137 #if defined(DEBUG)
138 thread->set_thread_state(NULL); // Exclude thread itself from the dupe check.
139 Isolate::CheckForDuplicateThreadState(thread_state);
140 thread->set_thread_state(thread_state);
141 #endif
142 ASSERT(thread_state != NULL);
143 // TODO(koda): Migrate profiler interface to use Thread. 156 // TODO(koda): Migrate profiler interface to use Thread.
144 Profiler::BeginExecution(isolate); 157 Profiler::BeginExecution(isolate);
145 } 158 }
146 159
147 160
148 void Thread::ExitIsolate() { 161 void Thread::ExitIsolate() {
149 Thread* thread = Thread::Current(); 162 Thread* thread = Thread::Current();
150 // TODO(koda): Audit callers; they should know whether they're in an isolate. 163 // TODO(koda): Audit callers; they should know whether they're in an isolate.
151 if (thread == NULL || thread->isolate() == NULL) return; 164 if (thread == NULL || thread->isolate() == NULL) return;
152 Isolate* isolate = thread->isolate(); 165 Isolate* isolate = thread->isolate();
153 Profiler::EndExecution(isolate); 166 Profiler::EndExecution(isolate);
154 thread->set_thread_state(NULL);
155 thread->Unschedule(); 167 thread->Unschedule();
156 // TODO(koda): Move store_buffer_block_ into State. 168 // TODO(koda): Move store_buffer_block_ into State.
157 thread->StoreBufferRelease(); 169 thread->StoreBufferRelease();
158 if (isolate->is_runnable()) { 170 if (isolate->is_runnable()) {
159 isolate->set_vm_tag(VMTag::kIdleTagId); 171 isolate->set_vm_tag(VMTag::kIdleTagId);
160 } else { 172 } else {
161 isolate->set_vm_tag(VMTag::kLoadWaitTagId); 173 isolate->set_vm_tag(VMTag::kLoadWaitTagId);
162 } 174 }
163 isolate->ClearMutatorThread(); 175 isolate->ClearMutatorThread();
164 thread->isolate_ = NULL; 176 thread->isolate_ = NULL;
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
252 return isolate_->cha_; 264 return isolate_->cha_;
253 } 265 }
254 266
255 267
256 void Thread::set_cha(CHA* value) { 268 void Thread::set_cha(CHA* value) {
257 ASSERT(isolate_ != NULL); 269 ASSERT(isolate_ != NULL);
258 isolate_->cha_ = value; 270 isolate_->cha_ = value;
259 } 271 }
260 272
261 273
274 void Thread::SetThreadInterrupter(ThreadInterruptCallback callback,
koda 2015/08/20 15:45:14 Consider ASSERT that this is only called on the cu
Cutch 2015/08/20 20:40:18 Done.
275 void* data) {
276 thread_interrupt_callback_ = callback;
koda 2015/08/20 14:55:53 This update is not done atomically. Thus, if we ge
koda 2015/08/20 15:18:33 One way to make the interface safer is to remove t
Cutch 2015/08/20 20:40:18 I've removed the individual accessors. New API: b
277 thread_interrupt_data_ = data;
278 }
279
280
281 bool Thread::ShouldInterrupt() const {
koda 2015/08/20 15:45:14 Consider ASSERT that this is only called on the cu
Cutch 2015/08/20 20:40:19 Done.
282 return (thread_interrupt_data_ != NULL) &&
283 (thread_interrupt_callback_ != NULL);
284 }
285
286
262 bool Thread::CanLoadFromThread(const Object& object) { 287 bool Thread::CanLoadFromThread(const Object& object) {
263 #define CHECK_OBJECT(type_name, member_name, expr, default_init_value) \ 288 #define CHECK_OBJECT(type_name, member_name, expr, default_init_value) \
264 if (object.raw() == expr) return true; 289 if (object.raw() == expr) return true;
265 CACHED_VM_OBJECTS_LIST(CHECK_OBJECT) 290 CACHED_VM_OBJECTS_LIST(CHECK_OBJECT)
266 #undef CHECK_OBJECT 291 #undef CHECK_OBJECT
267 return false; 292 return false;
268 } 293 }
269 294
270 295
271 intptr_t Thread::OffsetFromThread(const Object& object) { 296 intptr_t Thread::OffsetFromThread(const Object& object) {
272 #define COMPUTE_OFFSET(type_name, member_name, expr, default_init_value) \ 297 #define COMPUTE_OFFSET(type_name, member_name, expr, default_init_value) \
273 ASSERT((expr)->IsVMHeapObject()); \ 298 ASSERT((expr)->IsVMHeapObject()); \
274 if (object.raw() == expr) return Thread::member_name##offset(); 299 if (object.raw() == expr) return Thread::member_name##offset();
275 CACHED_VM_OBJECTS_LIST(COMPUTE_OFFSET) 300 CACHED_VM_OBJECTS_LIST(COMPUTE_OFFSET)
276 #undef COMPUTE_OFFSET 301 #undef COMPUTE_OFFSET
277 UNREACHABLE(); 302 UNREACHABLE();
278 return -1; 303 return -1;
279 } 304 }
280 305
281 } // namespace dart 306 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698