| 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 |