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

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

Issue 1289153002: Add test of full GC on helper thread (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Address comments. 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') | runtime/vm/thread_test.cc » ('j') | 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"
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after
120 120
121 void Thread::EnterIsolate(Isolate* isolate) { 121 void Thread::EnterIsolate(Isolate* isolate) {
122 Thread* thread = Thread::Current(); 122 Thread* thread = Thread::Current();
123 ASSERT(thread != NULL); 123 ASSERT(thread != NULL);
124 ASSERT(thread->isolate() == NULL); 124 ASSERT(thread->isolate() == NULL);
125 ASSERT(!isolate->HasMutatorThread()); 125 ASSERT(!isolate->HasMutatorThread());
126 thread->isolate_ = isolate; 126 thread->isolate_ = isolate;
127 isolate->MakeCurrentThreadMutator(thread); 127 isolate->MakeCurrentThreadMutator(thread);
128 isolate->set_vm_tag(VMTag::kVMTagId); 128 isolate->set_vm_tag(VMTag::kVMTagId);
129 ASSERT(thread->store_buffer_block_ == NULL); 129 ASSERT(thread->store_buffer_block_ == NULL);
130 thread->store_buffer_block_ = isolate->store_buffer()->PopNonFullBlock(); 130 thread->StoreBufferAcquire();
131 ASSERT(isolate->heap() != NULL); 131 ASSERT(isolate->heap() != NULL);
132 thread->heap_ = isolate->heap(); 132 thread->heap_ = isolate->heap();
133 thread->Schedule(isolate); 133 thread->Schedule(isolate);
134 ASSERT(thread->thread_state() == NULL); 134 ASSERT(thread->thread_state() == NULL);
135 InterruptableThreadState* thread_state = 135 InterruptableThreadState* thread_state =
136 ThreadInterrupter::GetCurrentThreadState(); 136 ThreadInterrupter::GetCurrentThreadState();
137 #if defined(DEBUG) 137 #if defined(DEBUG)
138 thread->set_thread_state(NULL); // Exclude thread itself from the dupe check. 138 thread->set_thread_state(NULL); // Exclude thread itself from the dupe check.
139 Isolate::CheckForDuplicateThreadState(thread_state); 139 Isolate::CheckForDuplicateThreadState(thread_state);
140 thread->set_thread_state(thread_state); 140 thread->set_thread_state(thread_state);
141 #endif 141 #endif
142 ASSERT(thread_state != NULL); 142 ASSERT(thread_state != NULL);
143 // TODO(koda): Migrate profiler interface to use Thread. 143 // TODO(koda): Migrate profiler interface to use Thread.
144 Profiler::BeginExecution(isolate); 144 Profiler::BeginExecution(isolate);
145 } 145 }
146 146
147 147
148 void Thread::ExitIsolate() { 148 void Thread::ExitIsolate() {
149 Thread* thread = Thread::Current(); 149 Thread* thread = Thread::Current();
150 // TODO(koda): Audit callers; they should know whether they're in an isolate. 150 // TODO(koda): Audit callers; they should know whether they're in an isolate.
151 if (thread == NULL || thread->isolate() == NULL) return; 151 if (thread == NULL || thread->isolate() == NULL) return;
152 Isolate* isolate = thread->isolate(); 152 Isolate* isolate = thread->isolate();
153 Profiler::EndExecution(isolate); 153 Profiler::EndExecution(isolate);
154 thread->set_thread_state(NULL); 154 thread->set_thread_state(NULL);
155 thread->Unschedule(); 155 thread->Unschedule();
156 StoreBufferBlock* block = thread->store_buffer_block_; 156 // TODO(koda): Move store_buffer_block_ into State.
157 thread->store_buffer_block_ = NULL; 157 thread->StoreBufferRelease();
158 isolate->store_buffer()->PushBlock(block);
159 if (isolate->is_runnable()) { 158 if (isolate->is_runnable()) {
160 isolate->set_vm_tag(VMTag::kIdleTagId); 159 isolate->set_vm_tag(VMTag::kIdleTagId);
161 } else { 160 } else {
162 isolate->set_vm_tag(VMTag::kLoadWaitTagId); 161 isolate->set_vm_tag(VMTag::kLoadWaitTagId);
163 } 162 }
164 isolate->ClearMutatorThread(); 163 isolate->ClearMutatorThread();
165 thread->isolate_ = NULL; 164 thread->isolate_ = NULL;
166 ASSERT(Isolate::Current() == NULL); 165 ASSERT(Isolate::Current() == NULL);
167 thread->heap_ = NULL; 166 thread->heap_ = NULL;
168 } 167 }
169 168
170 169
171 void Thread::EnterIsolateAsHelper(Isolate* isolate) { 170 void Thread::EnterIsolateAsHelper(Isolate* isolate) {
172 Thread* thread = Thread::Current(); 171 Thread* thread = Thread::Current();
173 ASSERT(thread != NULL); 172 ASSERT(thread != NULL);
174 ASSERT(thread->isolate() == NULL); 173 ASSERT(thread->isolate() == NULL);
175 thread->isolate_ = isolate; 174 thread->isolate_ = isolate;
175 ASSERT(thread->store_buffer_block_ == NULL);
176 thread->StoreBufferAcquire();
176 ASSERT(isolate->heap() != NULL); 177 ASSERT(isolate->heap() != NULL);
177 thread->heap_ = isolate->heap(); 178 thread->heap_ = isolate->heap();
178 ASSERT(thread->thread_state() == NULL); 179 ASSERT(thread->thread_state() == NULL);
179 // Do not update isolate->mutator_thread, but perform sanity check: 180 // Do not update isolate->mutator_thread, but perform sanity check:
180 // this thread should not be both the main mutator and helper. 181 // this thread should not be both the main mutator and helper.
181 ASSERT(!isolate->MutatorThreadIsCurrentThread()); 182 ASSERT(!isolate->MutatorThreadIsCurrentThread());
182 thread->Schedule(isolate); 183 thread->Schedule(isolate);
183 } 184 }
184 185
185 186
186 void Thread::ExitIsolateAsHelper() { 187 void Thread::ExitIsolateAsHelper() {
187 Thread* thread = Thread::Current(); 188 Thread* thread = Thread::Current();
188 // If the helper thread chose to use the store buffer, check that it has
189 // already been flushed manually.
190 ASSERT(thread->store_buffer_block_ == NULL);
191 Isolate* isolate = thread->isolate(); 189 Isolate* isolate = thread->isolate();
192 ASSERT(isolate != NULL); 190 ASSERT(isolate != NULL);
193 thread->Unschedule(); 191 thread->Unschedule();
192 // TODO(koda): Move store_buffer_block_ into State.
193 thread->StoreBufferRelease();
194 thread->set_thread_state(NULL); 194 thread->set_thread_state(NULL);
195 thread->isolate_ = NULL; 195 thread->isolate_ = NULL;
196 thread->heap_ = NULL; 196 thread->heap_ = NULL;
197 ASSERT(!isolate->MutatorThreadIsCurrentThread()); 197 ASSERT(!isolate->MutatorThreadIsCurrentThread());
198 } 198 }
199 199
200 200
201 void Thread::PrepareForGC() { 201 void Thread::PrepareForGC() {
Ivan Posva 2015/08/18 00:28:00 Is there a reason this is a static method on the t
koda 2015/08/18 14:21:35 It should become non-static and called from Safepo
202 Thread* thread = Thread::Current(); 202 Thread* thread = Thread::Current();
203 StoreBuffer* sb = thread->isolate()->store_buffer(); 203 const bool kDoNotCheckThreshold = false; // Prevent scheduling another GC.
204 StoreBufferBlock* block = thread->store_buffer_block_; 204 thread->StoreBufferRelease(/* check_threshold = */ kDoNotCheckThreshold);
Ivan Posva 2015/08/18 00:28:00 Please remove the comment so it reads more natural
koda 2015/08/18 14:21:35 Done.
205 thread->store_buffer_block_ = NULL; 205 thread->store_buffer_block_ =
206 const bool kCheckThreshold = false; // Prevent scheduling another GC. 206 thread->isolate()->store_buffer()->PopEmptyBlock();
Ivan Posva 2015/08/18 00:28:00 StoreBufferAcquire?
koda 2015/08/18 14:21:35 That would not work, since we must make sure to ge
207 sb->PushBlock(block, kCheckThreshold);
208 thread->store_buffer_block_ = sb->PopEmptyBlock();
209 } 207 }
210 208
211 209
212 void Thread::StoreBufferBlockProcess(bool check_threshold) { 210 void Thread::StoreBufferBlockProcess(bool check_threshold) {
213 StoreBuffer* sb = isolate()->store_buffer(); 211 StoreBufferRelease(check_threshold);
214 StoreBufferBlock* block = store_buffer_block_; 212 store_buffer_block_ = isolate()->store_buffer()->PopNonFullBlock();
Ivan Posva 2015/08/18 00:28:00 ditto: StoreBufferAcquire.
koda 2015/08/18 14:21:34 Done.
215 store_buffer_block_ = NULL;
216 sb->PushBlock(block, check_threshold);
217 store_buffer_block_ = sb->PopNonFullBlock();
218 } 213 }
219 214
220 215
221 void Thread::StoreBufferAddObject(RawObject* obj) { 216 void Thread::StoreBufferAddObject(RawObject* obj) {
222 store_buffer_block_->Push(obj); 217 store_buffer_block_->Push(obj);
223 if (store_buffer_block_->IsFull()) { 218 if (store_buffer_block_->IsFull()) {
224 StoreBufferBlockProcess(true); 219 StoreBufferBlockProcess(true);
225 } 220 }
226 } 221 }
227 222
228 223
229 void Thread::StoreBufferAddObjectGC(RawObject* obj) { 224 void Thread::StoreBufferAddObjectGC(RawObject* obj) {
230 store_buffer_block_->Push(obj); 225 store_buffer_block_->Push(obj);
231 if (store_buffer_block_->IsFull()) { 226 if (store_buffer_block_->IsFull()) {
232 StoreBufferBlockProcess(false); 227 StoreBufferBlockProcess(false);
233 } 228 }
234 } 229 }
235 230
236 231
232 void Thread::StoreBufferRelease(bool check_threshold) {
233 StoreBufferBlock* block = store_buffer_block_;
234 store_buffer_block_ = NULL;
235 isolate_->store_buffer()->PushBlock(block, check_threshold);
236 }
237
238
239 void Thread::StoreBufferAcquire() {
240 store_buffer_block_ = isolate()->store_buffer()->PopNonFullBlock();
241 }
242
243
237 CHA* Thread::cha() const { 244 CHA* Thread::cha() const {
238 ASSERT(isolate_ != NULL); 245 ASSERT(isolate_ != NULL);
239 return isolate_->cha_; 246 return isolate_->cha_;
240 } 247 }
241 248
242 249
243 void Thread::set_cha(CHA* value) { 250 void Thread::set_cha(CHA* value) {
244 ASSERT(isolate_ != NULL); 251 ASSERT(isolate_ != NULL);
245 isolate_->cha_ = value; 252 isolate_->cha_ = value;
246 } 253 }
(...skipping 12 matching lines...) Expand all
259 #define COMPUTE_OFFSET(type_name, member_name, expr, default_init_value) \ 266 #define COMPUTE_OFFSET(type_name, member_name, expr, default_init_value) \
260 ASSERT((expr)->IsVMHeapObject()); \ 267 ASSERT((expr)->IsVMHeapObject()); \
261 if (object.raw() == expr) return Thread::member_name##offset(); 268 if (object.raw() == expr) return Thread::member_name##offset();
262 CACHED_VM_OBJECTS_LIST(COMPUTE_OFFSET) 269 CACHED_VM_OBJECTS_LIST(COMPUTE_OFFSET)
263 #undef COMPUTE_OFFSET 270 #undef COMPUTE_OFFSET
264 UNREACHABLE(); 271 UNREACHABLE();
265 return -1; 272 return -1;
266 } 273 }
267 274
268 } // namespace dart 275 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/thread.h ('k') | runtime/vm/thread_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698