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

Side by Side Diff: src/sampler.cc

Issue 14238007: Unify Sampler implementation across platforms using signals to suspend thread (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Removed empty line Created 7 years, 8 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.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2013 the V8 project authors. All rights reserved. 1 // Copyright 2013 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 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
62 #include "log.h" 62 #include "log.h"
63 #include "platform.h" 63 #include "platform.h"
64 #include "simulator.h" 64 #include "simulator.h"
65 #include "v8threads.h" 65 #include "v8threads.h"
66 66
67 67
68 namespace v8 { 68 namespace v8 {
69 namespace internal { 69 namespace internal {
70 70
71 71
72 #if defined(__linux__) || defined(__FreeBSD__) || defined(__OpenBSD__) \ 72 #if defined(USE_SIGNALS)
73 || defined(__NetBSD__) || defined(__sun) || defined(__ANDROID__)
74 73
75 #if defined(__ANDROID__) && !defined(__BIONIC_HAVE_UCONTEXT_T) 74 #if defined(__ANDROID__) && !defined(__BIONIC_HAVE_UCONTEXT_T)
76 75
77 // Not all versions of Android's C library provide ucontext_t. 76 // Not all versions of Android's C library provide ucontext_t.
78 // Detect this and provide custom but compatible definitions. Note that these 77 // Detect this and provide custom but compatible definitions. Note that these
79 // follow the GLibc naming convention to access register values from 78 // follow the GLibc naming convention to access register values from
80 // mcontext_t. 79 // mcontext_t.
81 // 80 //
82 // See http://code.google.com/p/android/issues/detail?id=34784 81 // See http://code.google.com/p/android/issues/detail?id=34784
83 82
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
140 stack_t uc_stack; 139 stack_t uc_stack;
141 mcontext_t uc_mcontext; 140 mcontext_t uc_mcontext;
142 // Other fields are not used by V8, don't define them here. 141 // Other fields are not used by V8, don't define them here.
143 } ucontext_t; 142 } ucontext_t;
144 enum { REG_EBP = 6, REG_ESP = 7, REG_EIP = 14 }; 143 enum { REG_EBP = 6, REG_ESP = 7, REG_EIP = 14 };
145 #endif 144 #endif
146 145
147 #endif // __ANDROID__ && !defined(__BIONIC_HAVE_UCONTEXT_T) 146 #endif // __ANDROID__ && !defined(__BIONIC_HAVE_UCONTEXT_T)
148 147
149 148
150 static pthread_t GetThreadID() {
151 #if defined(__ANDROID__)
152 // Android's C library provides gettid(2).
153 return gettid();
154 #elif defined(__linux__)
155 // Glibc doesn't provide a wrapper for gettid(2).
156 return syscall(SYS_gettid);
157 #elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) \
158 || defined(__sun)
159 return pthread_self();
160 #endif
161 }
162
163
164 class Sampler::PlatformData : public Malloced { 149 class Sampler::PlatformData : public Malloced {
165 public: 150 public:
166 PlatformData() 151 PlatformData()
167 : vm_tid_(GetThreadID()), 152 : vm_tid_(pthread_self()),
168 vm_tgid_(getpid()),
169 profiled_thread_id_(ThreadId::Current()) {} 153 profiled_thread_id_(ThreadId::Current()) {}
170 154
171 pthread_t vm_tid() const { return vm_tid_; } 155 pthread_t vm_tid() const { return vm_tid_; }
172 int vm_tgid() const { return vm_tgid_; }
173 ThreadId profiled_thread_id() { return profiled_thread_id_; } 156 ThreadId profiled_thread_id() { return profiled_thread_id_; }
174 157
175 private: 158 private:
176 pthread_t vm_tid_; 159 pthread_t vm_tid_;
177 const int vm_tgid_;
178 ThreadId profiled_thread_id_; 160 ThreadId profiled_thread_id_;
179 }; 161 };
180 162
181 163
182 static void ProfilerSignalHandler(int signal, siginfo_t* info, void* context) { 164 static void ProfilerSignalHandler(int signal, siginfo_t* info, void* context) {
183 #if defined(__native_client__) 165 #if defined(__native_client__)
184 // As Native Client does not support signal handling, profiling 166 // As Native Client does not support signal handling, profiling
185 // is disabled. 167 // is disabled.
186 return; 168 return;
187 #else 169 #else
(...skipping 245 matching lines...) Expand 10 before | Expand all | Expand 10 after
433 if (state == SamplerRegistry::HAS_CPU_PROFILING_SAMPLERS) { 415 if (state == SamplerRegistry::HAS_CPU_PROFILING_SAMPLERS) {
434 #if defined(USE_SIGNALS) 416 #if defined(USE_SIGNALS)
435 if (!signal_handler_installed_) InstallSignalHandler(); 417 if (!signal_handler_installed_) InstallSignalHandler();
436 #endif 418 #endif
437 SamplerRegistry::IterateActiveSamplers(&DoCpuProfile, this); 419 SamplerRegistry::IterateActiveSamplers(&DoCpuProfile, this);
438 } else { 420 } else {
439 #if defined(USE_SIGNALS) 421 #if defined(USE_SIGNALS)
440 if (signal_handler_installed_) RestoreSignalHandler(); 422 if (signal_handler_installed_) RestoreSignalHandler();
441 #endif 423 #endif
442 } 424 }
443 Sleep(); // TODO(svenpanne) Figure out if OS:Sleep(interval_) is enough. 425 OS::Sleep(interval_);
444 } 426 }
445 } 427 }
446 428
447 static void DoCpuProfile(Sampler* sampler, void* raw_sender) { 429 static void DoCpuProfile(Sampler* sampler, void* raw_sender) {
448 if (!sampler->isolate()->IsInitialized()) return; 430 if (!sampler->isolate()->IsInitialized()) return;
449 if (!sampler->IsProfiling()) return; 431 if (!sampler->IsProfiling()) return;
450 SamplerThread* sender = reinterpret_cast<SamplerThread*>(raw_sender); 432 SamplerThread* sender = reinterpret_cast<SamplerThread*>(raw_sender);
451 sender->SampleContext(sampler); 433 sender->SampleContext(sampler);
452 } 434 }
453 435
454 #if defined(USE_SIGNALS) 436 #if defined(USE_SIGNALS)
437
455 void SampleContext(Sampler* sampler) { 438 void SampleContext(Sampler* sampler) {
456 if (!signal_handler_installed_) return; 439 if (!signal_handler_installed_) return;
457 Sampler::PlatformData* platform_data = sampler->platform_data(); 440 pthread_t tid = sampler->platform_data()->vm_tid();
458 int tid = platform_data->vm_tid(); 441 int result = pthread_kill(tid, SIGPROF);
459 // Glibc doesn't provide a wrapper for tgkill(2).
460 #if defined(ANDROID)
461 syscall(__NR_tgkill, platform_data->vm_tgid(), tid, SIGPROF);
462 #elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) \
463 || defined(__sun)
464 pthread_kill(tid, SIGPROF);
465 #else
466 int result = syscall(SYS_tgkill, platform_data->vm_tgid(), tid, SIGPROF);
467 USE(result); 442 USE(result);
468 ASSERT(result == 0); 443 ASSERT(result == 0);
469 #endif
470 }
471
472 void Sleep() {
473 // Convert ms to us and subtract 100 us to compensate delays
474 // occuring during signal delivery.
475 useconds_t interval = interval_ * 1000 - 100;
476 #if defined(ANDROID)
477 usleep(interval);
478 #else
479 int result = usleep(interval);
480 #ifdef DEBUG
481 if (result != 0 && errno != EINTR) {
482 fprintf(stderr,
483 "SamplerThread usleep error; interval = %u, errno = %d\n",
484 interval,
485 errno);
486 ASSERT(result == 0 || errno == EINTR);
487 }
488 #endif // DEBUG
489 USE(result);
490 #endif // ANDROID
491 } 444 }
492 445
493 #elif defined(__MACH__) 446 #elif defined(__MACH__)
494 447
495 void SampleContext(Sampler* sampler) { 448 void SampleContext(Sampler* sampler) {
496 thread_act_t profiled_thread = sampler->platform_data()->profiled_thread(); 449 thread_act_t profiled_thread = sampler->platform_data()->profiled_thread();
497 Isolate* isolate = sampler->isolate(); 450 Isolate* isolate = sampler->isolate();
498 #if defined(USE_SIMULATOR) 451 #if defined(USE_SIMULATOR)
499 #if V8_TARGET_ARCH_ARM || V8_TARGET_ARCH_MIPS 452 #if V8_TARGET_ARCH_ARM || V8_TARGET_ARCH_MIPS
500 ThreadId thread_id = sampler->platform_data()->profiled_thread_id(); 453 ThreadId thread_id = sampler->platform_data()->profiled_thread_id();
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
554 sample->sp = reinterpret_cast<Address>(state.REGISTER_FIELD(sp)); 507 sample->sp = reinterpret_cast<Address>(state.REGISTER_FIELD(sp));
555 sample->fp = reinterpret_cast<Address>(state.REGISTER_FIELD(bp)); 508 sample->fp = reinterpret_cast<Address>(state.REGISTER_FIELD(bp));
556 #endif // USE_SIMULATOR 509 #endif // USE_SIMULATOR
557 #undef REGISTER_FIELD 510 #undef REGISTER_FIELD
558 sampler->SampleStack(sample); 511 sampler->SampleStack(sample);
559 sampler->Tick(sample); 512 sampler->Tick(sample);
560 } 513 }
561 thread_resume(profiled_thread); 514 thread_resume(profiled_thread);
562 } 515 }
563 516
564 void Sleep() {
565 OS::Sleep(interval_);
566 }
567
568 #elif defined(_WIN32) || defined(_WIN64) || defined(__CYGWIN__) 517 #elif defined(_WIN32) || defined(_WIN64) || defined(__CYGWIN__)
569 518
570 void SampleContext(Sampler* sampler) { 519 void SampleContext(Sampler* sampler) {
571 HANDLE profiled_thread = sampler->platform_data()->profiled_thread(); 520 HANDLE profiled_thread = sampler->platform_data()->profiled_thread();
572 if (profiled_thread == NULL) return; 521 if (profiled_thread == NULL) return;
573 522
574 // Context used for sampling the register state of the profiled thread. 523 // Context used for sampling the register state of the profiled thread.
575 CONTEXT context; 524 CONTEXT context;
576 memset(&context, 0, sizeof(context)); 525 memset(&context, 0, sizeof(context));
577 526
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
617 sample->sp = reinterpret_cast<Address>(context.Esp); 566 sample->sp = reinterpret_cast<Address>(context.Esp);
618 sample->fp = reinterpret_cast<Address>(context.Ebp); 567 sample->fp = reinterpret_cast<Address>(context.Ebp);
619 #endif 568 #endif
620 #endif // USE_SIMULATOR 569 #endif // USE_SIMULATOR
621 sampler->SampleStack(sample); 570 sampler->SampleStack(sample);
622 sampler->Tick(sample); 571 sampler->Tick(sample);
623 } 572 }
624 ResumeThread(profiled_thread); 573 ResumeThread(profiled_thread);
625 } 574 }
626 575
627 void Sleep() {
628 OS::Sleep(interval_);
629 }
630
631 #endif // USE_SIGNALS 576 #endif // USE_SIGNALS
632 577
633 const int interval_; 578 const int interval_;
634 579
635 // Protects the process wide state below. 580 // Protects the process wide state below.
636 static Mutex* mutex_; 581 static Mutex* mutex_;
637 static SamplerThread* instance_; 582 static SamplerThread* instance_;
638 #if defined(USE_SIGNALS) 583 #if defined(USE_SIGNALS)
639 static bool signal_handler_installed_; 584 static bool signal_handler_installed_;
640 static struct sigaction old_signal_handler_; 585 static struct sigaction old_signal_handler_;
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
690 SamplerThread::RemoveActiveSampler(this); 635 SamplerThread::RemoveActiveSampler(this);
691 SetActive(false); 636 SetActive(false);
692 } 637 }
693 638
694 void Sampler::SampleStack(TickSample* sample) { 639 void Sampler::SampleStack(TickSample* sample) {
695 StackTracer::Trace(isolate_, sample); 640 StackTracer::Trace(isolate_, sample);
696 if (++samples_taken_ < 0) samples_taken_ = 0; 641 if (++samples_taken_ < 0) samples_taken_ = 0;
697 } 642 }
698 643
699 } } // namespace v8::internal 644 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/platform.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698