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

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

Issue 1294823004: Fix almost all leaks of InterruptableThreadState instances. (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
« no previous file with comments | « runtime/vm/thread.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 static void DeleteThread(void* thread) { 24 static void DeleteThread(void* thread) {
25 delete reinterpret_cast<Thread*>(thread); 25 delete reinterpret_cast<Thread*>(thread);
26 } 26 }
27 27
28 28
29 Thread::~Thread() { 29 Thread::~Thread() {
30 delete thread_state_;
30 // We should cleanly exit any isolate before destruction. 31 // We should cleanly exit any isolate before destruction.
31 ASSERT(isolate_ == NULL); 32 ASSERT(isolate_ == NULL);
32 } 33 }
33 34
34 35
35 void Thread::InitOnceBeforeIsolate() { 36 void Thread::InitOnceBeforeIsolate() {
36 ASSERT(thread_key_ == OSThread::kUnsetThreadLocalKey); 37 ASSERT(thread_key_ == OSThread::kUnsetThreadLocalKey);
37 thread_key_ = OSThread::CreateThreadLocal(DeleteThread); 38 thread_key_ = OSThread::CreateThreadLocal(DeleteThread);
38 ASSERT(thread_key_ != OSThread::kUnsetThreadLocalKey); 39 ASSERT(thread_key_ != OSThread::kUnsetThreadLocalKey);
39 ASSERT(Thread::Current() == NULL); 40 ASSERT(Thread::Current() == NULL);
(...skipping 11 matching lines...) Expand all
51 52
52 53
53 void Thread::SetCurrent(Thread* current) { 54 void Thread::SetCurrent(Thread* current) {
54 OSThread::SetThreadLocal(thread_key_, reinterpret_cast<uword>(current)); 55 OSThread::SetThreadLocal(thread_key_, reinterpret_cast<uword>(current));
55 } 56 }
56 57
57 58
58 void Thread::EnsureInit() { 59 void Thread::EnsureInit() {
59 if (Thread::Current() == NULL) { 60 if (Thread::Current() == NULL) {
60 SetCurrent(new Thread()); 61 SetCurrent(new Thread());
62 ThreadInterrupter::GetCurrentThreadState();
61 } 63 }
62 } 64 }
63 65
64 66
65 #if defined(TARGET_OS_WINDOWS) 67 #if defined(TARGET_OS_WINDOWS)
66 void Thread::CleanUp() { 68 void Thread::CleanUp() {
67 Thread* current = Current(); 69 Thread* current = Current();
68 if (current != NULL) { 70 if (current != NULL) {
69 delete current; 71 delete current;
70 } 72 }
71 SetCurrent(NULL); 73 SetCurrent(NULL);
72 } 74 }
73 #endif 75 #endif
74 76
75 77
76 Thread::Thread(bool init_vm_constants) 78 Thread::Thread(bool init_vm_constants)
77 : isolate_(NULL), 79 : isolate_(NULL),
78 store_buffer_block_(NULL) { 80 store_buffer_block_(NULL),
81 thread_state_(NULL) {
79 ClearState(); 82 ClearState();
80 #define DEFAULT_INIT(type_name, member_name, init_expr, default_init_value) \ 83 #define DEFAULT_INIT(type_name, member_name, init_expr, default_init_value) \
81 member_name = default_init_value; 84 member_name = default_init_value;
82 CACHED_CONSTANTS_LIST(DEFAULT_INIT) 85 CACHED_CONSTANTS_LIST(DEFAULT_INIT)
83 #undef DEFAULT_INIT 86 #undef DEFAULT_INIT
84 if (init_vm_constants) { 87 if (init_vm_constants) {
85 InitVMConstants(); 88 InitVMConstants();
86 } 89 }
87 } 90 }
88 91
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
124 ASSERT(thread->isolate() == NULL); 127 ASSERT(thread->isolate() == NULL);
125 ASSERT(!isolate->HasMutatorThread()); 128 ASSERT(!isolate->HasMutatorThread());
126 thread->isolate_ = isolate; 129 thread->isolate_ = isolate;
127 isolate->MakeCurrentThreadMutator(thread); 130 isolate->MakeCurrentThreadMutator(thread);
128 isolate->set_vm_tag(VMTag::kVMTagId); 131 isolate->set_vm_tag(VMTag::kVMTagId);
129 ASSERT(thread->store_buffer_block_ == NULL); 132 ASSERT(thread->store_buffer_block_ == NULL);
130 thread->StoreBufferAcquire(); 133 thread->StoreBufferAcquire();
131 ASSERT(isolate->heap() != NULL); 134 ASSERT(isolate->heap() != NULL);
132 thread->heap_ = isolate->heap(); 135 thread->heap_ = isolate->heap();
133 thread->Schedule(isolate); 136 thread->Schedule(isolate);
134 ASSERT(thread->thread_state() == NULL);
135 InterruptableThreadState* thread_state = 137 InterruptableThreadState* thread_state =
136 ThreadInterrupter::GetCurrentThreadState(); 138 ThreadInterrupter::GetCurrentThreadState();
137 #if defined(DEBUG) 139 #if defined(DEBUG)
138 thread->set_thread_state(NULL); // Exclude thread itself from the dupe check. 140 thread->set_thread_state(NULL); // Exclude thread itself from the dupe check.
139 Isolate::CheckForDuplicateThreadState(thread_state); 141 Isolate::CheckForDuplicateThreadState(thread_state);
140 thread->set_thread_state(thread_state); 142 thread->set_thread_state(thread_state);
141 #endif 143 #endif
142 ASSERT(thread_state != NULL); 144 ASSERT(thread_state != NULL);
143 // TODO(koda): Migrate profiler interface to use Thread. 145 // TODO(koda): Migrate profiler interface to use Thread.
144 Profiler::BeginExecution(isolate); 146 Profiler::BeginExecution(isolate);
145 } 147 }
146 148
147 149
148 void Thread::ExitIsolate() { 150 void Thread::ExitIsolate() {
149 Thread* thread = Thread::Current(); 151 Thread* thread = Thread::Current();
150 // TODO(koda): Audit callers; they should know whether they're in an isolate. 152 // TODO(koda): Audit callers; they should know whether they're in an isolate.
151 if (thread == NULL || thread->isolate() == NULL) return; 153 if (thread == NULL || thread->isolate() == NULL) return;
152 Isolate* isolate = thread->isolate(); 154 Isolate* isolate = thread->isolate();
153 Profiler::EndExecution(isolate); 155 Profiler::EndExecution(isolate);
154 thread->set_thread_state(NULL);
155 thread->Unschedule(); 156 thread->Unschedule();
156 // TODO(koda): Move store_buffer_block_ into State. 157 // TODO(koda): Move store_buffer_block_ into State.
157 thread->StoreBufferRelease(); 158 thread->StoreBufferRelease();
158 if (isolate->is_runnable()) { 159 if (isolate->is_runnable()) {
159 isolate->set_vm_tag(VMTag::kIdleTagId); 160 isolate->set_vm_tag(VMTag::kIdleTagId);
160 } else { 161 } else {
161 isolate->set_vm_tag(VMTag::kLoadWaitTagId); 162 isolate->set_vm_tag(VMTag::kLoadWaitTagId);
162 } 163 }
163 isolate->ClearMutatorThread(); 164 isolate->ClearMutatorThread();
164 thread->isolate_ = NULL; 165 thread->isolate_ = NULL;
165 ASSERT(Isolate::Current() == NULL); 166 ASSERT(Isolate::Current() == NULL);
166 thread->heap_ = NULL; 167 thread->heap_ = NULL;
167 } 168 }
168 169
169 170
170 void Thread::EnterIsolateAsHelper(Isolate* isolate) { 171 void Thread::EnterIsolateAsHelper(Isolate* isolate) {
171 Thread* thread = Thread::Current(); 172 Thread* thread = Thread::Current();
172 ASSERT(thread != NULL); 173 ASSERT(thread != NULL);
173 ASSERT(thread->isolate() == NULL); 174 ASSERT(thread->isolate() == NULL);
174 thread->isolate_ = isolate; 175 thread->isolate_ = isolate;
175 ASSERT(thread->store_buffer_block_ == NULL); 176 ASSERT(thread->store_buffer_block_ == NULL);
176 // TODO(koda): Use StoreBufferAcquire once we properly flush before Scavenge. 177 // TODO(koda): Use StoreBufferAcquire once we properly flush before Scavenge.
177 thread->store_buffer_block_ = 178 thread->store_buffer_block_ =
178 thread->isolate()->store_buffer()->PopEmptyBlock(); 179 thread->isolate()->store_buffer()->PopEmptyBlock();
179 ASSERT(isolate->heap() != NULL); 180 ASSERT(isolate->heap() != NULL);
180 thread->heap_ = isolate->heap(); 181 thread->heap_ = isolate->heap();
181 ASSERT(thread->thread_state() == NULL);
182 // Do not update isolate->mutator_thread, but perform sanity check: 182 // Do not update isolate->mutator_thread, but perform sanity check:
183 // this thread should not be both the main mutator and helper. 183 // this thread should not be both the main mutator and helper.
184 ASSERT(!isolate->MutatorThreadIsCurrentThread()); 184 ASSERT(!isolate->MutatorThreadIsCurrentThread());
185 thread->Schedule(isolate); 185 thread->Schedule(isolate);
186 } 186 }
187 187
188 188
189 void Thread::ExitIsolateAsHelper() { 189 void Thread::ExitIsolateAsHelper() {
190 Thread* thread = Thread::Current(); 190 Thread* thread = Thread::Current();
191 Isolate* isolate = thread->isolate(); 191 Isolate* isolate = thread->isolate();
192 ASSERT(isolate != NULL); 192 ASSERT(isolate != NULL);
193 thread->Unschedule(); 193 thread->Unschedule();
194 // TODO(koda): Move store_buffer_block_ into State. 194 // TODO(koda): Move store_buffer_block_ into State.
195 thread->StoreBufferRelease(); 195 thread->StoreBufferRelease();
196 thread->set_thread_state(NULL);
197 thread->isolate_ = NULL; 196 thread->isolate_ = NULL;
198 thread->heap_ = NULL; 197 thread->heap_ = NULL;
199 ASSERT(!isolate->MutatorThreadIsCurrentThread()); 198 ASSERT(!isolate->MutatorThreadIsCurrentThread());
200 } 199 }
201 200
202 201
203 // TODO(koda): Make non-static and invoke in SafepointThreads. 202 // TODO(koda): Make non-static and invoke in SafepointThreads.
204 void Thread::PrepareForGC() { 203 void Thread::PrepareForGC() {
205 Thread* thread = Thread::Current(); 204 Thread* thread = Thread::Current();
206 const bool kDoNotCheckThreshold = false; // Prevent scheduling another GC. 205 const bool kDoNotCheckThreshold = false; // Prevent scheduling another GC.
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
272 #define COMPUTE_OFFSET(type_name, member_name, expr, default_init_value) \ 271 #define COMPUTE_OFFSET(type_name, member_name, expr, default_init_value) \
273 ASSERT((expr)->IsVMHeapObject()); \ 272 ASSERT((expr)->IsVMHeapObject()); \
274 if (object.raw() == expr) return Thread::member_name##offset(); 273 if (object.raw() == expr) return Thread::member_name##offset();
275 CACHED_VM_OBJECTS_LIST(COMPUTE_OFFSET) 274 CACHED_VM_OBJECTS_LIST(COMPUTE_OFFSET)
276 #undef COMPUTE_OFFSET 275 #undef COMPUTE_OFFSET
277 UNREACHABLE(); 276 UNREACHABLE();
278 return -1; 277 return -1;
279 } 278 }
280 279
281 } // namespace dart 280 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/thread.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698