| OLD | NEW | 
|     1 // Copyright 2012 the V8 project authors. All rights reserved. |     1 // Copyright 2012 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 1004 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  1015 #if defined(__ANDROID__) |  1015 #if defined(__ANDROID__) | 
|  1016   // Android's C library provides gettid(2). |  1016   // Android's C library provides gettid(2). | 
|  1017   return gettid(); |  1017   return gettid(); | 
|  1018 #else |  1018 #else | 
|  1019   // Glibc doesn't provide a wrapper for gettid(2). |  1019   // Glibc doesn't provide a wrapper for gettid(2). | 
|  1020   return syscall(SYS_gettid); |  1020   return syscall(SYS_gettid); | 
|  1021 #endif |  1021 #endif | 
|  1022 } |  1022 } | 
|  1023  |  1023  | 
|  1024  |  1024  | 
 |  1025 static void ProfilerSignalHandler(int signal, siginfo_t* info, void* context) { | 
 |  1026   USE(info); | 
 |  1027   if (signal != SIGPROF) return; | 
 |  1028   Isolate* isolate = Isolate::UncheckedCurrent(); | 
 |  1029   if (isolate == NULL || !isolate->IsInitialized() || !isolate->IsInUse()) { | 
 |  1030     // We require a fully initialized and entered isolate. | 
 |  1031     return; | 
 |  1032   } | 
 |  1033   if (v8::Locker::IsActive() && | 
 |  1034       !isolate->thread_manager()->IsLockedByCurrentThread()) { | 
 |  1035     return; | 
 |  1036   } | 
 |  1037  | 
 |  1038   Sampler* sampler = isolate->logger()->sampler(); | 
 |  1039   if (sampler == NULL || !sampler->IsActive()) return; | 
 |  1040  | 
 |  1041   TickSample sample_obj; | 
 |  1042   TickSample* sample = CpuProfiler::TickSampleEvent(isolate); | 
 |  1043   if (sample == NULL) sample = &sample_obj; | 
 |  1044  | 
 |  1045   // Extracting the sample from the context is extremely machine dependent. | 
 |  1046   ucontext_t* ucontext = reinterpret_cast<ucontext_t*>(context); | 
 |  1047   mcontext_t& mcontext = ucontext->uc_mcontext; | 
 |  1048   sample->state = isolate->current_vm_state(); | 
 |  1049 #if V8_HOST_ARCH_IA32 | 
 |  1050   sample->pc = reinterpret_cast<Address>(mcontext.gregs[REG_EIP]); | 
 |  1051   sample->sp = reinterpret_cast<Address>(mcontext.gregs[REG_ESP]); | 
 |  1052   sample->fp = reinterpret_cast<Address>(mcontext.gregs[REG_EBP]); | 
 |  1053 #elif V8_HOST_ARCH_X64 | 
 |  1054   sample->pc = reinterpret_cast<Address>(mcontext.gregs[REG_RIP]); | 
 |  1055   sample->sp = reinterpret_cast<Address>(mcontext.gregs[REG_RSP]); | 
 |  1056   sample->fp = reinterpret_cast<Address>(mcontext.gregs[REG_RBP]); | 
 |  1057 #elif V8_HOST_ARCH_ARM | 
 |  1058 #if defined(__GLIBC__) && !defined(__UCLIBC__) && \ | 
 |  1059     (__GLIBC__ < 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ <= 3)) | 
 |  1060   // Old GLibc ARM versions used a gregs[] array to access the register | 
 |  1061   // values from mcontext_t. | 
 |  1062   sample->pc = reinterpret_cast<Address>(mcontext.gregs[R15]); | 
 |  1063   sample->sp = reinterpret_cast<Address>(mcontext.gregs[R13]); | 
 |  1064   sample->fp = reinterpret_cast<Address>(mcontext.gregs[R11]); | 
 |  1065 #else | 
 |  1066   sample->pc = reinterpret_cast<Address>(mcontext.arm_pc); | 
 |  1067   sample->sp = reinterpret_cast<Address>(mcontext.arm_sp); | 
 |  1068   sample->fp = reinterpret_cast<Address>(mcontext.arm_fp); | 
 |  1069 #endif  // defined(__GLIBC__) && !defined(__UCLIBC__) && | 
 |  1070         // (__GLIBC__ < 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ <= 3)) | 
 |  1071 #elif V8_HOST_ARCH_MIPS | 
 |  1072   sample->pc = reinterpret_cast<Address>(mcontext.pc); | 
 |  1073   sample->sp = reinterpret_cast<Address>(mcontext.gregs[29]); | 
 |  1074   sample->fp = reinterpret_cast<Address>(mcontext.gregs[30]); | 
 |  1075 #endif  // V8_HOST_ARCH_* | 
 |  1076   sampler->SampleStack(sample); | 
 |  1077   sampler->Tick(sample); | 
 |  1078 } | 
 |  1079  | 
 |  1080  | 
