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

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

Issue 2974233002: VM: Re-format to use at most one newline between functions (Closed)
Patch Set: Rebase and merge Created 3 years, 5 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_barrier.h » ('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/compiler_stats.h" 7 #include "vm/compiler_stats.h"
8 #include "vm/dart_api_state.h" 8 #include "vm/dart_api_state.h"
9 #include "vm/growable_array.h" 9 #include "vm/growable_array.h"
10 #include "vm/isolate.h" 10 #include "vm/isolate.h"
11 #include "vm/json_stream.h" 11 #include "vm/json_stream.h"
12 #include "vm/lockers.h" 12 #include "vm/lockers.h"
13 #include "vm/log.h" 13 #include "vm/log.h"
14 #include "vm/message_handler.h" 14 #include "vm/message_handler.h"
15 #include "vm/native_entry.h" 15 #include "vm/native_entry.h"
16 #include "vm/object.h" 16 #include "vm/object.h"
17 #include "vm/os_thread.h" 17 #include "vm/os_thread.h"
18 #include "vm/profiler.h" 18 #include "vm/profiler.h"
19 #include "vm/runtime_entry.h" 19 #include "vm/runtime_entry.h"
20 #include "vm/stub_code.h" 20 #include "vm/stub_code.h"
21 #include "vm/symbols.h" 21 #include "vm/symbols.h"
22 #include "vm/thread_interrupter.h" 22 #include "vm/thread_interrupter.h"
23 #include "vm/thread_registry.h" 23 #include "vm/thread_registry.h"
24 #include "vm/timeline.h" 24 #include "vm/timeline.h"
25 #include "vm/zone.h" 25 #include "vm/zone.h"
26 26
27 namespace dart { 27 namespace dart {
28 28
29
30 DECLARE_FLAG(bool, trace_service); 29 DECLARE_FLAG(bool, trace_service);
31 DECLARE_FLAG(bool, trace_service_verbose); 30 DECLARE_FLAG(bool, trace_service_verbose);
32 31
33
34 Thread::~Thread() { 32 Thread::~Thread() {
35 // We should cleanly exit any isolate before destruction. 33 // We should cleanly exit any isolate before destruction.
36 ASSERT(isolate_ == NULL); 34 ASSERT(isolate_ == NULL);
37 if (compiler_stats_ != NULL) { 35 if (compiler_stats_ != NULL) {
38 delete compiler_stats_; 36 delete compiler_stats_;
39 compiler_stats_ = NULL; 37 compiler_stats_ = NULL;
40 } 38 }
41 // There should be no top api scopes at this point. 39 // There should be no top api scopes at this point.
42 ASSERT(api_top_scope() == NULL); 40 ASSERT(api_top_scope() == NULL);
43 // Delete the resusable api scope if there is one. 41 // Delete the resusable api scope if there is one.
44 if (api_reusable_scope_) { 42 if (api_reusable_scope_) {
45 delete api_reusable_scope_; 43 delete api_reusable_scope_;
46 api_reusable_scope_ = NULL; 44 api_reusable_scope_ = NULL;
47 } 45 }
48 delete thread_lock_; 46 delete thread_lock_;
49 thread_lock_ = NULL; 47 thread_lock_ = NULL;
50 } 48 }
51 49
52 #if defined(DEBUG) 50 #if defined(DEBUG)
53 #define REUSABLE_HANDLE_SCOPE_INIT(object) \ 51 #define REUSABLE_HANDLE_SCOPE_INIT(object) \
54 reusable_##object##_handle_scope_active_(false), 52 reusable_##object##_handle_scope_active_(false),
55 #else 53 #else
56 #define REUSABLE_HANDLE_SCOPE_INIT(object) 54 #define REUSABLE_HANDLE_SCOPE_INIT(object)
57 #endif // defined(DEBUG) 55 #endif // defined(DEBUG)
58 56
59 #define REUSABLE_HANDLE_INITIALIZERS(object) object##_handle_(NULL), 57 #define REUSABLE_HANDLE_INITIALIZERS(object) object##_handle_(NULL),
60 58
61
62 Thread::Thread(Isolate* isolate) 59 Thread::Thread(Isolate* isolate)
63 : BaseThread(false), 60 : BaseThread(false),
64 stack_limit_(0), 61 stack_limit_(0),
65 stack_overflow_flags_(0), 62 stack_overflow_flags_(0),
66 isolate_(NULL), 63 isolate_(NULL),
67 heap_(NULL), 64 heap_(NULL),
68 top_exit_frame_info_(0), 65 top_exit_frame_info_(0),
69 store_buffer_block_(NULL), 66 store_buffer_block_(NULL),
70 vm_tag_(0), 67 vm_tag_(0),
71 task_kind_(kUnknownTask), 68 task_kind_(kUnknownTask),
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
141 Zone* current = zone_; 138 Zone* current = zone_;
142 uintptr_t total_zone_capacity = 0; 139 uintptr_t total_zone_capacity = 0;
143 while (current != NULL) { 140 while (current != NULL) {
144 total_zone_capacity += current->CapacityInBytes(); 141 total_zone_capacity += current->CapacityInBytes();
145 current = current->previous(); 142 current = current->previous();
146 } 143 }
147 ASSERT(current_zone_capacity_ == total_zone_capacity); 144 ASSERT(current_zone_capacity_ == total_zone_capacity);
148 } 145 }
149 } 146 }
150 147
151
152 static const struct ALIGN16 { 148 static const struct ALIGN16 {
153 uint64_t a; 149 uint64_t a;
154 uint64_t b; 150 uint64_t b;
155 } double_negate_constant = {0x8000000000000000LL, 0x8000000000000000LL}; 151 } double_negate_constant = {0x8000000000000000LL, 0x8000000000000000LL};
156 152
157 static const struct ALIGN16 { 153 static const struct ALIGN16 {
158 uint64_t a; 154 uint64_t a;
159 uint64_t b; 155 uint64_t b;
160 } double_abs_constant = {0x7FFFFFFFFFFFFFFFLL, 0x7FFFFFFFFFFFFFFFLL}; 156 } double_abs_constant = {0x7FFFFFFFFFFFFFFFLL, 0x7FFFFFFFFFFFFFFFLL};
161 157
(...skipping 18 matching lines...) Expand all
180 uint32_t d; 176 uint32_t d;
181 } float_absolute_constant = {0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF}; 177 } float_absolute_constant = {0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF};
182 178
183 static const struct ALIGN16 { 179 static const struct ALIGN16 {
184 uint32_t a; 180 uint32_t a;
185 uint32_t b; 181 uint32_t b;
186 uint32_t c; 182 uint32_t c;
187 uint32_t d; 183 uint32_t d;
188 } float_zerow_constant = {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000}; 184 } float_zerow_constant = {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000};
189 185
190
191 void Thread::InitVMConstants() { 186 void Thread::InitVMConstants() {
192 #define ASSERT_VM_HEAP(type_name, member_name, init_expr, default_init_value) \ 187 #define ASSERT_VM_HEAP(type_name, member_name, init_expr, default_init_value) \
193 ASSERT((init_expr)->IsOldObject()); 188 ASSERT((init_expr)->IsOldObject());
194 CACHED_VM_OBJECTS_LIST(ASSERT_VM_HEAP) 189 CACHED_VM_OBJECTS_LIST(ASSERT_VM_HEAP)
195 #undef ASSERT_VM_HEAP 190 #undef ASSERT_VM_HEAP
196 191
197 #define INIT_VALUE(type_name, member_name, init_expr, default_init_value) \ 192 #define INIT_VALUE(type_name, member_name, init_expr, default_init_value) \
198 ASSERT(member_name == default_init_value); \ 193 ASSERT(member_name == default_init_value); \
199 member_name = (init_expr); 194 member_name = (init_expr);
200 CACHED_CONSTANTS_LIST(INIT_VALUE) 195 CACHED_CONSTANTS_LIST(INIT_VALUE)
(...skipping 11 matching lines...) Expand all
212 LEAF_RUNTIME_ENTRY_LIST(INIT_VALUE) 207 LEAF_RUNTIME_ENTRY_LIST(INIT_VALUE)
213 #undef INIT_VALUE 208 #undef INIT_VALUE
214 209
215 // Setup the thread specific reusable handles. 210 // Setup the thread specific reusable handles.
216 #define REUSABLE_HANDLE_ALLOCATION(object) \ 211 #define REUSABLE_HANDLE_ALLOCATION(object) \
217 this->object##_handle_ = this->AllocateReusableHandle<object>(); 212 this->object##_handle_ = this->AllocateReusableHandle<object>();
218 REUSABLE_HANDLE_LIST(REUSABLE_HANDLE_ALLOCATION) 213 REUSABLE_HANDLE_LIST(REUSABLE_HANDLE_ALLOCATION)
219 #undef REUSABLE_HANDLE_ALLOCATION 214 #undef REUSABLE_HANDLE_ALLOCATION
220 } 215 }
221 216
222
223 #ifndef PRODUCT 217 #ifndef PRODUCT
224 // Collect information about each individual zone associated with this thread. 218 // Collect information about each individual zone associated with this thread.
225 void Thread::PrintJSON(JSONStream* stream) const { 219 void Thread::PrintJSON(JSONStream* stream) const {
226 JSONObject jsobj(stream); 220 JSONObject jsobj(stream);
227 jsobj.AddProperty("type", "_Thread"); 221 jsobj.AddProperty("type", "_Thread");
228 jsobj.AddPropertyF("id", "threads/%" Pd "", 222 jsobj.AddPropertyF("id", "threads/%" Pd "",
229 OSThread::ThreadIdToIntPtr(os_thread()->trace_id())); 223 OSThread::ThreadIdToIntPtr(os_thread()->trace_id()));
230 jsobj.AddProperty("kind", TaskKindToCString(task_kind())); 224 jsobj.AddProperty("kind", TaskKindToCString(task_kind()));
231 jsobj.AddPropertyF("_zoneHighWatermark", "%" Pu "", zone_high_watermark_); 225 jsobj.AddPropertyF("_zoneHighWatermark", "%" Pu "", zone_high_watermark_);
232 jsobj.AddPropertyF("_zoneCapacity", "%" Pu "", current_zone_capacity_); 226 jsobj.AddPropertyF("_zoneCapacity", "%" Pu "", current_zone_capacity_);
233 } 227 }
234 #endif 228 #endif
235 229
236
237 RawGrowableObjectArray* Thread::pending_functions() { 230 RawGrowableObjectArray* Thread::pending_functions() {
238 if (pending_functions_ == GrowableObjectArray::null()) { 231 if (pending_functions_ == GrowableObjectArray::null()) {
239 pending_functions_ = GrowableObjectArray::New(Heap::kOld); 232 pending_functions_ = GrowableObjectArray::New(Heap::kOld);
240 } 233 }
241 return pending_functions_; 234 return pending_functions_;
242 } 235 }
243 236
244
245 void Thread::clear_pending_functions() { 237 void Thread::clear_pending_functions() {
246 pending_functions_ = GrowableObjectArray::null(); 238 pending_functions_ = GrowableObjectArray::null();
247 } 239 }
248 240
249
250 void Thread::set_active_exception(const Object& value) { 241 void Thread::set_active_exception(const Object& value) {
251 ASSERT(!value.IsNull()); 242 ASSERT(!value.IsNull());
252 active_exception_ = value.raw(); 243 active_exception_ = value.raw();
253 } 244 }
254 245
255
256 void Thread::set_active_stacktrace(const Object& value) { 246 void Thread::set_active_stacktrace(const Object& value) {
257 active_stacktrace_ = value.raw(); 247 active_stacktrace_ = value.raw();
258 } 248 }
259 249
260
261 RawError* Thread::sticky_error() const { 250 RawError* Thread::sticky_error() const {
262 return sticky_error_; 251 return sticky_error_;
263 } 252 }
264 253
265
266 void Thread::set_sticky_error(const Error& value) { 254 void Thread::set_sticky_error(const Error& value) {
267 ASSERT(!value.IsNull()); 255 ASSERT(!value.IsNull());
268 sticky_error_ = value.raw(); 256 sticky_error_ = value.raw();
269 } 257 }
270 258
271
272 void Thread::clear_sticky_error() { 259 void Thread::clear_sticky_error() {
273 sticky_error_ = Error::null(); 260 sticky_error_ = Error::null();
274 } 261 }
275 262
276
277 RawError* Thread::get_and_clear_sticky_error() { 263 RawError* Thread::get_and_clear_sticky_error() {
278 NoSafepointScope nss; 264 NoSafepointScope nss;
279 RawError* return_value = sticky_error_; 265 RawError* return_value = sticky_error_;
280 sticky_error_ = Error::null(); 266 sticky_error_ = Error::null();
281 return return_value; 267 return return_value;
282 } 268 }
283 269
284
285 const char* Thread::TaskKindToCString(TaskKind kind) { 270 const char* Thread::TaskKindToCString(TaskKind kind) {
286 switch (kind) { 271 switch (kind) {
287 case kUnknownTask: 272 case kUnknownTask:
288 return "kUnknownTask"; 273 return "kUnknownTask";
289 case kMutatorTask: 274 case kMutatorTask:
290 return "kMutatorTask"; 275 return "kMutatorTask";
291 case kCompilerTask: 276 case kCompilerTask:
292 return "kCompilerTask"; 277 return "kCompilerTask";
293 case kSweeperTask: 278 case kSweeperTask:
294 return "kSweeperTask"; 279 return "kSweeperTask";
295 case kMarkerTask: 280 case kMarkerTask:
296 return "kMarkerTask"; 281 return "kMarkerTask";
297 default: 282 default:
298 UNREACHABLE(); 283 UNREACHABLE();
299 return ""; 284 return "";
300 } 285 }
301 } 286 }
302 287
303
304 RawStackTrace* Thread::async_stack_trace() const { 288 RawStackTrace* Thread::async_stack_trace() const {
305 return async_stack_trace_; 289 return async_stack_trace_;
306 } 290 }
307 291
308
309 void Thread::set_async_stack_trace(const StackTrace& stack_trace) { 292 void Thread::set_async_stack_trace(const StackTrace& stack_trace) {
310 ASSERT(!stack_trace.IsNull()); 293 ASSERT(!stack_trace.IsNull());
311 async_stack_trace_ = stack_trace.raw(); 294 async_stack_trace_ = stack_trace.raw();
312 } 295 }
313 296
314
315 void Thread::set_raw_async_stack_trace(RawStackTrace* raw_stack_trace) { 297 void Thread::set_raw_async_stack_trace(RawStackTrace* raw_stack_trace) {
316 async_stack_trace_ = raw_stack_trace; 298 async_stack_trace_ = raw_stack_trace;
317 } 299 }
318 300
319
320 void Thread::clear_async_stack_trace() { 301 void Thread::clear_async_stack_trace() {
321 async_stack_trace_ = StackTrace::null(); 302 async_stack_trace_ = StackTrace::null();
322 } 303 }
323 304
324
325 bool Thread::EnterIsolate(Isolate* isolate) { 305 bool Thread::EnterIsolate(Isolate* isolate) {
326 const bool kIsMutatorThread = true; 306 const bool kIsMutatorThread = true;
327 Thread* thread = isolate->ScheduleThread(kIsMutatorThread); 307 Thread* thread = isolate->ScheduleThread(kIsMutatorThread);
328 if (thread != NULL) { 308 if (thread != NULL) {
329 ASSERT(thread->store_buffer_block_ == NULL); 309 ASSERT(thread->store_buffer_block_ == NULL);
330 thread->task_kind_ = kMutatorTask; 310 thread->task_kind_ = kMutatorTask;
331 thread->StoreBufferAcquire(); 311 thread->StoreBufferAcquire();
332 return true; 312 return true;
333 } 313 }
334 return false; 314 return false;
335 } 315 }
336 316
337
338 void Thread::ExitIsolate() { 317 void Thread::ExitIsolate() {
339 Thread* thread = Thread::Current(); 318 Thread* thread = Thread::Current();
340 ASSERT(thread != NULL && thread->IsMutatorThread()); 319 ASSERT(thread != NULL && thread->IsMutatorThread());
341 DEBUG_ASSERT(!thread->IsAnyReusableHandleScopeActive()); 320 DEBUG_ASSERT(!thread->IsAnyReusableHandleScopeActive());
342 thread->task_kind_ = kUnknownTask; 321 thread->task_kind_ = kUnknownTask;
343 Isolate* isolate = thread->isolate(); 322 Isolate* isolate = thread->isolate();
344 ASSERT(isolate != NULL); 323 ASSERT(isolate != NULL);
345 ASSERT(thread->execution_state() == Thread::kThreadInVM); 324 ASSERT(thread->execution_state() == Thread::kThreadInVM);
346 // Clear since GC will not visit the thread once it is unscheduled. 325 // Clear since GC will not visit the thread once it is unscheduled.
347 thread->ClearReusableHandles(); 326 thread->ClearReusableHandles();
348 thread->StoreBufferRelease(); 327 thread->StoreBufferRelease();
349 if (isolate->is_runnable()) { 328 if (isolate->is_runnable()) {
350 thread->set_vm_tag(VMTag::kIdleTagId); 329 thread->set_vm_tag(VMTag::kIdleTagId);
351 } else { 330 } else {
352 thread->set_vm_tag(VMTag::kLoadWaitTagId); 331 thread->set_vm_tag(VMTag::kLoadWaitTagId);
353 } 332 }
354 const bool kIsMutatorThread = true; 333 const bool kIsMutatorThread = true;
355 isolate->UnscheduleThread(thread, kIsMutatorThread); 334 isolate->UnscheduleThread(thread, kIsMutatorThread);
356 } 335 }
357 336
358
359 bool Thread::EnterIsolateAsHelper(Isolate* isolate, 337 bool Thread::EnterIsolateAsHelper(Isolate* isolate,
360 TaskKind kind, 338 TaskKind kind,
361 bool bypass_safepoint) { 339 bool bypass_safepoint) {
362 ASSERT(kind != kMutatorTask); 340 ASSERT(kind != kMutatorTask);
363 const bool kIsNotMutatorThread = false; 341 const bool kIsNotMutatorThread = false;
364 Thread* thread = 342 Thread* thread =
365 isolate->ScheduleThread(kIsNotMutatorThread, bypass_safepoint); 343 isolate->ScheduleThread(kIsNotMutatorThread, bypass_safepoint);
366 if (thread != NULL) { 344 if (thread != NULL) {
367 ASSERT(thread->store_buffer_block_ == NULL); 345 ASSERT(thread->store_buffer_block_ == NULL);
368 // TODO(koda): Use StoreBufferAcquire once we properly flush 346 // TODO(koda): Use StoreBufferAcquire once we properly flush
369 // before Scavenge. 347 // before Scavenge.
370 thread->store_buffer_block_ = 348 thread->store_buffer_block_ =
371 thread->isolate()->store_buffer()->PopEmptyBlock(); 349 thread->isolate()->store_buffer()->PopEmptyBlock();
372 // This thread should not be the main mutator. 350 // This thread should not be the main mutator.
373 thread->task_kind_ = kind; 351 thread->task_kind_ = kind;
374 ASSERT(!thread->IsMutatorThread()); 352 ASSERT(!thread->IsMutatorThread());
375 return true; 353 return true;
376 } 354 }
377 return false; 355 return false;
378 } 356 }
379 357
380
381 void Thread::ExitIsolateAsHelper(bool bypass_safepoint) { 358 void Thread::ExitIsolateAsHelper(bool bypass_safepoint) {
382 Thread* thread = Thread::Current(); 359 Thread* thread = Thread::Current();
383 ASSERT(thread != NULL); 360 ASSERT(thread != NULL);
384 ASSERT(!thread->IsMutatorThread()); 361 ASSERT(!thread->IsMutatorThread());
385 ASSERT(thread->execution_state() == Thread::kThreadInVM); 362 ASSERT(thread->execution_state() == Thread::kThreadInVM);
386 thread->task_kind_ = kUnknownTask; 363 thread->task_kind_ = kUnknownTask;
387 // Clear since GC will not visit the thread once it is unscheduled. 364 // Clear since GC will not visit the thread once it is unscheduled.
388 thread->ClearReusableHandles(); 365 thread->ClearReusableHandles();
389 thread->StoreBufferRelease(); 366 thread->StoreBufferRelease();
390 Isolate* isolate = thread->isolate(); 367 Isolate* isolate = thread->isolate();
391 ASSERT(isolate != NULL); 368 ASSERT(isolate != NULL);
392 const bool kIsNotMutatorThread = false; 369 const bool kIsNotMutatorThread = false;
393 isolate->UnscheduleThread(thread, kIsNotMutatorThread, bypass_safepoint); 370 isolate->UnscheduleThread(thread, kIsNotMutatorThread, bypass_safepoint);
394 } 371 }
395 372
396
397 void Thread::PrepareForGC() { 373 void Thread::PrepareForGC() {
398 ASSERT(IsAtSafepoint()); 374 ASSERT(IsAtSafepoint());
399 // Prevent scheduling another GC by ignoring the threshold. 375 // Prevent scheduling another GC by ignoring the threshold.
400 ASSERT(store_buffer_block_ != NULL); 376 ASSERT(store_buffer_block_ != NULL);
401 StoreBufferRelease(StoreBuffer::kIgnoreThreshold); 377 StoreBufferRelease(StoreBuffer::kIgnoreThreshold);
402 // Make sure to get an *empty* block; the isolate needs all entries 378 // Make sure to get an *empty* block; the isolate needs all entries
403 // at GC time. 379 // at GC time.
404 // TODO(koda): Replace with an epilogue (PrepareAfterGC) that acquires. 380 // TODO(koda): Replace with an epilogue (PrepareAfterGC) that acquires.
405 store_buffer_block_ = isolate()->store_buffer()->PopEmptyBlock(); 381 store_buffer_block_ = isolate()->store_buffer()->PopEmptyBlock();
406 } 382 }
407 383
408
409 void Thread::SetStackLimitFromStackBase(uword stack_base) { 384 void Thread::SetStackLimitFromStackBase(uword stack_base) {
410 // Set stack limit. 385 // Set stack limit.
411 #if !defined(TARGET_ARCH_DBC) 386 #if !defined(TARGET_ARCH_DBC)
412 #if defined(USING_SIMULATOR) 387 #if defined(USING_SIMULATOR)
413 // Ignore passed-in native stack top and use Simulator stack top. 388 // Ignore passed-in native stack top and use Simulator stack top.
414 Simulator* sim = Simulator::Current(); // May allocate a simulator. 389 Simulator* sim = Simulator::Current(); // May allocate a simulator.
415 ASSERT(isolate()->simulator() == sim); // Isolate's simulator is current one. 390 ASSERT(isolate()->simulator() == sim); // Isolate's simulator is current one.
416 stack_base = sim->StackTop(); 391 stack_base = sim->StackTop();
417 // The overflow area is accounted for by the simulator. 392 // The overflow area is accounted for by the simulator.
418 #endif 393 #endif
419 SetStackLimit(stack_base - OSThread::GetSpecifiedStackSize()); 394 SetStackLimit(stack_base - OSThread::GetSpecifiedStackSize());
420 #else 395 #else
421 SetStackLimit(Simulator::Current()->StackTop()); 396 SetStackLimit(Simulator::Current()->StackTop());
422 #endif // !defined(TARGET_ARCH_DBC) 397 #endif // !defined(TARGET_ARCH_DBC)
423 } 398 }
424 399
425
426 void Thread::SetStackLimit(uword limit) { 400 void Thread::SetStackLimit(uword limit) {
427 // The thread setting the stack limit is not necessarily the thread which 401 // The thread setting the stack limit is not necessarily the thread which
428 // the stack limit is being set on. 402 // the stack limit is being set on.
429 MonitorLocker ml(thread_lock_); 403 MonitorLocker ml(thread_lock_);
430 if (stack_limit_ == saved_stack_limit_) { 404 if (stack_limit_ == saved_stack_limit_) {
431 // No interrupt pending, set stack_limit_ too. 405 // No interrupt pending, set stack_limit_ too.
432 stack_limit_ = limit; 406 stack_limit_ = limit;
433 } 407 }
434 saved_stack_limit_ = limit; 408 saved_stack_limit_ = limit;
435 } 409 }
436 410
437
438 void Thread::ClearStackLimit() { 411 void Thread::ClearStackLimit() {
439 SetStackLimit(~static_cast<uword>(0)); 412 SetStackLimit(~static_cast<uword>(0));
440 } 413 }
441 414
442
443 /* static */ 415 /* static */
444 uword Thread::GetCurrentStackPointer() { 416 uword Thread::GetCurrentStackPointer() {
445 #if !defined(TARGET_ARCH_DBC) 417 #if !defined(TARGET_ARCH_DBC)
446 // Since AddressSanitizer's detect_stack_use_after_return instruments the 418 // Since AddressSanitizer's detect_stack_use_after_return instruments the
447 // C++ code to give out fake stack addresses, we call a stub in that case. 419 // C++ code to give out fake stack addresses, we call a stub in that case.
448 ASSERT(StubCode::GetCStackPointer_entry() != NULL); 420 ASSERT(StubCode::GetCStackPointer_entry() != NULL);
449 uword (*func)() = reinterpret_cast<uword (*)()>( 421 uword (*func)() = reinterpret_cast<uword (*)()>(
450 StubCode::GetCStackPointer_entry()->EntryPoint()); 422 StubCode::GetCStackPointer_entry()->EntryPoint());
451 #else 423 #else
452 uword (*func)() = NULL; 424 uword (*func)() = NULL;
453 #endif 425 #endif
454 // But for performance (and to support simulators), we normally use a local. 426 // But for performance (and to support simulators), we normally use a local.
455 #if defined(__has_feature) 427 #if defined(__has_feature)
456 #if __has_feature(address_sanitizer) || __has_feature(safe_stack) 428 #if __has_feature(address_sanitizer) || __has_feature(safe_stack)
457 uword current_sp = func(); 429 uword current_sp = func();
458 return current_sp; 430 return current_sp;
459 #else 431 #else
460 uword stack_allocated_local_address = reinterpret_cast<uword>(&func); 432 uword stack_allocated_local_address = reinterpret_cast<uword>(&func);
461 return stack_allocated_local_address; 433 return stack_allocated_local_address;
462 #endif 434 #endif
463 #else 435 #else
464 uword stack_allocated_local_address = reinterpret_cast<uword>(&func); 436 uword stack_allocated_local_address = reinterpret_cast<uword>(&func);
465 return stack_allocated_local_address; 437 return stack_allocated_local_address;
466 #endif 438 #endif
467 } 439 }
468 440
469
470 void Thread::ScheduleInterrupts(uword interrupt_bits) { 441 void Thread::ScheduleInterrupts(uword interrupt_bits) {
471 MonitorLocker ml(thread_lock_); 442 MonitorLocker ml(thread_lock_);
472 ScheduleInterruptsLocked(interrupt_bits); 443 ScheduleInterruptsLocked(interrupt_bits);
473 } 444 }
474 445
475
476 void Thread::ScheduleInterruptsLocked(uword interrupt_bits) { 446 void Thread::ScheduleInterruptsLocked(uword interrupt_bits) {
477 ASSERT(thread_lock_->IsOwnedByCurrentThread()); 447 ASSERT(thread_lock_->IsOwnedByCurrentThread());
478 ASSERT((interrupt_bits & ~kInterruptsMask) == 0); // Must fit in mask. 448 ASSERT((interrupt_bits & ~kInterruptsMask) == 0); // Must fit in mask.
479 449
480 // Check to see if any of the requested interrupts should be deferred. 450 // Check to see if any of the requested interrupts should be deferred.
481 uword defer_bits = interrupt_bits & deferred_interrupts_mask_; 451 uword defer_bits = interrupt_bits & deferred_interrupts_mask_;
482 if (defer_bits != 0) { 452 if (defer_bits != 0) {
483 deferred_interrupts_ |= defer_bits; 453 deferred_interrupts_ |= defer_bits;
484 interrupt_bits &= ~deferred_interrupts_mask_; 454 interrupt_bits &= ~deferred_interrupts_mask_;
485 if (interrupt_bits == 0) { 455 if (interrupt_bits == 0) {
486 return; 456 return;
487 } 457 }
488 } 458 }
489 459
490 if (stack_limit_ == saved_stack_limit_) { 460 if (stack_limit_ == saved_stack_limit_) {
491 stack_limit_ = kInterruptStackLimit & ~kInterruptsMask; 461 stack_limit_ = kInterruptStackLimit & ~kInterruptsMask;
492 } 462 }
493 stack_limit_ |= interrupt_bits; 463 stack_limit_ |= interrupt_bits;
494 } 464 }
495 465
496
497 uword Thread::GetAndClearInterrupts() { 466 uword Thread::GetAndClearInterrupts() {
498 MonitorLocker ml(thread_lock_); 467 MonitorLocker ml(thread_lock_);
499 if (stack_limit_ == saved_stack_limit_) { 468 if (stack_limit_ == saved_stack_limit_) {
500 return 0; // No interrupt was requested. 469 return 0; // No interrupt was requested.
501 } 470 }
502 uword interrupt_bits = stack_limit_ & kInterruptsMask; 471 uword interrupt_bits = stack_limit_ & kInterruptsMask;
503 stack_limit_ = saved_stack_limit_; 472 stack_limit_ = saved_stack_limit_;
504 return interrupt_bits; 473 return interrupt_bits;
505 } 474 }
506 475
507
508 bool Thread::ZoneIsOwnedByThread(Zone* zone) const { 476 bool Thread::ZoneIsOwnedByThread(Zone* zone) const {
509 ASSERT(zone != NULL); 477 ASSERT(zone != NULL);
510 Zone* current = zone_; 478 Zone* current = zone_;
511 while (current != NULL) { 479 while (current != NULL) {
512 if (current == zone) { 480 if (current == zone) {
513 return true; 481 return true;
514 } 482 }
515 current = current->previous(); 483 current = current->previous();
516 } 484 }
517 return false; 485 return false;
518 } 486 }
519 487
520
521 void Thread::DeferOOBMessageInterrupts() { 488 void Thread::DeferOOBMessageInterrupts() {
522 MonitorLocker ml(thread_lock_); 489 MonitorLocker ml(thread_lock_);
523 defer_oob_messages_count_++; 490 defer_oob_messages_count_++;
524 if (defer_oob_messages_count_ > 1) { 491 if (defer_oob_messages_count_ > 1) {
525 // OOB message interrupts are already deferred. 492 // OOB message interrupts are already deferred.
526 return; 493 return;
527 } 494 }
528 ASSERT(deferred_interrupts_mask_ == 0); 495 ASSERT(deferred_interrupts_mask_ == 0);
529 deferred_interrupts_mask_ = kMessageInterrupt; 496 deferred_interrupts_mask_ = kMessageInterrupt;
530 497
531 if (stack_limit_ != saved_stack_limit_) { 498 if (stack_limit_ != saved_stack_limit_) {
532 // Defer any interrupts which are currently pending. 499 // Defer any interrupts which are currently pending.
533 deferred_interrupts_ = stack_limit_ & deferred_interrupts_mask_; 500 deferred_interrupts_ = stack_limit_ & deferred_interrupts_mask_;
534 501
535 // Clear deferrable interrupts, if present. 502 // Clear deferrable interrupts, if present.
536 stack_limit_ &= ~deferred_interrupts_mask_; 503 stack_limit_ &= ~deferred_interrupts_mask_;
537 504
538 if ((stack_limit_ & kInterruptsMask) == 0) { 505 if ((stack_limit_ & kInterruptsMask) == 0) {
539 // No other pending interrupts. Restore normal stack limit. 506 // No other pending interrupts. Restore normal stack limit.
540 stack_limit_ = saved_stack_limit_; 507 stack_limit_ = saved_stack_limit_;
541 } 508 }
542 } 509 }
543 if (FLAG_trace_service && FLAG_trace_service_verbose) { 510 if (FLAG_trace_service && FLAG_trace_service_verbose) {
544 OS::Print("[+%" Pd64 "ms] Isolate %s deferring OOB interrupts\n", 511 OS::Print("[+%" Pd64 "ms] Isolate %s deferring OOB interrupts\n",
545 Dart::UptimeMillis(), isolate()->name()); 512 Dart::UptimeMillis(), isolate()->name());
546 } 513 }
547 } 514 }
548 515
549
550 void Thread::RestoreOOBMessageInterrupts() { 516 void Thread::RestoreOOBMessageInterrupts() {
551 MonitorLocker ml(thread_lock_); 517 MonitorLocker ml(thread_lock_);
552 defer_oob_messages_count_--; 518 defer_oob_messages_count_--;
553 if (defer_oob_messages_count_ > 0) { 519 if (defer_oob_messages_count_ > 0) {
554 return; 520 return;
555 } 521 }
556 ASSERT(defer_oob_messages_count_ == 0); 522 ASSERT(defer_oob_messages_count_ == 0);
557 ASSERT(deferred_interrupts_mask_ == kMessageInterrupt); 523 ASSERT(deferred_interrupts_mask_ == kMessageInterrupt);
558 deferred_interrupts_mask_ = 0; 524 deferred_interrupts_mask_ = 0;
559 if (deferred_interrupts_ != 0) { 525 if (deferred_interrupts_ != 0) {
560 if (stack_limit_ == saved_stack_limit_) { 526 if (stack_limit_ == saved_stack_limit_) {
561 stack_limit_ = kInterruptStackLimit & ~kInterruptsMask; 527 stack_limit_ = kInterruptStackLimit & ~kInterruptsMask;
562 } 528 }
563 stack_limit_ |= deferred_interrupts_; 529 stack_limit_ |= deferred_interrupts_;
564 deferred_interrupts_ = 0; 530 deferred_interrupts_ = 0;
565 } 531 }
566 if (FLAG_trace_service && FLAG_trace_service_verbose) { 532 if (FLAG_trace_service && FLAG_trace_service_verbose) {
567 OS::Print("[+%" Pd64 "ms] Isolate %s restoring OOB interrupts\n", 533 OS::Print("[+%" Pd64 "ms] Isolate %s restoring OOB interrupts\n",
568 Dart::UptimeMillis(), isolate()->name()); 534 Dart::UptimeMillis(), isolate()->name());
569 } 535 }
570 } 536 }
571 537
572
573 RawError* Thread::HandleInterrupts() { 538 RawError* Thread::HandleInterrupts() {
574 uword interrupt_bits = GetAndClearInterrupts(); 539 uword interrupt_bits = GetAndClearInterrupts();
575 if ((interrupt_bits & kVMInterrupt) != 0) { 540 if ((interrupt_bits & kVMInterrupt) != 0) {
576 if (isolate()->store_buffer()->Overflowed()) { 541 if (isolate()->store_buffer()->Overflowed()) {
577 if (FLAG_verbose_gc) { 542 if (FLAG_verbose_gc) {
578 OS::PrintErr("Scavenge scheduled by store buffer overflow.\n"); 543 OS::PrintErr("Scavenge scheduled by store buffer overflow.\n");
579 } 544 }
580 heap()->CollectGarbage(Heap::kNew); 545 heap()->CollectGarbage(Heap::kNew);
581 } 546 }
582 } 547 }
(...skipping 12 matching lines...) Expand all
595 Thread* thread = Thread::Current(); 560 Thread* thread = Thread::Current();
596 const Error& error = Error::Handle(thread->sticky_error()); 561 const Error& error = Error::Handle(thread->sticky_error());
597 ASSERT(!error.IsNull() && error.IsUnwindError()); 562 ASSERT(!error.IsNull() && error.IsUnwindError());
598 thread->clear_sticky_error(); 563 thread->clear_sticky_error();
599 return error.raw(); 564 return error.raw();
600 } 565 }
601 } 566 }
602 return Error::null(); 567 return Error::null();
603 } 568 }
604 569
605
606 uword Thread::GetAndClearStackOverflowFlags() { 570 uword Thread::GetAndClearStackOverflowFlags() {
607 uword stack_overflow_flags = stack_overflow_flags_; 571 uword stack_overflow_flags = stack_overflow_flags_;
608 stack_overflow_flags_ = 0; 572 stack_overflow_flags_ = 0;
609 return stack_overflow_flags; 573 return stack_overflow_flags;
610 } 574 }
611 575
612
613 void Thread::StoreBufferBlockProcess(StoreBuffer::ThresholdPolicy policy) { 576 void Thread::StoreBufferBlockProcess(StoreBuffer::ThresholdPolicy policy) {
614 StoreBufferRelease(policy); 577 StoreBufferRelease(policy);
615 StoreBufferAcquire(); 578 StoreBufferAcquire();
616 } 579 }
617 580
618
619 void Thread::StoreBufferAddObject(RawObject* obj) { 581 void Thread::StoreBufferAddObject(RawObject* obj) {
620 store_buffer_block_->Push(obj); 582 store_buffer_block_->Push(obj);
621 if (store_buffer_block_->IsFull()) { 583 if (store_buffer_block_->IsFull()) {
622 StoreBufferBlockProcess(StoreBuffer::kCheckThreshold); 584 StoreBufferBlockProcess(StoreBuffer::kCheckThreshold);
623 } 585 }
624 } 586 }
625 587
626
627 void Thread::StoreBufferAddObjectGC(RawObject* obj) { 588 void Thread::StoreBufferAddObjectGC(RawObject* obj) {
628 store_buffer_block_->Push(obj); 589 store_buffer_block_->Push(obj);
629 if (store_buffer_block_->IsFull()) { 590 if (store_buffer_block_->IsFull()) {
630 StoreBufferBlockProcess(StoreBuffer::kIgnoreThreshold); 591 StoreBufferBlockProcess(StoreBuffer::kIgnoreThreshold);
631 } 592 }
632 } 593 }
633 594
634
635 void Thread::StoreBufferRelease(StoreBuffer::ThresholdPolicy policy) { 595 void Thread::StoreBufferRelease(StoreBuffer::ThresholdPolicy policy) {
636 StoreBufferBlock* block = store_buffer_block_; 596 StoreBufferBlock* block = store_buffer_block_;
637 store_buffer_block_ = NULL; 597 store_buffer_block_ = NULL;
638 isolate()->store_buffer()->PushBlock(block, policy); 598 isolate()->store_buffer()->PushBlock(block, policy);
639 } 599 }
640 600
641
642 void Thread::StoreBufferAcquire() { 601 void Thread::StoreBufferAcquire() {
643 store_buffer_block_ = isolate()->store_buffer()->PopNonFullBlock(); 602 store_buffer_block_ = isolate()->store_buffer()->PopNonFullBlock();
644 } 603 }
645 604
646
647 bool Thread::IsMutatorThread() const { 605 bool Thread::IsMutatorThread() const {
648 return ((isolate_ != NULL) && (isolate_->mutator_thread() == this)); 606 return ((isolate_ != NULL) && (isolate_->mutator_thread() == this));
649 } 607 }
650 608
651
652 bool Thread::CanCollectGarbage() const { 609 bool Thread::CanCollectGarbage() const {
653 // We grow the heap instead of triggering a garbage collection when a 610 // We grow the heap instead of triggering a garbage collection when a
654 // thread is at a safepoint in the following situations : 611 // thread is at a safepoint in the following situations :
655 // - background compiler thread finalizing and installing code 612 // - background compiler thread finalizing and installing code
656 // - disassembly of the generated code is done after compilation 613 // - disassembly of the generated code is done after compilation
657 // So essentially we state that garbage collection is possible only 614 // So essentially we state that garbage collection is possible only
658 // when we are not at a safepoint. 615 // when we are not at a safepoint.
659 return !IsAtSafepoint(); 616 return !IsAtSafepoint();
660 } 617 }
661 618
662
663 bool Thread::IsExecutingDartCode() const { 619 bool Thread::IsExecutingDartCode() const {
664 return (top_exit_frame_info() == 0) && (vm_tag() == VMTag::kDartTagId); 620 return (top_exit_frame_info() == 0) && (vm_tag() == VMTag::kDartTagId);
665 } 621 }
666 622
667
668 bool Thread::HasExitedDartCode() const { 623 bool Thread::HasExitedDartCode() const {
669 return (top_exit_frame_info() != 0) && (vm_tag() != VMTag::kDartTagId); 624 return (top_exit_frame_info() != 0) && (vm_tag() != VMTag::kDartTagId);
670 } 625 }
671 626
672
673 template <class C> 627 template <class C>
674 C* Thread::AllocateReusableHandle() { 628 C* Thread::AllocateReusableHandle() {
675 C* handle = reinterpret_cast<C*>(reusable_handles_.AllocateScopedHandle()); 629 C* handle = reinterpret_cast<C*>(reusable_handles_.AllocateScopedHandle());
676 C::initializeHandle(handle, C::null()); 630 C::initializeHandle(handle, C::null());
677 return handle; 631 return handle;
678 } 632 }
679 633
680
681 void Thread::ClearReusableHandles() { 634 void Thread::ClearReusableHandles() {
682 #define CLEAR_REUSABLE_HANDLE(object) *object##_handle_ = object::null(); 635 #define CLEAR_REUSABLE_HANDLE(object) *object##_handle_ = object::null();
683 REUSABLE_HANDLE_LIST(CLEAR_REUSABLE_HANDLE) 636 REUSABLE_HANDLE_LIST(CLEAR_REUSABLE_HANDLE)
684 #undef CLEAR_REUSABLE_HANDLE 637 #undef CLEAR_REUSABLE_HANDLE
685 } 638 }
686 639
687
688 void Thread::VisitObjectPointers(ObjectPointerVisitor* visitor, 640 void Thread::VisitObjectPointers(ObjectPointerVisitor* visitor,
689 bool validate_frames) { 641 bool validate_frames) {
690 ASSERT(visitor != NULL); 642 ASSERT(visitor != NULL);
691 643
692 if (zone_ != NULL) { 644 if (zone_ != NULL) {
693 zone_->VisitObjectPointers(visitor); 645 zone_->VisitObjectPointers(visitor);
694 } 646 }
695 647
696 // Visit objects in thread specific handles area. 648 // Visit objects in thread specific handles area.
697 reusable_handles_.VisitObjectPointers(visitor); 649 reusable_handles_.VisitObjectPointers(visitor);
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
729 // Iterate over all the stack frames and visit objects on the stack. 681 // Iterate over all the stack frames and visit objects on the stack.
730 StackFrameIterator frames_iterator(top_exit_frame_info(), validation_policy, 682 StackFrameIterator frames_iterator(top_exit_frame_info(), validation_policy,
731 this, cross_thread_policy); 683 this, cross_thread_policy);
732 StackFrame* frame = frames_iterator.NextFrame(); 684 StackFrame* frame = frames_iterator.NextFrame();
733 while (frame != NULL) { 685 while (frame != NULL) {
734 frame->VisitObjectPointers(visitor); 686 frame->VisitObjectPointers(visitor);
735 frame = frames_iterator.NextFrame(); 687 frame = frames_iterator.NextFrame();
736 } 688 }
737 } 689 }
738 690
739
740 bool Thread::CanLoadFromThread(const Object& object) { 691 bool Thread::CanLoadFromThread(const Object& object) {
741 #define CHECK_OBJECT(type_name, member_name, expr, default_init_value) \ 692 #define CHECK_OBJECT(type_name, member_name, expr, default_init_value) \
742 if (object.raw() == expr) return true; 693 if (object.raw() == expr) return true;
743 CACHED_VM_OBJECTS_LIST(CHECK_OBJECT) 694 CACHED_VM_OBJECTS_LIST(CHECK_OBJECT)
744 #undef CHECK_OBJECT 695 #undef CHECK_OBJECT
745 return false; 696 return false;
746 } 697 }
747 698
748
749 intptr_t Thread::OffsetFromThread(const Object& object) { 699 intptr_t Thread::OffsetFromThread(const Object& object) {
750 #define COMPUTE_OFFSET(type_name, member_name, expr, default_init_value) \ 700 #define COMPUTE_OFFSET(type_name, member_name, expr, default_init_value) \
751 ASSERT((expr)->IsVMHeapObject()); \ 701 ASSERT((expr)->IsVMHeapObject()); \
752 if (object.raw() == expr) return Thread::member_name##offset(); 702 if (object.raw() == expr) return Thread::member_name##offset();
753 CACHED_VM_OBJECTS_LIST(COMPUTE_OFFSET) 703 CACHED_VM_OBJECTS_LIST(COMPUTE_OFFSET)
754 #undef COMPUTE_OFFSET 704 #undef COMPUTE_OFFSET
755 UNREACHABLE(); 705 UNREACHABLE();
756 return -1; 706 return -1;
757 } 707 }
758 708
759
760 bool Thread::ObjectAtOffset(intptr_t offset, Object* object) { 709 bool Thread::ObjectAtOffset(intptr_t offset, Object* object) {
761 if (Isolate::Current() == Dart::vm_isolate()) { 710 if (Isolate::Current() == Dart::vm_isolate()) {
762 // --disassemble-stubs runs before all the references through 711 // --disassemble-stubs runs before all the references through
763 // thread have targets 712 // thread have targets
764 return false; 713 return false;
765 } 714 }
766 715
767 #define COMPUTE_OFFSET(type_name, member_name, expr, default_init_value) \ 716 #define COMPUTE_OFFSET(type_name, member_name, expr, default_init_value) \
768 if (Thread::member_name##offset() == offset) { \ 717 if (Thread::member_name##offset() == offset) { \
769 *object = expr; \ 718 *object = expr; \
770 return true; \ 719 return true; \
771 } 720 }
772 CACHED_VM_OBJECTS_LIST(COMPUTE_OFFSET) 721 CACHED_VM_OBJECTS_LIST(COMPUTE_OFFSET)
773 #undef COMPUTE_OFFSET 722 #undef COMPUTE_OFFSET
774 return false; 723 return false;
775 } 724 }
776 725
777
778 intptr_t Thread::OffsetFromThread(const RuntimeEntry* runtime_entry) { 726 intptr_t Thread::OffsetFromThread(const RuntimeEntry* runtime_entry) {
779 #define COMPUTE_OFFSET(name) \ 727 #define COMPUTE_OFFSET(name) \
780 if (runtime_entry->function() == k##name##RuntimeEntry.function()) { \ 728 if (runtime_entry->function() == k##name##RuntimeEntry.function()) { \
781 return Thread::name##_entry_point_offset(); \ 729 return Thread::name##_entry_point_offset(); \
782 } 730 }
783 RUNTIME_ENTRY_LIST(COMPUTE_OFFSET) 731 RUNTIME_ENTRY_LIST(COMPUTE_OFFSET)
784 #undef COMPUTE_OFFSET 732 #undef COMPUTE_OFFSET
785 733
786 #define COMPUTE_OFFSET(returntype, name, ...) \ 734 #define COMPUTE_OFFSET(returntype, name, ...) \
787 if (runtime_entry->function() == k##name##RuntimeEntry.function()) { \ 735 if (runtime_entry->function() == k##name##RuntimeEntry.function()) { \
788 return Thread::name##_entry_point_offset(); \ 736 return Thread::name##_entry_point_offset(); \
789 } 737 }
790 LEAF_RUNTIME_ENTRY_LIST(COMPUTE_OFFSET) 738 LEAF_RUNTIME_ENTRY_LIST(COMPUTE_OFFSET)
791 #undef COMPUTE_OFFSET 739 #undef COMPUTE_OFFSET
792 740
793 UNREACHABLE(); 741 UNREACHABLE();
794 return -1; 742 return -1;
795 } 743 }
796 744
797
798 bool Thread::IsValidHandle(Dart_Handle object) const { 745 bool Thread::IsValidHandle(Dart_Handle object) const {
799 return IsValidLocalHandle(object) || IsValidZoneHandle(object) || 746 return IsValidLocalHandle(object) || IsValidZoneHandle(object) ||
800 IsValidScopedHandle(object); 747 IsValidScopedHandle(object);
801 } 748 }
802 749
803
804 bool Thread::IsValidLocalHandle(Dart_Handle object) const { 750 bool Thread::IsValidLocalHandle(Dart_Handle object) const {
805 ApiLocalScope* scope = api_top_scope_; 751 ApiLocalScope* scope = api_top_scope_;
806 while (scope != NULL) { 752 while (scope != NULL) {
807 if (scope->local_handles()->IsValidHandle(object)) { 753 if (scope->local_handles()->IsValidHandle(object)) {
808 return true; 754 return true;
809 } 755 }
810 scope = scope->previous(); 756 scope = scope->previous();
811 } 757 }
812 return false; 758 return false;
813 } 759 }
814 760
815
816 intptr_t Thread::CountLocalHandles() const { 761 intptr_t Thread::CountLocalHandles() const {
817 intptr_t total = 0; 762 intptr_t total = 0;
818 ApiLocalScope* scope = api_top_scope_; 763 ApiLocalScope* scope = api_top_scope_;
819 while (scope != NULL) { 764 while (scope != NULL) {
820 total += scope->local_handles()->CountHandles(); 765 total += scope->local_handles()->CountHandles();
821 scope = scope->previous(); 766 scope = scope->previous();
822 } 767 }
823 return total; 768 return total;
824 } 769 }
825 770
826
827 bool Thread::IsValidZoneHandle(Dart_Handle object) const { 771 bool Thread::IsValidZoneHandle(Dart_Handle object) const {
828 Zone* zone = zone_; 772 Zone* zone = zone_;
829 while (zone != NULL) { 773 while (zone != NULL) {
830 if (zone->handles()->IsValidZoneHandle(reinterpret_cast<uword>(object))) { 774 if (zone->handles()->IsValidZoneHandle(reinterpret_cast<uword>(object))) {
831 return true; 775 return true;
832 } 776 }
833 zone = zone->previous(); 777 zone = zone->previous();
834 } 778 }
835 return false; 779 return false;
836 } 780 }
837 781
838
839 intptr_t Thread::CountZoneHandles() const { 782 intptr_t Thread::CountZoneHandles() const {
840 intptr_t count = 0; 783 intptr_t count = 0;
841 Zone* zone = zone_; 784 Zone* zone = zone_;
842 while (zone != NULL) { 785 while (zone != NULL) {
843 count += zone->handles()->CountZoneHandles(); 786 count += zone->handles()->CountZoneHandles();
844 zone = zone->previous(); 787 zone = zone->previous();
845 } 788 }
846 ASSERT(count >= 0); 789 ASSERT(count >= 0);
847 return count; 790 return count;
848 } 791 }
849 792
850
851 bool Thread::IsValidScopedHandle(Dart_Handle object) const { 793 bool Thread::IsValidScopedHandle(Dart_Handle object) const {
852 Zone* zone = zone_; 794 Zone* zone = zone_;
853 while (zone != NULL) { 795 while (zone != NULL) {
854 if (zone->handles()->IsValidScopedHandle(reinterpret_cast<uword>(object))) { 796 if (zone->handles()->IsValidScopedHandle(reinterpret_cast<uword>(object))) {
855 return true; 797 return true;
856 } 798 }
857 zone = zone->previous(); 799 zone = zone->previous();
858 } 800 }
859 return false; 801 return false;
860 } 802 }
861 803
862
863 intptr_t Thread::CountScopedHandles() const { 804 intptr_t Thread::CountScopedHandles() const {
864 intptr_t count = 0; 805 intptr_t count = 0;
865 Zone* zone = zone_; 806 Zone* zone = zone_;
866 while (zone != NULL) { 807 while (zone != NULL) {
867 count += zone->handles()->CountScopedHandles(); 808 count += zone->handles()->CountScopedHandles();
868 zone = zone->previous(); 809 zone = zone->previous();
869 } 810 }
870 ASSERT(count >= 0); 811 ASSERT(count >= 0);
871 return count; 812 return count;
872 } 813 }
873 814
874
875 int Thread::ZoneSizeInBytes() const { 815 int Thread::ZoneSizeInBytes() const {
876 int total = 0; 816 int total = 0;
877 ApiLocalScope* scope = api_top_scope_; 817 ApiLocalScope* scope = api_top_scope_;
878 while (scope != NULL) { 818 while (scope != NULL) {
879 total += scope->zone()->SizeInBytes(); 819 total += scope->zone()->SizeInBytes();
880 scope = scope->previous(); 820 scope = scope->previous();
881 } 821 }
882 return total; 822 return total;
883 } 823 }
884 824
885
886 void Thread::UnwindScopes(uword stack_marker) { 825 void Thread::UnwindScopes(uword stack_marker) {
887 // Unwind all scopes using the same stack_marker, i.e. all scopes allocated 826 // Unwind all scopes using the same stack_marker, i.e. all scopes allocated
888 // under the same top_exit_frame_info. 827 // under the same top_exit_frame_info.
889 ApiLocalScope* scope = api_top_scope_; 828 ApiLocalScope* scope = api_top_scope_;
890 while (scope != NULL && scope->stack_marker() != 0 && 829 while (scope != NULL && scope->stack_marker() != 0 &&
891 scope->stack_marker() == stack_marker) { 830 scope->stack_marker() == stack_marker) {
892 api_top_scope_ = scope->previous(); 831 api_top_scope_ = scope->previous();
893 delete scope; 832 delete scope;
894 scope = api_top_scope_; 833 scope = api_top_scope_;
895 } 834 }
896 } 835 }
897 836
898
899 void Thread::EnterSafepointUsingLock() { 837 void Thread::EnterSafepointUsingLock() {
900 isolate()->safepoint_handler()->EnterSafepointUsingLock(this); 838 isolate()->safepoint_handler()->EnterSafepointUsingLock(this);
901 } 839 }
902 840
903
904 void Thread::ExitSafepointUsingLock() { 841 void Thread::ExitSafepointUsingLock() {
905 isolate()->safepoint_handler()->ExitSafepointUsingLock(this); 842 isolate()->safepoint_handler()->ExitSafepointUsingLock(this);
906 } 843 }
907 844
908
909 void Thread::BlockForSafepoint() { 845 void Thread::BlockForSafepoint() {
910 isolate()->safepoint_handler()->BlockForSafepoint(this); 846 isolate()->safepoint_handler()->BlockForSafepoint(this);
911 } 847 }
912 848
913
914 DisableThreadInterruptsScope::DisableThreadInterruptsScope(Thread* thread) 849 DisableThreadInterruptsScope::DisableThreadInterruptsScope(Thread* thread)
915 : StackResource(thread) { 850 : StackResource(thread) {
916 if (thread != NULL) { 851 if (thread != NULL) {
917 OSThread* os_thread = thread->os_thread(); 852 OSThread* os_thread = thread->os_thread();
918 ASSERT(os_thread != NULL); 853 ASSERT(os_thread != NULL);
919 os_thread->DisableThreadInterrupts(); 854 os_thread->DisableThreadInterrupts();
920 } 855 }
921 } 856 }
922 857
923
924 DisableThreadInterruptsScope::~DisableThreadInterruptsScope() { 858 DisableThreadInterruptsScope::~DisableThreadInterruptsScope() {
925 if (thread() != NULL) { 859 if (thread() != NULL) {
926 OSThread* os_thread = thread()->os_thread(); 860 OSThread* os_thread = thread()->os_thread();
927 ASSERT(os_thread != NULL); 861 ASSERT(os_thread != NULL);
928 os_thread->EnableThreadInterrupts(); 862 os_thread->EnableThreadInterrupts();
929 } 863 }
930 } 864 }
931 865
932 } // namespace dart 866 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/thread.h ('k') | runtime/vm/thread_barrier.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698