| OLD | NEW |
| 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 26 matching lines...) Expand all Loading... |
| 37 #include <stdlib.h> | 37 #include <stdlib.h> |
| 38 | 38 |
| 39 // Ubuntu Dapper requires memory pages to be marked as | 39 // Ubuntu Dapper requires memory pages to be marked as |
| 40 // executable. Otherwise, OS raises an exception when executing code | 40 // executable. Otherwise, OS raises an exception when executing code |
| 41 // in that page. | 41 // in that page. |
| 42 #include <sys/types.h> // mmap & munmap | 42 #include <sys/types.h> // mmap & munmap |
| 43 #include <sys/mman.h> // mmap & munmap | 43 #include <sys/mman.h> // mmap & munmap |
| 44 #include <sys/stat.h> // open | 44 #include <sys/stat.h> // open |
| 45 #include <fcntl.h> // open | 45 #include <fcntl.h> // open |
| 46 #include <unistd.h> // sysconf | 46 #include <unistd.h> // sysconf |
| 47 #ifdef __GLIBC__ |
| 47 #include <execinfo.h> // backtrace, backtrace_symbols | 48 #include <execinfo.h> // backtrace, backtrace_symbols |
| 49 #endif // def __GLIBC__ |
| 48 #include <strings.h> // index | 50 #include <strings.h> // index |
| 49 #include <errno.h> | 51 #include <errno.h> |
| 50 #include <stdarg.h> | 52 #include <stdarg.h> |
| 51 | 53 |
| 52 #include <arpa/inet.h> | 54 #include <arpa/inet.h> |
| 53 #include <netinet/in.h> | 55 #include <netinet/in.h> |
| 54 #include <netdb.h> | 56 #include <netdb.h> |
| 55 | 57 |
| 56 #undef MAP_TYPE | 58 #undef MAP_TYPE |
| 57 | 59 |
| (...skipping 296 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 354 if (start_of_path == NULL) continue; | 356 if (start_of_path == NULL) continue; |
| 355 buffer[bytes_read] = 0; | 357 buffer[bytes_read] = 0; |
| 356 LOG(SharedLibraryEvent(start_of_path, start, end)); | 358 LOG(SharedLibraryEvent(start_of_path, start, end)); |
| 357 } | 359 } |
| 358 close(fd); | 360 close(fd); |
| 359 #endif | 361 #endif |
| 360 } | 362 } |
| 361 | 363 |
| 362 | 364 |
| 363 int OS::StackWalk(OS::StackFrame* frames, int frames_size) { | 365 int OS::StackWalk(OS::StackFrame* frames, int frames_size) { |
| 366 // backtrace is a glibc extension. |
| 367 #ifdef __GLIBC__ |
| 364 void** addresses = NewArray<void*>(frames_size); | 368 void** addresses = NewArray<void*>(frames_size); |
| 365 | 369 |
| 366 int frames_count = backtrace(addresses, frames_size); | 370 int frames_count = backtrace(addresses, frames_size); |
| 367 | 371 |
| 368 char** symbols; | 372 char** symbols; |
| 369 symbols = backtrace_symbols(addresses, frames_count); | 373 symbols = backtrace_symbols(addresses, frames_count); |
| 370 if (symbols == NULL) { | 374 if (symbols == NULL) { |
| 371 DeleteArray(addresses); | 375 DeleteArray(addresses); |
| 372 return kStackWalkError; | 376 return kStackWalkError; |
| 373 } | 377 } |
| 374 | 378 |
| 375 for (int i = 0; i < frames_count; i++) { | 379 for (int i = 0; i < frames_count; i++) { |
| 376 frames[i].address = addresses[i]; | 380 frames[i].address = addresses[i]; |
| 377 // Format a text representation of the frame based on the information | 381 // Format a text representation of the frame based on the information |
| 378 // available. | 382 // available. |
| 379 SNPrintF(MutableCStrVector(frames[i].text, kStackWalkMaxTextLen), | 383 SNPrintF(MutableCStrVector(frames[i].text, kStackWalkMaxTextLen), |
| 380 "%s", | 384 "%s", |
| 381 symbols[i]); | 385 symbols[i]); |
| 382 // Make sure line termination is in place. | 386 // Make sure line termination is in place. |
| 383 frames[i].text[kStackWalkMaxTextLen - 1] = '\0'; | 387 frames[i].text[kStackWalkMaxTextLen - 1] = '\0'; |
| 384 } | 388 } |
| 385 | 389 |
| 386 DeleteArray(addresses); | 390 DeleteArray(addresses); |
| 387 free(symbols); | 391 free(symbols); |
| 388 | 392 |
| 389 return frames_count; | 393 return frames_count; |
| 394 #else // ndef __GLIBC__ |
| 395 return 0; |
| 396 #endif // ndef __GLIBC__ |
| 390 } | 397 } |
| 391 | 398 |
| 392 | 399 |
| 393 // Constants used for mmap. | 400 // Constants used for mmap. |
| 394 static const int kMmapFd = -1; | 401 static const int kMmapFd = -1; |
| 395 static const int kMmapFdOffset = 0; | 402 static const int kMmapFdOffset = 0; |
| 396 | 403 |
| 397 | 404 |
| 398 VirtualMemory::VirtualMemory(size_t size) { | 405 VirtualMemory::VirtualMemory(size_t size) { |
| 399 address_ = mmap(NULL, size, PROT_NONE, | 406 address_ = mmap(NULL, size, PROT_NONE, |
| (...skipping 407 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 807 Socket* OS::CreateSocket() { | 814 Socket* OS::CreateSocket() { |
| 808 return new LinuxSocket(); | 815 return new LinuxSocket(); |
| 809 } | 816 } |
| 810 | 817 |
| 811 | 818 |
| 812 #ifdef ENABLE_LOGGING_AND_PROFILING | 819 #ifdef ENABLE_LOGGING_AND_PROFILING |
| 813 | 820 |
| 814 static Sampler* active_sampler_ = NULL; | 821 static Sampler* active_sampler_ = NULL; |
| 815 | 822 |
| 816 static void ProfilerSignalHandler(int signal, siginfo_t* info, void* context) { | 823 static void ProfilerSignalHandler(int signal, siginfo_t* info, void* context) { |
| 824 // Ucontext is a glibc extension - no profiling on Android at the moment. |
| 825 #ifdef __GLIBC__ |
| 817 USE(info); | 826 USE(info); |
| 818 if (signal != SIGPROF) return; | 827 if (signal != SIGPROF) return; |
| 819 if (active_sampler_ == NULL) return; | 828 if (active_sampler_ == NULL) return; |
| 820 | 829 |
| 821 TickSample sample; | 830 TickSample sample; |
| 822 | 831 |
| 823 // If profiling, we extract the current pc and sp. | 832 // If profiling, we extract the current pc and sp. |
| 824 if (active_sampler_->IsProfiling()) { | 833 if (active_sampler_->IsProfiling()) { |
| 825 // Extracting the sample from the context is extremely machine dependent. | 834 // Extracting the sample from the context is extremely machine dependent. |
| 826 ucontext_t* ucontext = reinterpret_cast<ucontext_t*>(context); | 835 ucontext_t* ucontext = reinterpret_cast<ucontext_t*>(context); |
| 827 mcontext_t& mcontext = ucontext->uc_mcontext; | 836 mcontext_t& mcontext = ucontext->uc_mcontext; |
| 828 #if defined (__arm__) || defined(__thumb__) | 837 #if defined (__arm__) || defined(__thumb__) |
| 829 sample.pc = mcontext.gregs[R15]; | 838 sample.pc = mcontext.gregs[R15]; |
| 830 sample.sp = mcontext.gregs[R13]; | 839 sample.sp = mcontext.gregs[R13]; |
| 831 sample.fp = mcontext.gregs[R11]; | 840 sample.fp = mcontext.gregs[R11]; |
| 832 #else | 841 #else |
| 833 sample.pc = mcontext.gregs[REG_EIP]; | 842 sample.pc = mcontext.gregs[REG_EIP]; |
| 834 sample.sp = mcontext.gregs[REG_ESP]; | 843 sample.sp = mcontext.gregs[REG_ESP]; |
| 835 sample.fp = mcontext.gregs[REG_EBP]; | 844 sample.fp = mcontext.gregs[REG_EBP]; |
| 836 #endif | 845 #endif |
| 837 } | 846 } |
| 838 | 847 |
| 839 // We always sample the VM state. | 848 // We always sample the VM state. |
| 840 sample.state = Logger::state(); | 849 sample.state = Logger::state(); |
| 841 | 850 |
| 842 active_sampler_->Tick(&sample); | 851 active_sampler_->Tick(&sample); |
| 852 #endif |
| 843 } | 853 } |
| 844 | 854 |
| 845 | 855 |
| 846 class Sampler::PlatformData : public Malloced { | 856 class Sampler::PlatformData : public Malloced { |
| 847 public: | 857 public: |
| 848 PlatformData() { | 858 PlatformData() { |
| 849 signal_handler_installed_ = false; | 859 signal_handler_installed_ = false; |
| 850 } | 860 } |
| 851 | 861 |
| 852 bool signal_handler_installed_; | 862 bool signal_handler_installed_; |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 902 } | 912 } |
| 903 | 913 |
| 904 // This sampler is no longer the active sampler. | 914 // This sampler is no longer the active sampler. |
| 905 active_sampler_ = NULL; | 915 active_sampler_ = NULL; |
| 906 active_ = false; | 916 active_ = false; |
| 907 } | 917 } |
| 908 | 918 |
| 909 #endif // ENABLE_LOGGING_AND_PROFILING | 919 #endif // ENABLE_LOGGING_AND_PROFILING |
| 910 | 920 |
| 911 } } // namespace v8::internal | 921 } } // namespace v8::internal |
| OLD | NEW |