OLD | NEW |
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/sampler.h" | 5 #include "src/sampler.h" |
6 | 6 |
7 #if V8_OS_POSIX && !V8_OS_CYGWIN | 7 #if V8_OS_POSIX && !V8_OS_CYGWIN |
8 | 8 |
9 #define USE_SIGNALS | 9 #define USE_SIGNALS |
10 | 10 |
(...skipping 26 matching lines...) Expand all Loading... |
37 #endif | 37 #endif |
38 | 38 |
39 #elif V8_OS_WIN || V8_OS_CYGWIN | 39 #elif V8_OS_WIN || V8_OS_CYGWIN |
40 | 40 |
41 #include "src/base/win32-headers.h" | 41 #include "src/base/win32-headers.h" |
42 | 42 |
43 #endif | 43 #endif |
44 | 44 |
45 #include "src/v8.h" | 45 #include "src/v8.h" |
46 | 46 |
| 47 #include "src/base/platform/platform.h" |
47 #include "src/cpu-profiler-inl.h" | 48 #include "src/cpu-profiler-inl.h" |
48 #include "src/flags.h" | 49 #include "src/flags.h" |
49 #include "src/frames-inl.h" | 50 #include "src/frames-inl.h" |
50 #include "src/log.h" | 51 #include "src/log.h" |
51 #include "src/platform.h" | |
52 #include "src/simulator.h" | 52 #include "src/simulator.h" |
53 #include "src/v8threads.h" | 53 #include "src/v8threads.h" |
54 #include "src/vm-state-inl.h" | 54 #include "src/vm-state-inl.h" |
55 | 55 |
56 | 56 |
57 #if V8_OS_ANDROID && !defined(__BIONIC_HAVE_UCONTEXT_T) | 57 #if V8_OS_ANDROID && !defined(__BIONIC_HAVE_UCONTEXT_T) |
58 | 58 |
59 // Not all versions of Android's C library provide ucontext_t. | 59 // Not all versions of Android's C library provide ucontext_t. |
60 // Detect this and provide custom but compatible definitions. Note that these | 60 // Detect this and provide custom but compatible definitions. Note that these |
61 // follow the GLibc naming convention to access register values from | 61 // follow the GLibc naming convention to access register values from |
(...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
262 private: | 262 private: |
263 Simulator* simulator_; | 263 Simulator* simulator_; |
264 }; | 264 }; |
265 #endif // USE_SIMULATOR | 265 #endif // USE_SIMULATOR |
266 | 266 |
267 | 267 |
268 #if defined(USE_SIGNALS) | 268 #if defined(USE_SIGNALS) |
269 | 269 |
270 class SignalHandler : public AllStatic { | 270 class SignalHandler : public AllStatic { |
271 public: | 271 public: |
272 static void SetUp() { if (!mutex_) mutex_ = new Mutex(); } | 272 static void SetUp() { if (!mutex_) mutex_ = new base::Mutex(); } |
273 static void TearDown() { delete mutex_; } | 273 static void TearDown() { delete mutex_; } |
274 | 274 |
275 static void IncreaseSamplerCount() { | 275 static void IncreaseSamplerCount() { |
276 LockGuard<Mutex> lock_guard(mutex_); | 276 base::LockGuard<base::Mutex> lock_guard(mutex_); |
277 if (++client_count_ == 1) Install(); | 277 if (++client_count_ == 1) Install(); |
278 } | 278 } |
279 | 279 |
280 static void DecreaseSamplerCount() { | 280 static void DecreaseSamplerCount() { |
281 LockGuard<Mutex> lock_guard(mutex_); | 281 base::LockGuard<base::Mutex> lock_guard(mutex_); |
282 if (--client_count_ == 0) Restore(); | 282 if (--client_count_ == 0) Restore(); |
283 } | 283 } |
284 | 284 |
285 static bool Installed() { | 285 static bool Installed() { |
286 return signal_handler_installed_; | 286 return signal_handler_installed_; |
287 } | 287 } |
288 | 288 |
289 private: | 289 private: |
290 static void Install() { | 290 static void Install() { |
291 struct sigaction sa; | 291 struct sigaction sa; |
(...skipping 10 matching lines...) Expand all Loading... |
302 | 302 |
303 static void Restore() { | 303 static void Restore() { |
304 if (signal_handler_installed_) { | 304 if (signal_handler_installed_) { |
305 sigaction(SIGPROF, &old_signal_handler_, 0); | 305 sigaction(SIGPROF, &old_signal_handler_, 0); |
306 signal_handler_installed_ = false; | 306 signal_handler_installed_ = false; |
307 } | 307 } |
308 } | 308 } |
309 | 309 |
310 static void HandleProfilerSignal(int signal, siginfo_t* info, void* context); | 310 static void HandleProfilerSignal(int signal, siginfo_t* info, void* context); |
311 // Protects the process wide state below. | 311 // Protects the process wide state below. |
312 static Mutex* mutex_; | 312 static base::Mutex* mutex_; |
313 static int client_count_; | 313 static int client_count_; |
314 static bool signal_handler_installed_; | 314 static bool signal_handler_installed_; |
315 static struct sigaction old_signal_handler_; | 315 static struct sigaction old_signal_handler_; |
316 }; | 316 }; |
317 | 317 |
318 | 318 |
319 Mutex* SignalHandler::mutex_ = NULL; | 319 base::Mutex* SignalHandler::mutex_ = NULL; |
320 int SignalHandler::client_count_ = 0; | 320 int SignalHandler::client_count_ = 0; |
321 struct sigaction SignalHandler::old_signal_handler_; | 321 struct sigaction SignalHandler::old_signal_handler_; |
322 bool SignalHandler::signal_handler_installed_ = false; | 322 bool SignalHandler::signal_handler_installed_ = false; |
323 | 323 |
324 | 324 |
325 void SignalHandler::HandleProfilerSignal(int signal, siginfo_t* info, | 325 void SignalHandler::HandleProfilerSignal(int signal, siginfo_t* info, |
326 void* context) { | 326 void* context) { |
327 #if V8_OS_NACL | 327 #if V8_OS_NACL |
328 // As Native Client does not support signal handling, profiling | 328 // As Native Client does not support signal handling, profiling |
329 // is disabled. | 329 // is disabled. |
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
466 #endif // V8_HOST_ARCH_* | 466 #endif // V8_HOST_ARCH_* |
467 #endif // V8_OS_QNX | 467 #endif // V8_OS_QNX |
468 #endif // USE_SIMULATOR | 468 #endif // USE_SIMULATOR |
469 sampler->SampleStack(state); | 469 sampler->SampleStack(state); |
470 #endif // V8_OS_NACL | 470 #endif // V8_OS_NACL |
471 } | 471 } |
472 | 472 |
473 #endif | 473 #endif |
474 | 474 |
475 | 475 |
476 class SamplerThread : public Thread { | 476 class SamplerThread : public base::Thread { |
477 public: | 477 public: |
478 static const int kSamplerThreadStackSize = 64 * KB; | 478 static const int kSamplerThreadStackSize = 64 * KB; |
479 | 479 |
480 explicit SamplerThread(int interval) | 480 explicit SamplerThread(int interval) |
481 : Thread(Thread::Options("SamplerThread", kSamplerThreadStackSize)), | 481 : Thread(base::Thread::Options("SamplerThread", kSamplerThreadStackSize)), |
482 interval_(interval) {} | 482 interval_(interval) {} |
483 | 483 |
484 static void SetUp() { if (!mutex_) mutex_ = new Mutex(); } | 484 static void SetUp() { if (!mutex_) mutex_ = new base::Mutex(); } |
485 static void TearDown() { delete mutex_; mutex_ = NULL; } | 485 static void TearDown() { delete mutex_; mutex_ = NULL; } |
486 | 486 |
487 static void AddActiveSampler(Sampler* sampler) { | 487 static void AddActiveSampler(Sampler* sampler) { |
488 bool need_to_start = false; | 488 bool need_to_start = false; |
489 LockGuard<Mutex> lock_guard(mutex_); | 489 base::LockGuard<base::Mutex> lock_guard(mutex_); |
490 if (instance_ == NULL) { | 490 if (instance_ == NULL) { |
491 // Start a thread that will send SIGPROF signal to VM threads, | 491 // Start a thread that will send SIGPROF signal to VM threads, |
492 // when CPU profiling will be enabled. | 492 // when CPU profiling will be enabled. |
493 instance_ = new SamplerThread(sampler->interval()); | 493 instance_ = new SamplerThread(sampler->interval()); |
494 need_to_start = true; | 494 need_to_start = true; |
495 } | 495 } |
496 | 496 |
497 ASSERT(sampler->IsActive()); | 497 ASSERT(sampler->IsActive()); |
498 ASSERT(!instance_->active_samplers_.Contains(sampler)); | 498 ASSERT(!instance_->active_samplers_.Contains(sampler)); |
499 ASSERT(instance_->interval_ == sampler->interval()); | 499 ASSERT(instance_->interval_ == sampler->interval()); |
500 instance_->active_samplers_.Add(sampler); | 500 instance_->active_samplers_.Add(sampler); |
501 | 501 |
502 if (need_to_start) instance_->StartSynchronously(); | 502 if (need_to_start) instance_->StartSynchronously(); |
503 } | 503 } |
504 | 504 |
505 static void RemoveActiveSampler(Sampler* sampler) { | 505 static void RemoveActiveSampler(Sampler* sampler) { |
506 SamplerThread* instance_to_remove = NULL; | 506 SamplerThread* instance_to_remove = NULL; |
507 { | 507 { |
508 LockGuard<Mutex> lock_guard(mutex_); | 508 base::LockGuard<base::Mutex> lock_guard(mutex_); |
509 | 509 |
510 ASSERT(sampler->IsActive()); | 510 ASSERT(sampler->IsActive()); |
511 bool removed = instance_->active_samplers_.RemoveElement(sampler); | 511 bool removed = instance_->active_samplers_.RemoveElement(sampler); |
512 ASSERT(removed); | 512 ASSERT(removed); |
513 USE(removed); | 513 USE(removed); |
514 | 514 |
515 // We cannot delete the instance immediately as we need to Join() the | 515 // We cannot delete the instance immediately as we need to Join() the |
516 // thread but we are holding mutex_ and the thread may try to acquire it. | 516 // thread but we are holding mutex_ and the thread may try to acquire it. |
517 if (instance_->active_samplers_.is_empty()) { | 517 if (instance_->active_samplers_.is_empty()) { |
518 instance_to_remove = instance_; | 518 instance_to_remove = instance_; |
519 instance_ = NULL; | 519 instance_ = NULL; |
520 } | 520 } |
521 } | 521 } |
522 | 522 |
523 if (!instance_to_remove) return; | 523 if (!instance_to_remove) return; |
524 instance_to_remove->Join(); | 524 instance_to_remove->Join(); |
525 delete instance_to_remove; | 525 delete instance_to_remove; |
526 } | 526 } |
527 | 527 |
528 // Implement Thread::Run(). | 528 // Implement Thread::Run(). |
529 virtual void Run() { | 529 virtual void Run() { |
530 while (true) { | 530 while (true) { |
531 { | 531 { |
532 LockGuard<Mutex> lock_guard(mutex_); | 532 base::LockGuard<base::Mutex> lock_guard(mutex_); |
533 if (active_samplers_.is_empty()) break; | 533 if (active_samplers_.is_empty()) break; |
534 // When CPU profiling is enabled both JavaScript and C++ code is | 534 // When CPU profiling is enabled both JavaScript and C++ code is |
535 // profiled. We must not suspend. | 535 // profiled. We must not suspend. |
536 for (int i = 0; i < active_samplers_.length(); ++i) { | 536 for (int i = 0; i < active_samplers_.length(); ++i) { |
537 Sampler* sampler = active_samplers_.at(i); | 537 Sampler* sampler = active_samplers_.at(i); |
538 if (!sampler->isolate()->IsInitialized()) continue; | 538 if (!sampler->isolate()->IsInitialized()) continue; |
539 if (!sampler->IsProfiling()) continue; | 539 if (!sampler->IsProfiling()) continue; |
540 sampler->DoSample(); | 540 sampler->DoSample(); |
541 } | 541 } |
542 } | 542 } |
543 OS::Sleep(interval_); | 543 base::OS::Sleep(interval_); |
544 } | 544 } |
545 } | 545 } |
546 | 546 |
547 private: | 547 private: |
548 // Protects the process wide state below. | 548 // Protects the process wide state below. |
549 static Mutex* mutex_; | 549 static base::Mutex* mutex_; |
550 static SamplerThread* instance_; | 550 static SamplerThread* instance_; |
551 | 551 |
552 const int interval_; | 552 const int interval_; |
553 List<Sampler*> active_samplers_; | 553 List<Sampler*> active_samplers_; |
554 | 554 |
555 DISALLOW_COPY_AND_ASSIGN(SamplerThread); | 555 DISALLOW_COPY_AND_ASSIGN(SamplerThread); |
556 }; | 556 }; |
557 | 557 |
558 | 558 |
559 Mutex* SamplerThread::mutex_ = NULL; | 559 base::Mutex* SamplerThread::mutex_ = NULL; |
560 SamplerThread* SamplerThread::instance_ = NULL; | 560 SamplerThread* SamplerThread::instance_ = NULL; |
561 | 561 |
562 | 562 |
563 // | 563 // |
564 // StackTracer implementation | 564 // StackTracer implementation |
565 // | 565 // |
566 DISABLE_ASAN void TickSample::Init(Isolate* isolate, | 566 DISABLE_ASAN void TickSample::Init(Isolate* isolate, |
567 const RegisterState& regs) { | 567 const RegisterState& regs) { |
568 ASSERT(isolate->IsInitialized()); | 568 ASSERT(isolate->IsInitialized()); |
569 timestamp = TimeTicks::HighResolutionNow(); | 569 timestamp = base::TimeTicks::HighResolutionNow(); |
570 pc = regs.pc; | 570 pc = regs.pc; |
571 state = isolate->current_vm_state(); | 571 state = isolate->current_vm_state(); |
572 | 572 |
573 // Avoid collecting traces while doing GC. | 573 // Avoid collecting traces while doing GC. |
574 if (state == GC) return; | 574 if (state == GC) return; |
575 | 575 |
576 Address js_entry_sp = isolate->js_entry_sp(); | 576 Address js_entry_sp = isolate->js_entry_sp(); |
577 if (js_entry_sp == 0) { | 577 if (js_entry_sp == 0) { |
578 // Not executing JS now. | 578 // Not executing JS now. |
579 return; | 579 return; |
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
728 #endif // USE_SIMULATOR | 728 #endif // USE_SIMULATOR |
729 SampleStack(state); | 729 SampleStack(state); |
730 } | 730 } |
731 ResumeThread(profiled_thread); | 731 ResumeThread(profiled_thread); |
732 } | 732 } |
733 | 733 |
734 #endif // USE_SIGNALS | 734 #endif // USE_SIGNALS |
735 | 735 |
736 | 736 |
737 } } // namespace v8::internal | 737 } } // namespace v8::internal |
OLD | NEW |