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

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: Add comments, use Acquire method. 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 // TODO(koda): Make non-static and invoke in SafepointThreads.
201 void Thread::PrepareForGC() { 202 void Thread::PrepareForGC() {
202 Thread* thread = Thread::Current(); 203 Thread* thread = Thread::Current();
203 StoreBuffer* sb = thread->isolate()->store_buffer(); 204 const bool kDoNotCheckThreshold = false; // Prevent scheduling another GC.
204 StoreBufferBlock* block = thread->store_buffer_block_; 205 thread->StoreBufferRelease(kDoNotCheckThreshold);
205 thread->store_buffer_block_ = NULL; 206 // Make sure to get an *empty* block; the isolate needs all entries
206 const bool kCheckThreshold = false; // Prevent scheduling another GC. 207 // at GC time.
207 sb->PushBlock(block, kCheckThreshold); 208 // TODO(koda): Replace with an epilogue (PrepareAfterGC) that acquires.
208 thread->store_buffer_block_ = sb->PopEmptyBlock(); 209 thread->store_buffer_block_ =
210 thread->isolate()->store_buffer()->PopEmptyBlock();
209 } 211 }
210 212
211 213
212 void Thread::StoreBufferBlockProcess(bool check_threshold) { 214 void Thread::StoreBufferBlockProcess(bool check_threshold) {
213 StoreBuffer* sb = isolate()->store_buffer(); 215 StoreBufferRelease(check_threshold);
214 StoreBufferBlock* block = store_buffer_block_; 216 StoreBufferAcquire();
215 store_buffer_block_ = NULL;
216 sb->PushBlock(block, check_threshold);
217 store_buffer_block_ = sb->PopNonFullBlock();
218 } 217 }
219 218
220 219
221 void Thread::StoreBufferAddObject(RawObject* obj) { 220 void Thread::StoreBufferAddObject(RawObject* obj) {
222 store_buffer_block_->Push(obj); 221 store_buffer_block_->Push(obj);
223 if (store_buffer_block_->IsFull()) { 222 if (store_buffer_block_->IsFull()) {
224 StoreBufferBlockProcess(true); 223 StoreBufferBlockProcess(true);
225 } 224 }
226 } 225 }
227 226
228 227
229 void Thread::StoreBufferAddObjectGC(RawObject* obj) { 228 void Thread::StoreBufferAddObjectGC(RawObject* obj) {
230 store_buffer_block_->Push(obj); 229 store_buffer_block_->Push(obj);
231 if (store_buffer_block_->IsFull()) { 230 if (store_buffer_block_->IsFull()) {
232 StoreBufferBlockProcess(false); 231 StoreBufferBlockProcess(false);
233 } 232 }
234 } 233 }
235 234
236 235
236 void Thread::StoreBufferRelease(bool check_threshold) {
237 StoreBufferBlock* block = store_buffer_block_;
238 store_buffer_block_ = NULL;
239 isolate_->store_buffer()->PushBlock(block, check_threshold);
240 }
241
242
243 void Thread::StoreBufferAcquire() {
244 store_buffer_block_ = isolate()->store_buffer()->PopNonFullBlock();
245 }
246
247
237 CHA* Thread::cha() const { 248 CHA* Thread::cha() const {
238 ASSERT(isolate_ != NULL); 249 ASSERT(isolate_ != NULL);
239 return isolate_->cha_; 250 return isolate_->cha_;
240 } 251 }
241 252
242 253
243 void Thread::set_cha(CHA* value) { 254 void Thread::set_cha(CHA* value) {
244 ASSERT(isolate_ != NULL); 255 ASSERT(isolate_ != NULL);
245 isolate_->cha_ = value; 256 isolate_->cha_ = value;
246 } 257 }
(...skipping 12 matching lines...) Expand all
259 #define COMPUTE_OFFSET(type_name, member_name, expr, default_init_value) \ 270 #define COMPUTE_OFFSET(type_name, member_name, expr, default_init_value) \
260 ASSERT((expr)->IsVMHeapObject()); \ 271 ASSERT((expr)->IsVMHeapObject()); \
261 if (object.raw() == expr) return Thread::member_name##offset(); 272 if (object.raw() == expr) return Thread::member_name##offset();
262 CACHED_VM_OBJECTS_LIST(COMPUTE_OFFSET) 273 CACHED_VM_OBJECTS_LIST(COMPUTE_OFFSET)
263 #undef COMPUTE_OFFSET 274 #undef COMPUTE_OFFSET
264 UNREACHABLE(); 275 UNREACHABLE();
265 return -1; 276 return -1;
266 } 277 }
267 278
268 } // namespace dart 279 } // 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