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 1007 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
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) { | 1025 static void ProfilerSignalHandler(int signal, siginfo_t* info, void* context) { |
1026 USE(info); | 1026 USE(info); |
1027 if (signal != SIGPROF) return; | 1027 if (signal != SIGPROF) return; |
1028 | |
1029 Isolate* isolate = Isolate::UncheckedCurrent(); | 1028 Isolate* isolate = Isolate::UncheckedCurrent(); |
1030 if (isolate == NULL || !isolate->IsInitialized() || !isolate->IsInUse()) { | 1029 if (isolate == NULL || !isolate->IsInitialized() || !isolate->IsInUse()) { |
1031 // We require a fully initialized and entered isolate. | 1030 // We require a fully initialized and entered isolate. |
1032 return; | 1031 return; |
1033 } | 1032 } |
1034 if (v8::Locker::IsActive() && | 1033 if (v8::Locker::IsActive() && |
1035 !isolate->thread_manager()->IsLockedByCurrentThread()) { | 1034 !isolate->thread_manager()->IsLockedByCurrentThread()) { |
1036 return; | 1035 return; |
1037 } | 1036 } |
1038 | 1037 |
1039 Sampler* sampler = isolate->logger()->sampler(); | 1038 Sampler* sampler = isolate->logger()->sampler(); |
1040 if (sampler == NULL || !sampler->IsActive()) return; | 1039 if (sampler == NULL || !sampler->IsActive()) return; |
1041 | 1040 |
1042 TickSample sample_obj; | 1041 TickSample sample_obj; |
1043 TickSample* sample = CpuProfiler::StartTickSampleEvent(isolate); | 1042 TickSample* sample = CpuProfiler::TickSampleEvent(isolate); |
1044 if (sample == NULL) sample = &sample_obj; | 1043 if (sample == NULL) sample = &sample_obj; |
1045 | 1044 |
1046 // Extracting the sample from the context is extremely machine dependent. | 1045 // Extracting the sample from the context is extremely machine dependent. |
1047 ucontext_t* ucontext = reinterpret_cast<ucontext_t*>(context); | 1046 ucontext_t* ucontext = reinterpret_cast<ucontext_t*>(context); |
1048 mcontext_t& mcontext = ucontext->uc_mcontext; | 1047 mcontext_t& mcontext = ucontext->uc_mcontext; |
1049 sample->state = isolate->current_vm_state(); | 1048 sample->state = isolate->current_vm_state(); |
1050 #if V8_HOST_ARCH_IA32 | 1049 #if V8_HOST_ARCH_IA32 |
1051 sample->pc = reinterpret_cast<Address>(mcontext.gregs[REG_EIP]); | 1050 sample->pc = reinterpret_cast<Address>(mcontext.gregs[REG_EIP]); |
1052 sample->sp = reinterpret_cast<Address>(mcontext.gregs[REG_ESP]); | 1051 sample->sp = reinterpret_cast<Address>(mcontext.gregs[REG_ESP]); |
1053 sample->fp = reinterpret_cast<Address>(mcontext.gregs[REG_EBP]); | 1052 sample->fp = reinterpret_cast<Address>(mcontext.gregs[REG_EBP]); |
(...skipping 15 matching lines...) Expand all Loading... |
1069 sample->fp = reinterpret_cast<Address>(mcontext.arm_fp); | 1068 sample->fp = reinterpret_cast<Address>(mcontext.arm_fp); |
1070 #endif // defined(__GLIBC__) && !defined(__UCLIBC__) && | 1069 #endif // defined(__GLIBC__) && !defined(__UCLIBC__) && |
1071 // (__GLIBC__ < 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ <= 3)) | 1070 // (__GLIBC__ < 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ <= 3)) |
1072 #elif V8_HOST_ARCH_MIPS | 1071 #elif V8_HOST_ARCH_MIPS |
1073 sample->pc = reinterpret_cast<Address>(mcontext.pc); | 1072 sample->pc = reinterpret_cast<Address>(mcontext.pc); |
1074 sample->sp = reinterpret_cast<Address>(mcontext.gregs[29]); | 1073 sample->sp = reinterpret_cast<Address>(mcontext.gregs[29]); |
1075 sample->fp = reinterpret_cast<Address>(mcontext.gregs[30]); | 1074 sample->fp = reinterpret_cast<Address>(mcontext.gregs[30]); |
1076 #endif // V8_HOST_ARCH_* | 1075 #endif // V8_HOST_ARCH_* |
1077 sampler->SampleStack(sample); | 1076 sampler->SampleStack(sample); |
1078 sampler->Tick(sample); | 1077 sampler->Tick(sample); |
1079 CpuProfiler::FinishTickSampleEvent(isolate); | |
1080 } | 1078 } |
1081 | 1079 |
1082 | 1080 |
1083 class CpuProfilerSignalHandler { | |
1084 public: | |
1085 static void SetUp() { if (!mutex_) mutex_ = OS::CreateMutex(); } | |
1086 static void TearDown() { delete mutex_; } | |
1087 | |
1088 static void InstallSignalHandler() { | |
1089 struct sigaction sa; | |
1090 ScopedLock lock(mutex_); | |
1091 if (signal_handler_installed_counter_ > 0) { | |
1092 signal_handler_installed_counter_++; | |
1093 return; | |
1094 } | |
1095 sa.sa_sigaction = ProfilerSignalHandler; | |
1096 sigemptyset(&sa.sa_mask); | |
1097 sa.sa_flags = SA_RESTART | SA_SIGINFO; | |
1098 if (sigaction(SIGPROF, &sa, &old_signal_handler_) == 0) { | |
1099 signal_handler_installed_counter_++; | |
1100 } | |
1101 } | |
1102 | |
1103 static void RestoreSignalHandler() { | |
1104 ScopedLock lock(mutex_); | |
1105 if (signal_handler_installed_counter_ == 0) | |
1106 return; | |
1107 if (signal_handler_installed_counter_ == 1) { | |
1108 sigaction(SIGPROF, &old_signal_handler_, 0); | |
1109 } | |
1110 signal_handler_installed_counter_--; | |
1111 } | |
1112 | |
1113 static bool signal_handler_installed() { | |
1114 return signal_handler_installed_counter_ > 0; | |
1115 } | |
1116 | |
1117 private: | |
1118 static int signal_handler_installed_counter_; | |
1119 static struct sigaction old_signal_handler_; | |
1120 static Mutex* mutex_; | |
1121 }; | |
1122 | |
1123 | |
1124 int CpuProfilerSignalHandler::signal_handler_installed_counter_ = 0; | |
1125 struct sigaction CpuProfilerSignalHandler::old_signal_handler_; | |
1126 Mutex* CpuProfilerSignalHandler::mutex_ = NULL; | |
1127 | |
1128 | |
1129 class Sampler::PlatformData : public Malloced { | 1081 class Sampler::PlatformData : public Malloced { |
1130 public: | 1082 public: |
1131 PlatformData() | 1083 PlatformData() : vm_tid_(GetThreadID()) {} |
1132 : vm_tgid_(getpid()), | |
1133 vm_tid_(GetThreadID()) {} | |
1134 | 1084 |
1135 void SendProfilingSignal() { | 1085 int vm_tid() const { return vm_tid_; } |
1136 if (!CpuProfilerSignalHandler::signal_handler_installed()) return; | |
1137 // Glibc doesn't provide a wrapper for tgkill(2). | |
1138 #if defined(ANDROID) | |
1139 syscall(__NR_tgkill, vm_tgid_, vm_tid_, SIGPROF); | |
1140 #else | |
1141 syscall(SYS_tgkill, vm_tgid_, vm_tid_, SIGPROF); | |
1142 #endif | |
1143 } | |
1144 | 1086 |
1145 private: | 1087 private: |
1146 const int vm_tgid_; | |
1147 const int vm_tid_; | 1088 const int vm_tid_; |
1148 }; | 1089 }; |
1149 | 1090 |
1150 | 1091 |
1151 class SignalSender : public Thread { | 1092 class SignalSender : public Thread { |
1152 public: | 1093 public: |
1153 enum SleepInterval { | 1094 enum SleepInterval { |
1154 HALF_INTERVAL, | 1095 HALF_INTERVAL, |
1155 FULL_INTERVAL | 1096 FULL_INTERVAL |
1156 }; | 1097 }; |
1157 | 1098 |
1158 static const int kSignalSenderStackSize = 64 * KB; | 1099 static const int kSignalSenderStackSize = 64 * KB; |
1159 | 1100 |
1160 explicit SignalSender(int interval) | 1101 explicit SignalSender(int interval) |
1161 : Thread(Thread::Options("SignalSender", kSignalSenderStackSize)), | 1102 : Thread(Thread::Options("SignalSender", kSignalSenderStackSize)), |
| 1103 vm_tgid_(getpid()), |
1162 interval_(interval) {} | 1104 interval_(interval) {} |
1163 | 1105 |
1164 static void SetUp() { if (!mutex_) mutex_ = OS::CreateMutex(); } | 1106 static void SetUp() { if (!mutex_) mutex_ = OS::CreateMutex(); } |
1165 static void TearDown() { delete mutex_; } | 1107 static void TearDown() { delete mutex_; } |
1166 | 1108 |
| 1109 static void InstallSignalHandler() { |
| 1110 struct sigaction sa; |
| 1111 sa.sa_sigaction = ProfilerSignalHandler; |
| 1112 sigemptyset(&sa.sa_mask); |
| 1113 sa.sa_flags = SA_RESTART | SA_SIGINFO; |
| 1114 signal_handler_installed_ = |
| 1115 (sigaction(SIGPROF, &sa, &old_signal_handler_) == 0); |
| 1116 } |
| 1117 |
| 1118 static void RestoreSignalHandler() { |
| 1119 if (signal_handler_installed_) { |
| 1120 sigaction(SIGPROF, &old_signal_handler_, 0); |
| 1121 signal_handler_installed_ = false; |
| 1122 } |
| 1123 } |
| 1124 |
1167 static void AddActiveSampler(Sampler* sampler) { | 1125 static void AddActiveSampler(Sampler* sampler) { |
1168 ScopedLock lock(mutex_); | 1126 ScopedLock lock(mutex_); |
1169 SamplerRegistry::AddActiveSampler(sampler); | 1127 SamplerRegistry::AddActiveSampler(sampler); |
1170 if (instance_ == NULL) { | 1128 if (instance_ == NULL) { |
1171 // Start a thread that will send SIGPROF signal to VM threads, | 1129 // Start a thread that will send SIGPROF signal to VM threads, |
1172 // when CPU profiling will be enabled. | 1130 // when CPU profiling will be enabled. |
1173 instance_ = new SignalSender(sampler->interval()); | 1131 instance_ = new SignalSender(sampler->interval()); |
1174 instance_->Start(); | 1132 instance_->Start(); |
1175 } else { | 1133 } else { |
1176 ASSERT(instance_->interval_ == sampler->interval()); | 1134 ASSERT(instance_->interval_ == sampler->interval()); |
1177 } | 1135 } |
1178 } | 1136 } |
1179 | 1137 |
1180 static void RemoveActiveSampler(Sampler* sampler) { | 1138 static void RemoveActiveSampler(Sampler* sampler) { |
1181 ScopedLock lock(mutex_); | 1139 ScopedLock lock(mutex_); |
1182 SamplerRegistry::RemoveActiveSampler(sampler); | 1140 SamplerRegistry::RemoveActiveSampler(sampler); |
1183 if (SamplerRegistry::GetState() == SamplerRegistry::HAS_NO_SAMPLERS) { | 1141 if (SamplerRegistry::GetState() == SamplerRegistry::HAS_NO_SAMPLERS) { |
1184 RuntimeProfiler::StopRuntimeProfilerThreadBeforeShutdown(instance_); | 1142 RuntimeProfiler::StopRuntimeProfilerThreadBeforeShutdown(instance_); |
1185 delete instance_; | 1143 delete instance_; |
1186 instance_ = NULL; | 1144 instance_ = NULL; |
| 1145 RestoreSignalHandler(); |
1187 } | 1146 } |
1188 } | 1147 } |
1189 | 1148 |
1190 // Implement Thread::Run(). | 1149 // Implement Thread::Run(). |
1191 virtual void Run() { | 1150 virtual void Run() { |
1192 SamplerRegistry::State state; | 1151 SamplerRegistry::State state; |
1193 while ((state = SamplerRegistry::GetState()) != | 1152 while ((state = SamplerRegistry::GetState()) != |
1194 SamplerRegistry::HAS_NO_SAMPLERS) { | 1153 SamplerRegistry::HAS_NO_SAMPLERS) { |
1195 bool cpu_profiling_enabled = | 1154 bool cpu_profiling_enabled = |
1196 (state == SamplerRegistry::HAS_CPU_PROFILING_SAMPLERS); | 1155 (state == SamplerRegistry::HAS_CPU_PROFILING_SAMPLERS); |
1197 bool runtime_profiler_enabled = RuntimeProfiler::IsEnabled(); | 1156 bool runtime_profiler_enabled = RuntimeProfiler::IsEnabled(); |
| 1157 if (cpu_profiling_enabled && !signal_handler_installed_) { |
| 1158 InstallSignalHandler(); |
| 1159 } else if (!cpu_profiling_enabled && signal_handler_installed_) { |
| 1160 RestoreSignalHandler(); |
| 1161 } |
1198 // When CPU profiling is enabled both JavaScript and C++ code is | 1162 // When CPU profiling is enabled both JavaScript and C++ code is |
1199 // profiled. We must not suspend. | 1163 // profiled. We must not suspend. |
1200 if (!cpu_profiling_enabled) { | 1164 if (!cpu_profiling_enabled) { |
1201 if (rate_limiter_.SuspendIfNecessary()) continue; | 1165 if (rate_limiter_.SuspendIfNecessary()) continue; |
1202 } | 1166 } |
1203 if (cpu_profiling_enabled && runtime_profiler_enabled) { | 1167 if (cpu_profiling_enabled && runtime_profiler_enabled) { |
1204 if (!SamplerRegistry::IterateActiveSamplers(&DoCpuProfile, NULL)) { | 1168 if (!SamplerRegistry::IterateActiveSamplers(&DoCpuProfile, this)) { |
1205 return; | 1169 return; |
1206 } | 1170 } |
1207 Sleep(HALF_INTERVAL); | 1171 Sleep(HALF_INTERVAL); |
1208 if (!SamplerRegistry::IterateActiveSamplers(&DoRuntimeProfile, NULL)) { | 1172 if (!SamplerRegistry::IterateActiveSamplers(&DoRuntimeProfile, NULL)) { |
1209 return; | 1173 return; |
1210 } | 1174 } |
1211 Sleep(HALF_INTERVAL); | 1175 Sleep(HALF_INTERVAL); |
1212 } else { | 1176 } else { |
1213 if (cpu_profiling_enabled) { | 1177 if (cpu_profiling_enabled) { |
1214 if (!SamplerRegistry::IterateActiveSamplers(&DoCpuProfile, NULL)) { | 1178 if (!SamplerRegistry::IterateActiveSamplers(&DoCpuProfile, |
| 1179 this)) { |
1215 return; | 1180 return; |
1216 } | 1181 } |
1217 } | 1182 } |
1218 if (runtime_profiler_enabled) { | 1183 if (runtime_profiler_enabled) { |
1219 if (!SamplerRegistry::IterateActiveSamplers(&DoRuntimeProfile, | 1184 if (!SamplerRegistry::IterateActiveSamplers(&DoRuntimeProfile, |
1220 NULL)) { | 1185 NULL)) { |
1221 return; | 1186 return; |
1222 } | 1187 } |
1223 } | 1188 } |
1224 Sleep(FULL_INTERVAL); | 1189 Sleep(FULL_INTERVAL); |
1225 } | 1190 } |
1226 } | 1191 } |
1227 } | 1192 } |
1228 | 1193 |
1229 static void DoCpuProfile(Sampler* sampler, void*) { | 1194 static void DoCpuProfile(Sampler* sampler, void* raw_sender) { |
1230 if (!sampler->IsProfiling()) return; | 1195 if (!sampler->IsProfiling()) return; |
1231 sampler->platform_data()->SendProfilingSignal(); | 1196 SignalSender* sender = reinterpret_cast<SignalSender*>(raw_sender); |
| 1197 sender->SendProfilingSignal(sampler->platform_data()->vm_tid()); |
1232 } | 1198 } |
1233 | 1199 |
1234 static void DoRuntimeProfile(Sampler* sampler, void* ignored) { | 1200 static void DoRuntimeProfile(Sampler* sampler, void* ignored) { |
1235 if (!sampler->isolate()->IsInitialized()) return; | 1201 if (!sampler->isolate()->IsInitialized()) return; |
1236 sampler->isolate()->runtime_profiler()->NotifyTick(); | 1202 sampler->isolate()->runtime_profiler()->NotifyTick(); |
1237 } | 1203 } |
1238 | 1204 |
| 1205 void SendProfilingSignal(int tid) { |
| 1206 if (!signal_handler_installed_) return; |
| 1207 // Glibc doesn't provide a wrapper for tgkill(2). |
| 1208 #if defined(ANDROID) |
| 1209 syscall(__NR_tgkill, vm_tgid_, tid, SIGPROF); |
| 1210 #else |
| 1211 syscall(SYS_tgkill, vm_tgid_, tid, SIGPROF); |
| 1212 #endif |
| 1213 } |
| 1214 |
1239 void Sleep(SleepInterval full_or_half) { | 1215 void Sleep(SleepInterval full_or_half) { |
1240 // Convert ms to us and subtract 100 us to compensate delays | 1216 // Convert ms to us and subtract 100 us to compensate delays |
1241 // occuring during signal delivery. | 1217 // occuring during signal delivery. |
1242 useconds_t interval = interval_ * 1000 - 100; | 1218 useconds_t interval = interval_ * 1000 - 100; |
1243 if (full_or_half == HALF_INTERVAL) interval /= 2; | 1219 if (full_or_half == HALF_INTERVAL) interval /= 2; |
1244 #if defined(ANDROID) | 1220 #if defined(ANDROID) |
1245 usleep(interval); | 1221 usleep(interval); |
1246 #else | 1222 #else |
1247 int result = usleep(interval); | 1223 int result = usleep(interval); |
1248 #ifdef DEBUG | 1224 #ifdef DEBUG |
1249 if (result != 0 && errno != EINTR) { | 1225 if (result != 0 && errno != EINTR) { |
1250 fprintf(stderr, | 1226 fprintf(stderr, |
1251 "SignalSender usleep error; interval = %u, errno = %d\n", | 1227 "SignalSender usleep error; interval = %u, errno = %d\n", |
1252 interval, | 1228 interval, |
1253 errno); | 1229 errno); |
1254 ASSERT(result == 0 || errno == EINTR); | 1230 ASSERT(result == 0 || errno == EINTR); |
1255 } | 1231 } |
1256 #endif // DEBUG | 1232 #endif // DEBUG |
1257 USE(result); | 1233 USE(result); |
1258 #endif // ANDROID | 1234 #endif // ANDROID |
1259 } | 1235 } |
1260 | 1236 |
| 1237 const int vm_tgid_; |
1261 const int interval_; | 1238 const int interval_; |
1262 RuntimeProfilerRateLimiter rate_limiter_; | 1239 RuntimeProfilerRateLimiter rate_limiter_; |
1263 | 1240 |
1264 // Protects the process wide state below. | 1241 // Protects the process wide state below. |
1265 static Mutex* mutex_; | 1242 static Mutex* mutex_; |
1266 static SignalSender* instance_; | 1243 static SignalSender* instance_; |
| 1244 static bool signal_handler_installed_; |
| 1245 static struct sigaction old_signal_handler_; |
1267 | 1246 |
1268 private: | 1247 private: |
1269 DISALLOW_COPY_AND_ASSIGN(SignalSender); | 1248 DISALLOW_COPY_AND_ASSIGN(SignalSender); |
1270 }; | 1249 }; |
1271 | 1250 |
1272 | 1251 |
1273 Mutex* SignalSender::mutex_ = NULL; | 1252 Mutex* SignalSender::mutex_ = NULL; |
1274 SignalSender* SignalSender::instance_ = NULL; | 1253 SignalSender* SignalSender::instance_ = NULL; |
| 1254 struct sigaction SignalSender::old_signal_handler_; |
| 1255 bool SignalSender::signal_handler_installed_ = false; |
1275 | 1256 |
1276 | 1257 |
1277 void OS::SetUp() { | 1258 void OS::SetUp() { |
1278 // Seed the random number generator. We preserve microsecond resolution. | 1259 // Seed the random number generator. We preserve microsecond resolution. |
1279 uint64_t seed = Ticks() ^ (getpid() << 16); | 1260 uint64_t seed = Ticks() ^ (getpid() << 16); |
1280 srandom(static_cast<unsigned int>(seed)); | 1261 srandom(static_cast<unsigned int>(seed)); |
1281 limit_mutex = CreateMutex(); | 1262 limit_mutex = CreateMutex(); |
1282 | 1263 |
1283 #ifdef __arm__ | 1264 #ifdef __arm__ |
1284 // 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 |
1285 // by the C code is the same. | 1266 // by the C code is the same. |
1286 bool hard_float = OS::ArmUsingHardFloat(); | 1267 bool hard_float = OS::ArmUsingHardFloat(); |
1287 if (hard_float) { | 1268 if (hard_float) { |
1288 #if !USE_EABI_HARDFLOAT | 1269 #if !USE_EABI_HARDFLOAT |
1289 PrintF("ERROR: Binary compiled with -mfloat-abi=hard but without " | 1270 PrintF("ERROR: Binary compiled with -mfloat-abi=hard but without " |
1290 "-DUSE_EABI_HARDFLOAT\n"); | 1271 "-DUSE_EABI_HARDFLOAT\n"); |
1291 exit(1); | 1272 exit(1); |
1292 #endif | 1273 #endif |
1293 } else { | 1274 } else { |
1294 #if USE_EABI_HARDFLOAT | 1275 #if USE_EABI_HARDFLOAT |
1295 PrintF("ERROR: Binary not compiled with -mfloat-abi=hard but with " | 1276 PrintF("ERROR: Binary not compiled with -mfloat-abi=hard but with " |
1296 "-DUSE_EABI_HARDFLOAT\n"); | 1277 "-DUSE_EABI_HARDFLOAT\n"); |
1297 exit(1); | 1278 exit(1); |
1298 #endif | 1279 #endif |
1299 } | 1280 } |
1300 #endif | 1281 #endif |
1301 SignalSender::SetUp(); | 1282 SignalSender::SetUp(); |
1302 CpuProfilerSignalHandler::SetUp(); | |
1303 } | 1283 } |
1304 | 1284 |
1305 | 1285 |
1306 void OS::TearDown() { | 1286 void OS::TearDown() { |
1307 SignalSender::TearDown(); | 1287 SignalSender::TearDown(); |
1308 CpuProfilerSignalHandler::TearDown(); | |
1309 delete limit_mutex; | 1288 delete limit_mutex; |
1310 } | 1289 } |
1311 | 1290 |
1312 | 1291 |
1313 Sampler::Sampler(Isolate* isolate, int interval) | 1292 Sampler::Sampler(Isolate* isolate, int interval) |
1314 : isolate_(isolate), | 1293 : isolate_(isolate), |
1315 interval_(interval), | 1294 interval_(interval), |
1316 profiling_(false), | 1295 profiling_(false), |
1317 active_(false), | 1296 active_(false), |
1318 has_processing_thread_(false), | |
1319 samples_taken_(0) { | 1297 samples_taken_(0) { |
1320 data_ = new PlatformData; | 1298 data_ = new PlatformData; |
1321 } | 1299 } |
1322 | 1300 |
1323 | 1301 |
1324 Sampler::~Sampler() { | 1302 Sampler::~Sampler() { |
1325 ASSERT(!IsActive()); | 1303 ASSERT(!IsActive()); |
1326 delete data_; | 1304 delete data_; |
1327 } | 1305 } |
1328 | 1306 |
1329 | 1307 |
1330 void Sampler::DoSample() { | |
1331 platform_data()->SendProfilingSignal(); | |
1332 } | |
1333 | |
1334 | |
1335 void Sampler::Start() { | 1308 void Sampler::Start() { |
1336 ASSERT(!IsActive()); | 1309 ASSERT(!IsActive()); |
1337 SetActive(true); | 1310 SetActive(true); |
1338 SignalSender::AddActiveSampler(this); | 1311 SignalSender::AddActiveSampler(this); |
1339 } | 1312 } |
1340 | 1313 |
1341 | 1314 |
1342 void Sampler::Stop() { | 1315 void Sampler::Stop() { |
1343 ASSERT(IsActive()); | 1316 ASSERT(IsActive()); |
1344 SignalSender::RemoveActiveSampler(this); | 1317 SignalSender::RemoveActiveSampler(this); |
1345 SetActive(false); | 1318 SetActive(false); |
1346 } | 1319 } |
1347 | 1320 |
1348 | 1321 |
1349 void Sampler::StartSampling() { | |
1350 CpuProfilerSignalHandler::InstallSignalHandler(); | |
1351 } | |
1352 | |
1353 | |
1354 void Sampler::StopSampling() { | |
1355 CpuProfilerSignalHandler::RestoreSignalHandler(); | |
1356 } | |
1357 | |
1358 | |
1359 } } // namespace v8::internal | 1322 } } // namespace v8::internal |
OLD | NEW |