|  1025 class Sampler::PlatformData : public Malloced { |  1081 class Sampler::PlatformData : public Malloced { | 
|  1026  public: |  1082  public: | 
|  1027   PlatformData() : vm_tid_(GetThreadID()) {} |  1083   PlatformData() : vm_tid_(GetThreadID()) {} | 
|  1028  |  1084  | 
|  1029   int vm_tid() const { return vm_tid_; } |  1085   int vm_tid() const { return vm_tid_; } | 
|  1030  |  1086  | 
|  1031  private: |  1087  private: | 
|  1032   const int vm_tid_; |  1088   const int vm_tid_; | 
|  1033 }; |  1089 }; | 
|  1034  |  1090  | 
|  1035  |  1091  | 
|  1036 static void ProfilerSignalHandler(int signal, siginfo_t* info, void* context); |  | 
|  1037  |  | 
|  1038  |  | 
|  1039 class SignalSender : public Thread { |  1092 class SignalSender : public Thread { | 
|  1040  public: |  1093  public: | 
|  1041   enum SleepInterval { |  1094   enum SleepInterval { | 
|  1042     HALF_INTERVAL, |  1095     HALF_INTERVAL, | 
|  1043     FULL_INTERVAL |  1096     FULL_INTERVAL | 
|  1044   }; |  1097   }; | 
|  1045  |  1098  | 
|  1046   static const int kSignalSenderStackSize = 64 * KB; |  1099   static const int kSignalSenderStackSize = 64 * KB; | 
|  1047  |  1100  | 
|  1048   explicit SignalSender(int interval) |  1101   explicit SignalSender(int interval) | 
| (...skipping 13 matching lines...) Expand all  Loading... | 
|  1062         (sigaction(SIGPROF, &sa, &old_signal_handler_) == 0); |  1115         (sigaction(SIGPROF, &sa, &old_signal_handler_) == 0); | 
|  1063   } |  1116   } | 
|  1064  |  1117  | 
|  1065   static void RestoreSignalHandler() { |  1118   static void RestoreSignalHandler() { | 
|  1066     if (signal_handler_installed_) { |  1119     if (signal_handler_installed_) { | 
|  1067       sigaction(SIGPROF, &old_signal_handler_, 0); |  1120       sigaction(SIGPROF, &old_signal_handler_, 0); | 
|  1068       signal_handler_installed_ = false; |  1121       signal_handler_installed_ = false; | 
|  1069     } |  1122     } | 
|  1070   } |  1123   } | 
|  1071  |  1124  | 
|  1072   static void CallOldSignalHandler(int signal, siginfo_t* info, void* context) { |  | 
|  1073     if (signal_handler_installed_ && old_signal_handler_.sa_sigaction) |  | 
|  1074       old_signal_handler_.sa_sigaction(signal, info, context); |  | 
|  1075   } |  | 
|  1076  |  | 
|  1077   static void AddActiveSampler(Sampler* sampler) { |  1125   static void AddActiveSampler(Sampler* sampler) { | 
|  1078     ScopedLock lock(mutex_); |  1126     ScopedLock lock(mutex_); | 
|  1079     SamplerRegistry::AddActiveSampler(sampler); |  1127     SamplerRegistry::AddActiveSampler(sampler); | 
|  1080     if (instance_ == NULL) { |  1128     if (instance_ == NULL) { | 
|  1081       // Start a thread that will send SIGPROF signal to VM threads, |  1129       // Start a thread that will send SIGPROF signal to VM threads, | 
|  1082       // when CPU profiling will be enabled. |  1130       // when CPU profiling will be enabled. | 
|  1083       instance_ = new SignalSender(sampler->interval()); |  1131       instance_ = new SignalSender(sampler->interval()); | 
|  1084       instance_->Start(); |  1132       instance_->Start(); | 
|  1085     } else { |  1133     } else { | 
|  1086       ASSERT(instance_->interval_ == sampler->interval()); |  1134       ASSERT(instance_->interval_ == sampler->interval()); | 
| (...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  1200   DISALLOW_COPY_AND_ASSIGN(SignalSender); |  1248   DISALLOW_COPY_AND_ASSIGN(SignalSender); | 
|  1201 }; |  1249 }; | 
|  1202  |  1250  | 
|  1203  |  1251  | 
|  1204 Mutex* SignalSender::mutex_ = NULL; |  1252 Mutex* SignalSender::mutex_ = NULL; | 
|  1205 SignalSender* SignalSender::instance_ = NULL; |  1253 SignalSender* SignalSender::instance_ = NULL; | 
|  1206 struct sigaction SignalSender::old_signal_handler_; |  1254 struct sigaction SignalSender::old_signal_handler_; | 
|  1207 bool SignalSender::signal_handler_installed_ = false; |  1255 bool SignalSender::signal_handler_installed_ = false; | 
|  1208  |  1256  | 
|  1209  |  1257  | 
|  1210 static void ProfilerSignalHandler(int signal, siginfo_t* info, void* context) { |  | 
|  1211   USE(info); |  | 
|  1212   if (signal != SIGPROF) return; |  | 
|  1213   SignalSender::CallOldSignalHandler(signal, info, context); |  | 
|  1214   Isolate* isolate = Isolate::UncheckedCurrent(); |  | 
|  1215   if (isolate == NULL || !isolate->IsInitialized() || !isolate->IsInUse()) { |  | 
|  1216     // We require a fully initialized and entered isolate. |  | 
|  1217     return; |  | 
|  1218   } |  | 
|  1219   if (v8::Locker::IsActive() && |  | 
|  1220       !isolate->thread_manager()->IsLockedByCurrentThread()) { |  | 
|  1221     return; |  | 
|  1222   } |  | 
|  1223  |  | 
|  1224   Sampler* sampler = isolate->logger()->sampler(); |  | 
|  1225   if (sampler == NULL || !sampler->IsActive()) return; |  | 
|  1226  |  | 
|  1227   TickSample sample_obj; |  | 
|  1228   TickSample* sample = CpuProfiler::TickSampleEvent(isolate); |  | 
|  1229   if (sample == NULL) sample = &sample_obj; |  | 
|  1230  |  | 
|  1231   // Extracting the sample from the context is extremely machine dependent. |  | 
|  1232   ucontext_t* ucontext = reinterpret_cast<ucontext_t*>(context); |  | 
|  1233   mcontext_t& mcontext = ucontext->uc_mcontext; |  | 
|  1234   sample->state = isolate->current_vm_state(); |  | 
|  1235 #if V8_HOST_ARCH_IA32 |  | 
|  1236   sample->pc = reinterpret_cast<Address>(mcontext.gregs[REG_EIP]); |  | 
|  1237   sample->sp = reinterpret_cast<Address>(mcontext.gregs[REG_ESP]); |  | 
|  1238   sample->fp = reinterpret_cast<Address>(mcontext.gregs[REG_EBP]); |  | 
|  1239 #elif V8_HOST_ARCH_X64 |  | 
|  1240   sample->pc = reinterpret_cast<Address>(mcontext.gregs[REG_RIP]); |  | 
|  1241   sample->sp = reinterpret_cast<Address>(mcontext.gregs[REG_RSP]); |  | 
|  1242   sample->fp = reinterpret_cast<Address>(mcontext.gregs[REG_RBP]); |  | 
|  1243 #elif V8_HOST_ARCH_ARM |  | 
|  1244 #if defined(__GLIBC__) && !defined(__UCLIBC__) && \ |  | 
|  1245     (__GLIBC__ < 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ <= 3)) |  | 
|  1246   // Old GLibc ARM versions used a gregs[] array to access the register |  | 
|  1247   // values from mcontext_t. |  | 
|  1248   sample->pc = reinterpret_cast<Address>(mcontext.gregs[R15]); |  | 
|  1249   sample->sp = reinterpret_cast<Address>(mcontext.gregs[R13]); |  | 
|  1250   sample->fp = reinterpret_cast<Address>(mcontext.gregs[R11]); |  | 
|  1251 #else |  | 
|  1252   sample->pc = reinterpret_cast<Address>(mcontext.arm_pc); |  | 
|  1253   sample->sp = reinterpret_cast<Address>(mcontext.arm_sp); |  | 
|  1254   sample->fp = reinterpret_cast<Address>(mcontext.arm_fp); |  | 
|  1255 #endif  // defined(__GLIBC__) && !defined(__UCLIBC__) && |  | 
|  1256         // (__GLIBC__ < 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ <= 3)) |  | 
|  1257 #elif V8_HOST_ARCH_MIPS |  | 
|  1258   sample->pc = reinterpret_cast<Address>(mcontext.pc); |  | 
|  1259   sample->sp = reinterpret_cast<Address>(mcontext.gregs[29]); |  | 
|  1260   sample->fp = reinterpret_cast<Address>(mcontext.gregs[30]); |  | 
|  1261 #endif  // V8_HOST_ARCH_* |  | 
|  1262   sampler->SampleStack(sample); |  | 
|  1263   sampler->Tick(sample); |  | 
|  1264 } |  | 
|  1265  |  | 
|  1266  |  | 
|  1267 void OS::SetUp() { |  1258 void OS::SetUp() { | 
|  1268   // Seed the random number generator. We preserve microsecond resolution. |  1259   // Seed the random number generator. We preserve microsecond resolution. | 
|  1269   uint64_t seed = Ticks() ^ (getpid() << 16); |  1260   uint64_t seed = Ticks() ^ (getpid() << 16); | 
|  1270   srandom(static_cast<unsigned int>(seed)); |  1261   srandom(static_cast<unsigned int>(seed)); | 
|  1271   limit_mutex = CreateMutex(); |  1262   limit_mutex = CreateMutex(); | 
|  1272  |  1263  | 
|  1273 #ifdef __arm__ |  1264 #ifdef __arm__ | 
|  1274   // When running on ARM hardware check that the EABI used by V8 and |  1265   // When running on ARM hardware check that the EABI used by V8 and | 
|  1275   // by the C code is the same. |  1266   // by the C code is the same. | 
|  1276   bool hard_float = OS::ArmUsingHardFloat(); |  1267   bool hard_float = OS::ArmUsingHardFloat(); | 
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  1322  |  1313  | 
|  1323  |  1314  | 
|  1324 void Sampler::Stop() { |  1315 void Sampler::Stop() { | 
|  1325   ASSERT(IsActive()); |  1316   ASSERT(IsActive()); | 
|  1326   SignalSender::RemoveActiveSampler(this); |  1317   SignalSender::RemoveActiveSampler(this); | 
|  1327   SetActive(false); |  1318   SetActive(false); | 
|  1328 } |  1319 } | 
|  1329  |  1320  | 
|  1330  |  1321  | 
|  1331 } }  // namespace v8::internal |  1322 } }  // namespace v8::internal | 
| OLD | NEW |