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 |
11 #include <errno.h> | 11 #include <errno.h> |
12 #include <pthread.h> | 12 #include <pthread.h> |
13 #include <signal.h> | 13 #include <signal.h> |
14 #include <sys/time.h> | 14 #include <sys/time.h> |
15 | 15 |
16 #if !V8_OS_QNX | 16 #if !V8_OS_QNX && !V8_OS_NACL |
17 #include <sys/syscall.h> // NOLINT | 17 #include <sys/syscall.h> // NOLINT |
18 #endif | 18 #endif |
19 | 19 |
20 #if V8_OS_MACOSX | 20 #if V8_OS_MACOSX |
21 #include <mach/mach.h> | 21 #include <mach/mach.h> |
22 // OpenBSD doesn't have <ucontext.h>. ucontext_t lives in <signal.h> | 22 // OpenBSD doesn't have <ucontext.h>. ucontext_t lives in <signal.h> |
23 // and is a typedef for struct sigcontext. There is no uc_mcontext. | 23 // and is a typedef for struct sigcontext. There is no uc_mcontext. |
24 #elif(!V8_OS_ANDROID || defined(__BIONIC_HAVE_UCONTEXT_T)) \ | 24 #elif(!V8_OS_ANDROID || defined(__BIONIC_HAVE_UCONTEXT_T)) && \ |
25 && !V8_OS_OPENBSD | 25 !V8_OS_OPENBSD && !V8_OS_NACL |
26 #include <ucontext.h> | 26 #include <ucontext.h> |
27 #endif | 27 #endif |
28 | 28 |
29 #include <unistd.h> | 29 #include <unistd.h> |
30 | 30 |
31 // GLibc on ARM defines mcontext_t has a typedef for 'struct sigcontext'. | 31 // GLibc on ARM defines mcontext_t has a typedef for 'struct sigcontext'. |
32 // Old versions of the C library <signal.h> didn't define the type. | 32 // Old versions of the C library <signal.h> didn't define the type. |
33 #if V8_OS_ANDROID && !defined(__BIONIC_HAVE_UCONTEXT_T) && \ | 33 #if V8_OS_ANDROID && !defined(__BIONIC_HAVE_UCONTEXT_T) && \ |
34 (defined(__arm__) || defined(__aarch64__)) && \ | 34 (defined(__arm__) || defined(__aarch64__)) && \ |
35 !defined(__BIONIC_HAVE_STRUCT_SIGCONTEXT) | 35 !defined(__BIONIC_HAVE_STRUCT_SIGCONTEXT) |
(...skipping 251 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
287 base::LockGuard<base::Mutex> lock_guard(mutex_); | 287 base::LockGuard<base::Mutex> lock_guard(mutex_); |
288 if (--client_count_ == 0) Restore(); | 288 if (--client_count_ == 0) Restore(); |
289 } | 289 } |
290 | 290 |
291 static bool Installed() { | 291 static bool Installed() { |
292 return signal_handler_installed_; | 292 return signal_handler_installed_; |
293 } | 293 } |
294 | 294 |
295 private: | 295 private: |
296 static void Install() { | 296 static void Install() { |
| 297 #if !V8_OS_NACL |
297 struct sigaction sa; | 298 struct sigaction sa; |
298 sa.sa_sigaction = &HandleProfilerSignal; | 299 sa.sa_sigaction = &HandleProfilerSignal; |
299 sigemptyset(&sa.sa_mask); | 300 sigemptyset(&sa.sa_mask); |
300 #if V8_OS_QNX | 301 #if V8_OS_QNX |
301 sa.sa_flags = SA_SIGINFO; | 302 sa.sa_flags = SA_SIGINFO; |
302 #else | 303 #else |
303 sa.sa_flags = SA_RESTART | SA_SIGINFO; | 304 sa.sa_flags = SA_RESTART | SA_SIGINFO; |
304 #endif | 305 #endif |
305 signal_handler_installed_ = | 306 signal_handler_installed_ = |
306 (sigaction(SIGPROF, &sa, &old_signal_handler_) == 0); | 307 (sigaction(SIGPROF, &sa, &old_signal_handler_) == 0); |
| 308 #endif |
307 } | 309 } |
308 | 310 |
309 static void Restore() { | 311 static void Restore() { |
| 312 #if !V8_OS_NACL |
310 if (signal_handler_installed_) { | 313 if (signal_handler_installed_) { |
311 sigaction(SIGPROF, &old_signal_handler_, 0); | 314 sigaction(SIGPROF, &old_signal_handler_, 0); |
312 signal_handler_installed_ = false; | 315 signal_handler_installed_ = false; |
313 } | 316 } |
| 317 #endif |
314 } | 318 } |
315 | 319 |
| 320 #if !V8_OS_NACL |
316 static void HandleProfilerSignal(int signal, siginfo_t* info, void* context); | 321 static void HandleProfilerSignal(int signal, siginfo_t* info, void* context); |
| 322 #endif |
317 // Protects the process wide state below. | 323 // Protects the process wide state below. |
318 static base::Mutex* mutex_; | 324 static base::Mutex* mutex_; |
319 static int client_count_; | 325 static int client_count_; |
320 static bool signal_handler_installed_; | 326 static bool signal_handler_installed_; |
321 static struct sigaction old_signal_handler_; | 327 static struct sigaction old_signal_handler_; |
322 }; | 328 }; |
323 | 329 |
324 | 330 |
325 base::Mutex* SignalHandler::mutex_ = NULL; | 331 base::Mutex* SignalHandler::mutex_ = NULL; |
326 int SignalHandler::client_count_ = 0; | 332 int SignalHandler::client_count_ = 0; |
327 struct sigaction SignalHandler::old_signal_handler_; | 333 struct sigaction SignalHandler::old_signal_handler_; |
328 bool SignalHandler::signal_handler_installed_ = false; | 334 bool SignalHandler::signal_handler_installed_ = false; |
329 | 335 |
330 | 336 |
| 337 // As Native Client does not support signal handling, profiling is disabled. |
| 338 #if !V8_OS_NACL |
331 void SignalHandler::HandleProfilerSignal(int signal, siginfo_t* info, | 339 void SignalHandler::HandleProfilerSignal(int signal, siginfo_t* info, |
332 void* context) { | 340 void* context) { |
333 #if V8_OS_NACL | |
334 // As Native Client does not support signal handling, profiling | |
335 // is disabled. | |
336 return; | |
337 #else | |
338 USE(info); | 341 USE(info); |
339 if (signal != SIGPROF) return; | 342 if (signal != SIGPROF) return; |
340 Isolate* isolate = Isolate::UnsafeCurrent(); | 343 Isolate* isolate = Isolate::UnsafeCurrent(); |
341 if (isolate == NULL || !isolate->IsInitialized() || !isolate->IsInUse()) { | 344 if (isolate == NULL || !isolate->IsInitialized() || !isolate->IsInUse()) { |
342 // We require a fully initialized and entered isolate. | 345 // We require a fully initialized and entered isolate. |
343 return; | 346 return; |
344 } | 347 } |
345 if (v8::Locker::IsActive() && | 348 if (v8::Locker::IsActive() && |
346 !isolate->thread_manager()->IsLockedByCurrentThread()) { | 349 !isolate->thread_manager()->IsLockedByCurrentThread()) { |
347 return; | 350 return; |
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
470 state.sp = reinterpret_cast<Address>(mcontext.cpu.esp); | 473 state.sp = reinterpret_cast<Address>(mcontext.cpu.esp); |
471 state.fp = reinterpret_cast<Address>(mcontext.cpu.ebp); | 474 state.fp = reinterpret_cast<Address>(mcontext.cpu.ebp); |
472 #elif V8_HOST_ARCH_ARM | 475 #elif V8_HOST_ARCH_ARM |
473 state.pc = reinterpret_cast<Address>(mcontext.cpu.gpr[ARM_REG_PC]); | 476 state.pc = reinterpret_cast<Address>(mcontext.cpu.gpr[ARM_REG_PC]); |
474 state.sp = reinterpret_cast<Address>(mcontext.cpu.gpr[ARM_REG_SP]); | 477 state.sp = reinterpret_cast<Address>(mcontext.cpu.gpr[ARM_REG_SP]); |
475 state.fp = reinterpret_cast<Address>(mcontext.cpu.gpr[ARM_REG_FP]); | 478 state.fp = reinterpret_cast<Address>(mcontext.cpu.gpr[ARM_REG_FP]); |
476 #endif // V8_HOST_ARCH_* | 479 #endif // V8_HOST_ARCH_* |
477 #endif // V8_OS_QNX | 480 #endif // V8_OS_QNX |
478 #endif // USE_SIMULATOR | 481 #endif // USE_SIMULATOR |
479 sampler->SampleStack(state); | 482 sampler->SampleStack(state); |
| 483 } |
480 #endif // V8_OS_NACL | 484 #endif // V8_OS_NACL |
481 } | |
482 | 485 |
483 #endif | 486 #endif |
484 | 487 |
485 | 488 |
486 class SamplerThread : public base::Thread { | 489 class SamplerThread : public base::Thread { |
487 public: | 490 public: |
488 static const int kSamplerThreadStackSize = 64 * KB; | 491 static const int kSamplerThreadStackSize = 64 * KB; |
489 | 492 |
490 explicit SamplerThread(int interval) | 493 explicit SamplerThread(int interval) |
491 : Thread(base::Thread::Options("SamplerThread", kSamplerThreadStackSize)), | 494 : Thread(base::Thread::Options("SamplerThread", kSamplerThreadStackSize)), |
(...skipping 246 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
738 #endif // USE_SIMULATOR | 741 #endif // USE_SIMULATOR |
739 SampleStack(state); | 742 SampleStack(state); |
740 } | 743 } |
741 ResumeThread(profiled_thread); | 744 ResumeThread(profiled_thread); |
742 } | 745 } |
743 | 746 |
744 #endif // USE_SIGNALS | 747 #endif // USE_SIGNALS |
745 | 748 |
746 | 749 |
747 } } // namespace v8::internal | 750 } } // namespace v8::internal |
OLD | NEW |