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

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

Issue 1425093006: Revert "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
« no previous file with comments | « runtime/vm/thread.h ('k') | runtime/vm/thread_interrupter.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/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 196 matching lines...) Expand 10 before | Expand all | Expand 10 after
207 #define REUSABLE_HANDLE_SCOPE_INIT(object) 207 #define REUSABLE_HANDLE_SCOPE_INIT(object)
208 #endif // defined(DEBUG) 208 #endif // defined(DEBUG)
209 209
210 #define REUSABLE_HANDLE_INITIALIZERS(object) \ 210 #define REUSABLE_HANDLE_INITIALIZERS(object) \
211 object##_handle_(NULL), 211 object##_handle_(NULL),
212 212
213 213
214 Thread::Thread(bool init_vm_constants) 214 Thread::Thread(bool init_vm_constants)
215 : id_(OSThread::GetCurrentThreadId()), 215 : id_(OSThread::GetCurrentThreadId()),
216 join_id_(OSThread::GetCurrentThreadJoinId()), 216 join_id_(OSThread::GetCurrentThreadJoinId()),
217 thread_interrupt_disabled_(1), // Thread interrupts disabled by default. 217 thread_interrupt_callback_(NULL),
218 thread_interrupt_data_(NULL),
218 isolate_(NULL), 219 isolate_(NULL),
219 heap_(NULL), 220 heap_(NULL),
220 timeline_block_(NULL), 221 timeline_block_(NULL),
221 store_buffer_block_(NULL), 222 store_buffer_block_(NULL),
222 log_(new class Log()), 223 log_(new class Log()),
223 REUSABLE_HANDLE_LIST(REUSABLE_HANDLE_INITIALIZERS) 224 REUSABLE_HANDLE_LIST(REUSABLE_HANDLE_INITIALIZERS)
224 REUSABLE_HANDLE_LIST(REUSABLE_HANDLE_SCOPE_INIT) 225 REUSABLE_HANDLE_LIST(REUSABLE_HANDLE_SCOPE_INIT)
225 reusable_handles_(), 226 reusable_handles_(),
226 cha_(NULL), 227 cha_(NULL),
227 deopt_id_(0), 228 deopt_id_(0),
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
323 ASSERT(thread->isolate() == NULL); 324 ASSERT(thread->isolate() == NULL);
324 ASSERT(!isolate->HasMutatorThread()); 325 ASSERT(!isolate->HasMutatorThread());
325 thread->isolate_ = isolate; 326 thread->isolate_ = isolate;
326 isolate->MakeCurrentThreadMutator(thread); 327 isolate->MakeCurrentThreadMutator(thread);
327 thread->set_vm_tag(VMTag::kVMTagId); 328 thread->set_vm_tag(VMTag::kVMTagId);
328 ASSERT(thread->store_buffer_block_ == NULL); 329 ASSERT(thread->store_buffer_block_ == NULL);
329 thread->StoreBufferAcquire(); 330 thread->StoreBufferAcquire();
330 ASSERT(isolate->heap() != NULL); 331 ASSERT(isolate->heap() != NULL);
331 thread->heap_ = isolate->heap(); 332 thread->heap_ = isolate->heap();
332 thread->Schedule(isolate); 333 thread->Schedule(isolate);
333 thread->EnableThreadInterrupts(); 334 // TODO(koda): Migrate profiler interface to use Thread.
335 Profiler::BeginExecution(isolate);
334 } 336 }
335 337
336 338
337 void Thread::ExitIsolate() { 339 void Thread::ExitIsolate() {
338 Thread* thread = Thread::Current(); 340 Thread* thread = Thread::Current();
339 // TODO(koda): Audit callers; they should know whether they're in an isolate. 341 // TODO(koda): Audit callers; they should know whether they're in an isolate.
340 if (thread == NULL || thread->isolate() == NULL) return; 342 if (thread == NULL || thread->isolate() == NULL) return;
341 #if defined(DEBUG) 343 #if defined(DEBUG)
342 ASSERT(!thread->IsAnyReusableHandleScopeActive()); 344 ASSERT(!thread->IsAnyReusableHandleScopeActive());
343 #endif // DEBUG 345 #endif // DEBUG
344 thread->DisableThreadInterrupts();
345 // Clear since GC will not visit the thread once it is unscheduled. 346 // Clear since GC will not visit the thread once it is unscheduled.
346 thread->ClearReusableHandles(); 347 thread->ClearReusableHandles();
347 Isolate* isolate = thread->isolate(); 348 Isolate* isolate = thread->isolate();
349 Profiler::EndExecution(isolate);
348 thread->Unschedule(); 350 thread->Unschedule();
349 // TODO(koda): Move store_buffer_block_ into State. 351 // TODO(koda): Move store_buffer_block_ into State.
350 thread->StoreBufferRelease(); 352 thread->StoreBufferRelease();
351 if (isolate->is_runnable()) { 353 if (isolate->is_runnable()) {
352 thread->set_vm_tag(VMTag::kIdleTagId); 354 thread->set_vm_tag(VMTag::kIdleTagId);
353 } else { 355 } else {
354 thread->set_vm_tag(VMTag::kLoadWaitTagId); 356 thread->set_vm_tag(VMTag::kLoadWaitTagId);
355 } 357 }
356 isolate->ClearMutatorThread(); 358 isolate->ClearMutatorThread();
357 thread->isolate_ = NULL; 359 thread->isolate_ = NULL;
358 ASSERT(Isolate::Current() == NULL); 360 ASSERT(Isolate::Current() == NULL);
359 thread->heap_ = NULL; 361 thread->heap_ = NULL;
360 } 362 }
361 363
362 364
363 void Thread::EnterIsolateAsHelper(Isolate* isolate, bool bypass_safepoint) { 365 void Thread::EnterIsolateAsHelper(Isolate* isolate, bool bypass_safepoint) {
364 Thread* thread = Thread::Current(); 366 Thread* thread = Thread::Current();
365 ASSERT(thread != NULL); 367 ASSERT(thread != NULL);
366 ASSERT(thread->isolate() == NULL); 368 ASSERT(thread->isolate() == NULL);
367 thread->isolate_ = isolate; 369 thread->isolate_ = isolate;
368 ASSERT(thread->store_buffer_block_ == NULL); 370 ASSERT(thread->store_buffer_block_ == NULL);
369 // TODO(koda): Use StoreBufferAcquire once we properly flush before Scavenge. 371 // TODO(koda): Use StoreBufferAcquire once we properly flush before Scavenge.
370 thread->store_buffer_block_ = 372 thread->store_buffer_block_ =
371 thread->isolate()->store_buffer()->PopEmptyBlock(); 373 thread->isolate()->store_buffer()->PopEmptyBlock();
372 ASSERT(isolate->heap() != NULL); 374 ASSERT(isolate->heap() != NULL);
373 thread->heap_ = isolate->heap(); 375 thread->heap_ = isolate->heap();
376 ASSERT(thread->thread_interrupt_callback_ == NULL);
377 ASSERT(thread->thread_interrupt_data_ == NULL);
374 // Do not update isolate->mutator_thread, but perform sanity check: 378 // Do not update isolate->mutator_thread, but perform sanity check:
375 // this thread should not be both the main mutator and helper. 379 // this thread should not be both the main mutator and helper.
376 ASSERT(!thread->IsMutatorThread()); 380 ASSERT(!thread->IsMutatorThread());
377 thread->Schedule(isolate, bypass_safepoint); 381 thread->Schedule(isolate, bypass_safepoint);
378 thread->EnableThreadInterrupts();
379 } 382 }
380 383
381 384
382 void Thread::ExitIsolateAsHelper(bool bypass_safepoint) { 385 void Thread::ExitIsolateAsHelper(bool bypass_safepoint) {
383 Thread* thread = Thread::Current(); 386 Thread* thread = Thread::Current();
384 thread->DisableThreadInterrupts();
385 Isolate* isolate = thread->isolate(); 387 Isolate* isolate = thread->isolate();
386 ASSERT(isolate != NULL); 388 ASSERT(isolate != NULL);
387 thread->Unschedule(bypass_safepoint); 389 thread->Unschedule(bypass_safepoint);
388 // TODO(koda): Move store_buffer_block_ into State. 390 // TODO(koda): Move store_buffer_block_ into State.
389 thread->StoreBufferRelease(); 391 thread->StoreBufferRelease();
390 thread->isolate_ = NULL; 392 thread->isolate_ = NULL;
391 thread->heap_ = NULL; 393 thread->heap_ = NULL;
392 ASSERT(!thread->IsMutatorThread()); 394 ASSERT(!thread->IsMutatorThread());
393 } 395 }
394 396
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
438 void Thread::StoreBufferAcquire() { 440 void Thread::StoreBufferAcquire() {
439 store_buffer_block_ = isolate()->store_buffer()->PopNonFullBlock(); 441 store_buffer_block_ = isolate()->store_buffer()->PopNonFullBlock();
440 } 442 }
441 443
442 444
443 bool Thread::IsMutatorThread() const { 445 bool Thread::IsMutatorThread() const {
444 return ((isolate_ != NULL) && (isolate_->mutator_thread() == this)); 446 return ((isolate_ != NULL) && (isolate_->mutator_thread() == this));
445 } 447 }
446 448
447 449
448 bool Thread::IsExecutingDartCode() const {
449 return (top_exit_frame_info() == 0) &&
450 (vm_tag() == VMTag::kDartTagId);
451 }
452
453
454 bool Thread::HasExitedDartCode() const {
455 return (top_exit_frame_info() != 0) &&
456 (vm_tag() != VMTag::kDartTagId);
457 }
458
459
460 CHA* Thread::cha() const { 450 CHA* Thread::cha() const {
461 ASSERT(isolate_ != NULL); 451 ASSERT(isolate_ != NULL);
462 return cha_; 452 return cha_;
463 } 453 }
464 454
465 455
466 void Thread::set_cha(CHA* value) { 456 void Thread::set_cha(CHA* value) {
467 ASSERT(isolate_ != NULL); 457 ASSERT(isolate_ != NULL);
468 cha_ = value; 458 cha_ = value;
469 } 459 }
(...skipping 26 matching lines...) Expand all
496 // Visit objects in thread specific handles area. 486 // Visit objects in thread specific handles area.
497 reusable_handles_.VisitObjectPointers(visitor); 487 reusable_handles_.VisitObjectPointers(visitor);
498 488
499 if (pending_functions_ != GrowableObjectArray::null()) { 489 if (pending_functions_ != GrowableObjectArray::null()) {
500 visitor->VisitPointer( 490 visitor->VisitPointer(
501 reinterpret_cast<RawObject**>(&pending_functions_)); 491 reinterpret_cast<RawObject**>(&pending_functions_));
502 } 492 }
503 } 493 }
504 494
505 495
506 void Thread::DisableThreadInterrupts() { 496 void Thread::SetThreadInterrupter(ThreadInterruptCallback callback,
497 void* data) {
507 ASSERT(Thread::Current() == this); 498 ASSERT(Thread::Current() == this);
508 AtomicOperations::FetchAndIncrement(&thread_interrupt_disabled_); 499 thread_interrupt_callback_ = callback;
500 thread_interrupt_data_ = data;
509 } 501 }
510 502
511 503
512 void Thread::EnableThreadInterrupts() { 504 bool Thread::IsThreadInterrupterEnabled(ThreadInterruptCallback* callback,
513 ASSERT(Thread::Current() == this); 505 void** data) const {
514 uintptr_t old = 506 #if defined(TARGET_OS_WINDOWS)
515 AtomicOperations::FetchAndDecrement(&thread_interrupt_disabled_); 507 // On Windows we expect this to be called from the thread interrupter thread.
516 if (old == 1) { 508 ASSERT(id() != OSThread::GetCurrentThreadId());
517 // We just decremented from 1 to 0. 509 #else
518 // Make sure the thread interrupter is awake. 510 // On posix platforms, we expect this to be called from signal handler.
519 ThreadInterrupter::WakeUp(); 511 ASSERT(id() == OSThread::GetCurrentThreadId());
520 } 512 #endif
521 if (old == 0) { 513 ASSERT(callback != NULL);
522 // We just decremented from 0, this means we've got a mismatched pair 514 ASSERT(data != NULL);
523 // of calls to EnableThreadInterrupts and DisableThreadInterrupts. 515 *callback = thread_interrupt_callback_;
524 FATAL("Invalid call to Thread::EnableThreadInterrupts()"); 516 *data = thread_interrupt_data_;
525 } 517 return (*callback != NULL) &&
518 (*data != NULL);
526 } 519 }
527 520
528 521
529 bool Thread::ThreadInterruptsEnabled() {
530 return AtomicOperations::LoadRelaxed(&thread_interrupt_disabled_) == 0;
531 }
532
533
534 bool Thread::CanLoadFromThread(const Object& object) { 522 bool Thread::CanLoadFromThread(const Object& object) {
535 #define CHECK_OBJECT(type_name, member_name, expr, default_init_value) \ 523 #define CHECK_OBJECT(type_name, member_name, expr, default_init_value) \
536 if (object.raw() == expr) return true; 524 if (object.raw() == expr) return true;
537 CACHED_VM_OBJECTS_LIST(CHECK_OBJECT) 525 CACHED_VM_OBJECTS_LIST(CHECK_OBJECT)
538 #undef CHECK_OBJECT 526 #undef CHECK_OBJECT
539 return false; 527 return false;
540 } 528 }
541 529
542 530
543 intptr_t Thread::OffsetFromThread(const Object& object) { 531 intptr_t Thread::OffsetFromThread(const Object& object) {
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
595 583
596 Thread* ThreadIterator::Next() { 584 Thread* ThreadIterator::Next() {
597 ASSERT(Thread::thread_list_lock_ != NULL); 585 ASSERT(Thread::thread_list_lock_ != NULL);
598 ASSERT(Thread::thread_list_lock_->IsOwnedByCurrentThread()); 586 ASSERT(Thread::thread_list_lock_->IsOwnedByCurrentThread());
599 Thread* current = next_; 587 Thread* current = next_;
600 next_ = next_->thread_list_next_; 588 next_ = next_->thread_list_next_;
601 return current; 589 return current;
602 } 590 }
603 591
604 592
605 DisableThreadInterruptsScope::DisableThreadInterruptsScope(Thread* thread)
606 : StackResource(thread) {
607 if (thread != NULL) {
608 thread->DisableThreadInterrupts();
609 }
610 }
611
612
613 DisableThreadInterruptsScope::~DisableThreadInterruptsScope() {
614 if (thread() != NULL) {
615 thread()->EnableThreadInterrupts();
616 }
617 }
618
619 } // namespace dart 593 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/thread.h ('k') | runtime/vm/thread_interrupter.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698