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

Side by Side Diff: src/platform-macos.cc

Issue 3845006: Try to simplify the semantics of the profiling code by making... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: Created 10 years, 2 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 | Annotate | Revision Log
« no previous file with comments | « src/platform-linux.cc ('k') | src/platform-win32.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 2006-2008 the V8 project authors. All rights reserved. 1 // Copyright 2006-2008 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 531 matching lines...) Expand 10 before | Expand all | Expand 10 after
542 Sampler* sampler_; 542 Sampler* sampler_;
543 // Note: for profiled_thread_ Mach primitives are used instead of PThread's 543 // Note: for profiled_thread_ Mach primitives are used instead of PThread's
544 // because the latter doesn't provide thread manipulation primitives required. 544 // because the latter doesn't provide thread manipulation primitives required.
545 // For details, consult "Mac OS X Internals" book, Section 7.3. 545 // For details, consult "Mac OS X Internals" book, Section 7.3.
546 mach_port_t task_self_; 546 mach_port_t task_self_;
547 thread_act_t profiled_thread_; 547 thread_act_t profiled_thread_;
548 pthread_t sampler_thread_; 548 pthread_t sampler_thread_;
549 549
550 // Sampler thread handler. 550 // Sampler thread handler.
551 void Runner() { 551 void Runner() {
552 // Loop until the sampler is disengaged, keeping the specified samling freq. 552 // Loop until the sampler is disengaged, keeping the specified
553 // sampling frequency.
553 for ( ; sampler_->IsActive(); OS::Sleep(sampler_->interval_)) { 554 for ( ; sampler_->IsActive(); OS::Sleep(sampler_->interval_)) {
554 TickSample sample_obj; 555 TickSample sample_obj;
555 TickSample* sample = CpuProfiler::TickSampleEvent(); 556 TickSample* sample = CpuProfiler::TickSampleEvent();
556 if (sample == NULL) sample = &sample_obj; 557 if (sample == NULL) sample = &sample_obj;
557 558
559 // If the sampler runs in sync with the JS thread, we try to
560 // suspend it. If we fail, we skip the current sample.
561 if (sampler_->IsSynchronous()) {
562 if (KERN_SUCCESS != thread_suspend(profiled_thread_)) continue;
563 }
564
558 // We always sample the VM state. 565 // We always sample the VM state.
559 sample->state = VMState::current_state(); 566 sample->state = VMState::current_state();
567
560 // If profiling, we record the pc and sp of the profiled thread. 568 // If profiling, we record the pc and sp of the profiled thread.
561 if (sampler_->IsProfiling() 569 if (sampler_->IsProfiling()) {
562 && KERN_SUCCESS == thread_suspend(profiled_thread_)) {
563 #if V8_HOST_ARCH_X64 570 #if V8_HOST_ARCH_X64
564 thread_state_flavor_t flavor = x86_THREAD_STATE64; 571 thread_state_flavor_t flavor = x86_THREAD_STATE64;
565 x86_thread_state64_t state; 572 x86_thread_state64_t state;
566 mach_msg_type_number_t count = x86_THREAD_STATE64_COUNT; 573 mach_msg_type_number_t count = x86_THREAD_STATE64_COUNT;
567 #if __DARWIN_UNIX03 574 #if __DARWIN_UNIX03
568 #define REGISTER_FIELD(name) __r ## name 575 #define REGISTER_FIELD(name) __r ## name
569 #else 576 #else
570 #define REGISTER_FIELD(name) r ## name 577 #define REGISTER_FIELD(name) r ## name
571 #endif // __DARWIN_UNIX03 578 #endif // __DARWIN_UNIX03
572 #elif V8_HOST_ARCH_IA32 579 #elif V8_HOST_ARCH_IA32
(...skipping 11 matching lines...) Expand all
584 591
585 if (thread_get_state(profiled_thread_, 592 if (thread_get_state(profiled_thread_,
586 flavor, 593 flavor,
587 reinterpret_cast<natural_t*>(&state), 594 reinterpret_cast<natural_t*>(&state),
588 &count) == KERN_SUCCESS) { 595 &count) == KERN_SUCCESS) {
589 sample->pc = reinterpret_cast<Address>(state.REGISTER_FIELD(ip)); 596 sample->pc = reinterpret_cast<Address>(state.REGISTER_FIELD(ip));
590 sample->sp = reinterpret_cast<Address>(state.REGISTER_FIELD(sp)); 597 sample->sp = reinterpret_cast<Address>(state.REGISTER_FIELD(sp));
591 sample->fp = reinterpret_cast<Address>(state.REGISTER_FIELD(bp)); 598 sample->fp = reinterpret_cast<Address>(state.REGISTER_FIELD(bp));
592 sampler_->SampleStack(sample); 599 sampler_->SampleStack(sample);
593 } 600 }
594 thread_resume(profiled_thread_);
595 } 601 }
596 602
597 // Invoke tick handler with program counter and stack pointer. 603 // Invoke tick handler with program counter and stack pointer.
598 sampler_->Tick(sample); 604 sampler_->Tick(sample);
605
606 // If the sampler runs in sync with the JS thread, we have to
607 // remember to resume it.
608 if (sampler_->IsSynchronous()) thread_resume(profiled_thread_);
599 } 609 }
600 } 610 }
601 }; 611 };
602 612
603 #undef REGISTER_FIELD 613 #undef REGISTER_FIELD
604 614
605 615
606 // Entry point for sampler thread. 616 // Entry point for sampler thread.
607 static void* SamplerEntry(void* arg) { 617 static void* SamplerEntry(void* arg) {
608 Sampler::PlatformData* data = 618 Sampler::PlatformData* data =
609 reinterpret_cast<Sampler::PlatformData*>(arg); 619 reinterpret_cast<Sampler::PlatformData*>(arg);
610 data->Runner(); 620 data->Runner();
611 return 0; 621 return 0;
612 } 622 }
613 623
614 624
615 Sampler::Sampler(int interval, bool profiling) 625 Sampler::Sampler(int interval, bool profiling)
616 : interval_(interval), profiling_(profiling), active_(false) { 626 : interval_(interval),
627 profiling_(profiling),
628 synchronous_(profiling),
629 active_(false) {
617 data_ = new PlatformData(this); 630 data_ = new PlatformData(this);
618 } 631 }
619 632
620 633
621 Sampler::~Sampler() { 634 Sampler::~Sampler() {
622 delete data_; 635 delete data_;
623 } 636 }
624 637
625 638
626 void Sampler::Start() { 639 void Sampler::Start() {
627 // If we are profiling, we need to be able to access the calling 640 // If we are starting a synchronous sampler, we need to be able to
628 // thread. 641 // access the calling thread.
629 if (IsProfiling()) { 642 if (IsSynchronous()) {
630 data_->profiled_thread_ = mach_thread_self(); 643 data_->profiled_thread_ = mach_thread_self();
631 } 644 }
632 645
633 // Create sampler thread with high priority. 646 // Create sampler thread with high priority.
634 // According to POSIX spec, when SCHED_FIFO policy is used, a thread 647 // According to POSIX spec, when SCHED_FIFO policy is used, a thread
635 // runs until it exits or blocks. 648 // runs until it exits or blocks.
636 pthread_attr_t sched_attr; 649 pthread_attr_t sched_attr;
637 sched_param fifo_param; 650 sched_param fifo_param;
638 pthread_attr_init(&sched_attr); 651 pthread_attr_init(&sched_attr);
639 pthread_attr_setinheritsched(&sched_attr, PTHREAD_EXPLICIT_SCHED); 652 pthread_attr_setinheritsched(&sched_attr, PTHREAD_EXPLICIT_SCHED);
640 pthread_attr_setschedpolicy(&sched_attr, SCHED_FIFO); 653 pthread_attr_setschedpolicy(&sched_attr, SCHED_FIFO);
641 fifo_param.sched_priority = sched_get_priority_max(SCHED_FIFO); 654 fifo_param.sched_priority = sched_get_priority_max(SCHED_FIFO);
642 pthread_attr_setschedparam(&sched_attr, &fifo_param); 655 pthread_attr_setschedparam(&sched_attr, &fifo_param);
643 656
644 active_ = true; 657 active_ = true;
645 pthread_create(&data_->sampler_thread_, &sched_attr, SamplerEntry, data_); 658 pthread_create(&data_->sampler_thread_, &sched_attr, SamplerEntry, data_);
646 } 659 }
647 660
648 661
649 void Sampler::Stop() { 662 void Sampler::Stop() {
650 // Seting active to false triggers termination of the sampler 663 // Seting active to false triggers termination of the sampler
651 // thread. 664 // thread.
652 active_ = false; 665 active_ = false;
653 666
654 // Wait for sampler thread to terminate. 667 // Wait for sampler thread to terminate.
655 pthread_join(data_->sampler_thread_, NULL); 668 pthread_join(data_->sampler_thread_, NULL);
656 669
657 // Deallocate Mach port for thread. 670 // Deallocate Mach port for thread.
658 if (IsProfiling()) { 671 if (IsSynchronous()) {
659 mach_port_deallocate(data_->task_self_, data_->profiled_thread_); 672 mach_port_deallocate(data_->task_self_, data_->profiled_thread_);
660 } 673 }
661 } 674 }
662 675
663 #endif // ENABLE_LOGGING_AND_PROFILING 676 #endif // ENABLE_LOGGING_AND_PROFILING
664 677
665 } } // namespace v8::internal 678 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/platform-linux.cc ('k') | src/platform-win32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698