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

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

Issue 1412733008: Switch profiler from isolates to threads (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 5 years, 1 month 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/log.h" 10 #include "vm/log.h"
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
59 while (current != NULL) { 59 while (current != NULL) {
60 ASSERT(current != thread); 60 ASSERT(current != thread);
61 current = current->thread_list_next_; 61 current = current->thread_list_next_;
62 } 62 }
63 } 63 }
64 #endif 64 #endif
65 65
66 // Insert at head of list. 66 // Insert at head of list.
67 thread->thread_list_next_ = thread_list_head_; 67 thread->thread_list_next_ = thread_list_head_;
68 thread_list_head_ = thread; 68 thread_list_head_ = thread;
69
70 // Make sure the thread interrupter is awake.
71 ThreadInterrupter::WakeUp();
69 } 72 }
70 73
71 74
72 void Thread::RemoveThreadFromList(Thread* thread) { 75 void Thread::RemoveThreadFromList(Thread* thread) {
73 ASSERT(thread != NULL); 76 ASSERT(thread != NULL);
74 ASSERT(thread->isolate() == NULL); 77 ASSERT(thread->isolate() == NULL);
75 ASSERT(thread_list_lock_ != NULL); 78 ASSERT(thread_list_lock_ != NULL);
76 MutexLocker ml(thread_list_lock_); 79 MutexLocker ml(thread_list_lock_);
77 80
78 // Handle case where |thread| is head of list. 81 // Handle case where |thread| is head of list.
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
190 #endif // defined(DEBUG) 193 #endif // defined(DEBUG)
191 194
192 #define REUSABLE_HANDLE_INITIALIZERS(object) \ 195 #define REUSABLE_HANDLE_INITIALIZERS(object) \
193 object##_handle_(NULL), 196 object##_handle_(NULL),
194 197
195 198
196 Thread::Thread(bool init_vm_constants) 199 Thread::Thread(bool init_vm_constants)
197 : id_(OSThread::GetCurrentThreadId()), 200 : id_(OSThread::GetCurrentThreadId()),
198 join_id_(OSThread::GetCurrentThreadJoinId()), 201 join_id_(OSThread::GetCurrentThreadJoinId()),
199 thread_interrupt_callback_(NULL), 202 thread_interrupt_callback_(NULL),
200 thread_interrupt_data_(NULL), 203 thread_interrupt_disabled_(0),
201 isolate_(NULL), 204 isolate_(NULL),
202 heap_(NULL), 205 heap_(NULL),
203 timeline_block_(NULL), 206 timeline_block_(NULL),
204 store_buffer_block_(NULL), 207 store_buffer_block_(NULL),
205 log_(new class Log()), 208 log_(new class Log()),
206 REUSABLE_HANDLE_LIST(REUSABLE_HANDLE_INITIALIZERS) 209 REUSABLE_HANDLE_LIST(REUSABLE_HANDLE_INITIALIZERS)
207 REUSABLE_HANDLE_LIST(REUSABLE_HANDLE_SCOPE_INIT) 210 REUSABLE_HANDLE_LIST(REUSABLE_HANDLE_SCOPE_INIT)
208 reusable_handles_(), 211 reusable_handles_(),
209 cha_(NULL), 212 cha_(NULL),
210 deopt_id_(0), 213 deopt_id_(0),
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after
349 ASSERT(thread != NULL); 352 ASSERT(thread != NULL);
350 ASSERT(thread->isolate() == NULL); 353 ASSERT(thread->isolate() == NULL);
351 thread->isolate_ = isolate; 354 thread->isolate_ = isolate;
352 ASSERT(thread->store_buffer_block_ == NULL); 355 ASSERT(thread->store_buffer_block_ == NULL);
353 // TODO(koda): Use StoreBufferAcquire once we properly flush before Scavenge. 356 // TODO(koda): Use StoreBufferAcquire once we properly flush before Scavenge.
354 thread->store_buffer_block_ = 357 thread->store_buffer_block_ =
355 thread->isolate()->store_buffer()->PopEmptyBlock(); 358 thread->isolate()->store_buffer()->PopEmptyBlock();
356 ASSERT(isolate->heap() != NULL); 359 ASSERT(isolate->heap() != NULL);
357 thread->heap_ = isolate->heap(); 360 thread->heap_ = isolate->heap();
358 ASSERT(thread->thread_interrupt_callback_ == NULL); 361 ASSERT(thread->thread_interrupt_callback_ == NULL);
359 ASSERT(thread->thread_interrupt_data_ == NULL);
360 // Do not update isolate->mutator_thread, but perform sanity check: 362 // Do not update isolate->mutator_thread, but perform sanity check:
361 // this thread should not be both the main mutator and helper. 363 // this thread should not be both the main mutator and helper.
362 ASSERT(!thread->IsMutatorThread()); 364 ASSERT(!thread->IsMutatorThread());
363 thread->Schedule(isolate, bypass_safepoint); 365 thread->Schedule(isolate, bypass_safepoint);
364 } 366 }
365 367
366 368
367 void Thread::ExitIsolateAsHelper(bool bypass_safepoint) { 369 void Thread::ExitIsolateAsHelper(bool bypass_safepoint) {
368 Thread* thread = Thread::Current(); 370 Thread* thread = Thread::Current();
369 Isolate* isolate = thread->isolate(); 371 Isolate* isolate = thread->isolate();
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
422 void Thread::StoreBufferAcquire() { 424 void Thread::StoreBufferAcquire() {
423 store_buffer_block_ = isolate()->store_buffer()->PopNonFullBlock(); 425 store_buffer_block_ = isolate()->store_buffer()->PopNonFullBlock();
424 } 426 }
425 427
426 428
427 bool Thread::IsMutatorThread() const { 429 bool Thread::IsMutatorThread() const {
428 return ((isolate_ != NULL) && (isolate_->mutator_thread() == this)); 430 return ((isolate_ != NULL) && (isolate_->mutator_thread() == this));
429 } 431 }
430 432
431 433
434 bool Thread::IsExecutingDartCode() const {
435 return (top_exit_frame_info() == 0) &&
436 (vm_tag() == VMTag::kDartTagId);
437 }
438
439
440 bool Thread::HasExitedDartCode() const {
441 return (top_exit_frame_info() != 0) &&
442 (vm_tag() != VMTag::kDartTagId);
443 }
444
445
432 CHA* Thread::cha() const { 446 CHA* Thread::cha() const {
433 ASSERT(isolate_ != NULL); 447 ASSERT(isolate_ != NULL);
434 return cha_; 448 return cha_;
435 } 449 }
436 450
437 451
438 void Thread::set_cha(CHA* value) { 452 void Thread::set_cha(CHA* value) {
439 ASSERT(isolate_ != NULL); 453 ASSERT(isolate_ != NULL);
440 cha_ = value; 454 cha_ = value;
441 } 455 }
(...skipping 26 matching lines...) Expand all
468 // Visit objects in thread specific handles area. 482 // Visit objects in thread specific handles area.
469 reusable_handles_.VisitObjectPointers(visitor); 483 reusable_handles_.VisitObjectPointers(visitor);
470 484
471 if (pending_functions_ != GrowableObjectArray::null()) { 485 if (pending_functions_ != GrowableObjectArray::null()) {
472 visitor->VisitPointer( 486 visitor->VisitPointer(
473 reinterpret_cast<RawObject**>(&pending_functions_)); 487 reinterpret_cast<RawObject**>(&pending_functions_));
474 } 488 }
475 } 489 }
476 490
477 491
478 void Thread::SetThreadInterrupter(ThreadInterruptCallback callback, 492 void Thread::DisableThreadInterrupts() {
479 void* data) {
480 ASSERT(Thread::Current() == this); 493 ASSERT(Thread::Current() == this);
481 thread_interrupt_callback_ = callback; 494 AtomicOperations::FetchAndIncrement(&thread_interrupt_disabled_);
482 thread_interrupt_data_ = data;
483 } 495 }
484 496
485 497
486 bool Thread::IsThreadInterrupterEnabled(ThreadInterruptCallback* callback, 498 void Thread::EnableThreadInterrupts() {
487 void** data) const { 499 ASSERT(Thread::Current() == this);
500 uintptr_t old =
501 AtomicOperations::FetchAndDecrement(&thread_interrupt_disabled_);
502 if (old == 1) {
503 // We just decremented from 1 to 0.
504 // Make sure the thread interrupter is awake.
505 ThreadInterrupter::WakeUp();
506 }
507 if (old == 0) {
508 // We just decremented from 0, this means we've got a mismatched pair
509 // of calls to EnableThreadInterrupts and DisableThreadInterrupts.
510 FATAL("Invalid call to Thread::EnableThreadInterrupts()");
511 }
512 }
513
514
515 bool Thread::ThreadInterruptsEnabled() {
516 return AtomicOperations::LoadRelaxed(&thread_interrupt_disabled_) == 0;
517 }
518
519
520 void Thread::SetThreadInterruptCallback(ThreadInterruptCallback callback) {
521 ASSERT(Thread::Current() == this);
522 thread_interrupt_callback_ = callback;
523 }
524
525
526 bool Thread::GetThreadInterruptCallback(
527 ThreadInterruptCallback* callback) const {
488 #if defined(TARGET_OS_WINDOWS) 528 #if defined(TARGET_OS_WINDOWS)
489 // On Windows we expect this to be called from the thread interrupter thread. 529 // On Windows we expect this to be called from the thread interrupter thread.
490 ASSERT(id() != OSThread::GetCurrentThreadId()); 530 ASSERT(id() != OSThread::GetCurrentThreadId());
491 #else 531 #else
492 // On posix platforms, we expect this to be called from signal handler. 532 // On posix platforms, we expect this to be called from signal handler.
493 ASSERT(id() == OSThread::GetCurrentThreadId()); 533 ASSERT(id() == OSThread::GetCurrentThreadId());
494 #endif 534 #endif
495 ASSERT(callback != NULL); 535 ASSERT(callback != NULL);
496 ASSERT(data != NULL);
497 *callback = thread_interrupt_callback_; 536 *callback = thread_interrupt_callback_;
498 *data = thread_interrupt_data_; 537 return (*callback != NULL);
499 return (*callback != NULL) &&
500 (*data != NULL);
501 } 538 }
502 539
503 540
504 bool Thread::CanLoadFromThread(const Object& object) { 541 bool Thread::CanLoadFromThread(const Object& object) {
505 #define CHECK_OBJECT(type_name, member_name, expr, default_init_value) \ 542 #define CHECK_OBJECT(type_name, member_name, expr, default_init_value) \
506 if (object.raw() == expr) return true; 543 if (object.raw() == expr) return true;
507 CACHED_VM_OBJECTS_LIST(CHECK_OBJECT) 544 CACHED_VM_OBJECTS_LIST(CHECK_OBJECT)
508 #undef CHECK_OBJECT 545 #undef CHECK_OBJECT
509 return false; 546 return false;
510 } 547 }
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
566 Thread* ThreadIterator::Next() { 603 Thread* ThreadIterator::Next() {
567 ASSERT(Thread::thread_list_lock_ != NULL); 604 ASSERT(Thread::thread_list_lock_ != NULL);
568 ASSERT(Thread::thread_list_lock_->IsOwnedByCurrentThread()); 605 ASSERT(Thread::thread_list_lock_->IsOwnedByCurrentThread());
569 Thread* current = next_; 606 Thread* current = next_;
570 next_ = next_->thread_list_next_; 607 next_ = next_->thread_list_next_;
571 return current; 608 return current;
572 } 609 }
573 610
574 611
575 } // namespace dart 612 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698