| OLD | NEW |
| 1 // Copyright 2016 the V8 project authors. All rights reserved. | 1 // Copyright 2016 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/libsampler/v8-sampler.h" | 5 #include "src/libsampler/v8-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 |
| (...skipping 29 matching lines...) Expand all Loading... |
| 40 | 40 |
| 41 #include "src/base/win32-headers.h" | 41 #include "src/base/win32-headers.h" |
| 42 | 42 |
| 43 #endif | 43 #endif |
| 44 | 44 |
| 45 #include <algorithm> | 45 #include <algorithm> |
| 46 #include <vector> | 46 #include <vector> |
| 47 #include <map> | 47 #include <map> |
| 48 | 48 |
| 49 #include "src/base/atomic-utils.h" | 49 #include "src/base/atomic-utils.h" |
| 50 #include "src/base/hashmap.h" |
| 50 #include "src/base/platform/platform.h" | 51 #include "src/base/platform/platform.h" |
| 51 #include "src/libsampler/hashmap.h" | |
| 52 | |
| 53 | 52 |
| 54 #if V8_OS_ANDROID && !defined(__BIONIC_HAVE_UCONTEXT_T) | 53 #if V8_OS_ANDROID && !defined(__BIONIC_HAVE_UCONTEXT_T) |
| 55 | 54 |
| 56 // Not all versions of Android's C library provide ucontext_t. | 55 // Not all versions of Android's C library provide ucontext_t. |
| 57 // Detect this and provide custom but compatible definitions. Note that these | 56 // Detect this and provide custom but compatible definitions. Note that these |
| 58 // follow the GLibc naming convention to access register values from | 57 // follow the GLibc naming convention to access register values from |
| 59 // mcontext_t. | 58 // mcontext_t. |
| 60 // | 59 // |
| 61 // See http://code.google.com/p/android/issues/detail?id=34784 | 60 // See http://code.google.com/p/android/issues/detail?id=34784 |
| 62 | 61 |
| (...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 222 }; | 221 }; |
| 223 | 222 |
| 224 | 223 |
| 225 class SamplerManager { | 224 class SamplerManager { |
| 226 public: | 225 public: |
| 227 static void AddSampler(Sampler* sampler) { | 226 static void AddSampler(Sampler* sampler) { |
| 228 AtomicGuard atomic_guard(&samplers_access_counter_); | 227 AtomicGuard atomic_guard(&samplers_access_counter_); |
| 229 DCHECK(sampler->IsActive() || !sampler->IsRegistered()); | 228 DCHECK(sampler->IsActive() || !sampler->IsRegistered()); |
| 230 // Add sampler into map if needed. | 229 // Add sampler into map if needed. |
| 231 pthread_t thread_id = sampler->platform_data()->vm_tid(); | 230 pthread_t thread_id = sampler->platform_data()->vm_tid(); |
| 232 HashMap::Entry* entry = | 231 base::HashMap::Entry* entry = sampler_map_.Pointer()->LookupOrInsert( |
| 233 sampler_map_.Pointer()->LookupOrInsert(ThreadKey(thread_id), | 232 ThreadKey(thread_id), ThreadHash(thread_id)); |
| 234 ThreadHash(thread_id)); | |
| 235 DCHECK(entry != NULL); | 233 DCHECK(entry != NULL); |
| 236 if (entry->value == NULL) { | 234 if (entry->value == NULL) { |
| 237 SamplerList* samplers = new SamplerList(); | 235 SamplerList* samplers = new SamplerList(); |
| 238 samplers->push_back(sampler); | 236 samplers->push_back(sampler); |
| 239 entry->value = samplers; | 237 entry->value = samplers; |
| 240 } else { | 238 } else { |
| 241 SamplerList* samplers = reinterpret_cast<SamplerList*>(entry->value); | 239 SamplerList* samplers = reinterpret_cast<SamplerList*>(entry->value); |
| 242 bool exists = false; | 240 bool exists = false; |
| 243 for (SamplerListIterator iter = samplers->begin(); | 241 for (SamplerListIterator iter = samplers->begin(); |
| 244 iter != samplers->end(); ++iter) { | 242 iter != samplers->end(); ++iter) { |
| 245 if (*iter == sampler) { | 243 if (*iter == sampler) { |
| 246 exists = true; | 244 exists = true; |
| 247 break; | 245 break; |
| 248 } | 246 } |
| 249 } | 247 } |
| 250 if (!exists) { | 248 if (!exists) { |
| 251 samplers->push_back(sampler); | 249 samplers->push_back(sampler); |
| 252 } | 250 } |
| 253 } | 251 } |
| 254 } | 252 } |
| 255 | 253 |
| 256 static void RemoveSampler(Sampler* sampler) { | 254 static void RemoveSampler(Sampler* sampler) { |
| 257 AtomicGuard atomic_guard(&samplers_access_counter_); | 255 AtomicGuard atomic_guard(&samplers_access_counter_); |
| 258 DCHECK(sampler->IsActive() || sampler->IsRegistered()); | 256 DCHECK(sampler->IsActive() || sampler->IsRegistered()); |
| 259 // Remove sampler from map. | 257 // Remove sampler from map. |
| 260 pthread_t thread_id = sampler->platform_data()->vm_tid(); | 258 pthread_t thread_id = sampler->platform_data()->vm_tid(); |
| 261 void* thread_key = ThreadKey(thread_id); | 259 void* thread_key = ThreadKey(thread_id); |
| 262 uint32_t thread_hash = ThreadHash(thread_id); | 260 uint32_t thread_hash = ThreadHash(thread_id); |
| 263 HashMap::Entry* entry = sampler_map_.Get().Lookup(thread_key, thread_hash); | 261 base::HashMap::Entry* entry = |
| 262 sampler_map_.Get().Lookup(thread_key, thread_hash); |
| 264 DCHECK(entry != NULL); | 263 DCHECK(entry != NULL); |
| 265 SamplerList* samplers = reinterpret_cast<SamplerList*>(entry->value); | 264 SamplerList* samplers = reinterpret_cast<SamplerList*>(entry->value); |
| 266 for (SamplerListIterator iter = samplers->begin(); iter != samplers->end(); | 265 for (SamplerListIterator iter = samplers->begin(); iter != samplers->end(); |
| 267 ++iter) { | 266 ++iter) { |
| 268 if (*iter == sampler) { | 267 if (*iter == sampler) { |
| 269 samplers->erase(iter); | 268 samplers->erase(iter); |
| 270 break; | 269 break; |
| 271 } | 270 } |
| 272 } | 271 } |
| 273 if (samplers->empty()) { | 272 if (samplers->empty()) { |
| 274 sampler_map_.Pointer()->Remove(thread_key, thread_hash); | 273 sampler_map_.Pointer()->Remove(thread_key, thread_hash); |
| 275 delete samplers; | 274 delete samplers; |
| 276 } | 275 } |
| 277 } | 276 } |
| 278 | 277 |
| 279 private: | 278 private: |
| 280 struct HashMapCreateTrait { | 279 struct HashMapCreateTrait { |
| 281 static void Construct(HashMap* allocated_ptr) { | 280 static void Construct(base::HashMap* allocated_ptr) { |
| 282 new (allocated_ptr) HashMap(HashMap::PointersMatch); | 281 new (allocated_ptr) base::HashMap(base::HashMap::PointersMatch); |
| 283 } | 282 } |
| 284 }; | 283 }; |
| 285 friend class SignalHandler; | 284 friend class SignalHandler; |
| 286 static base::LazyInstance<HashMap, HashMapCreateTrait>::type | 285 static base::LazyInstance<base::HashMap, HashMapCreateTrait>::type |
| 287 sampler_map_; | 286 sampler_map_; |
| 288 static base::AtomicValue<int> samplers_access_counter_; | 287 static base::AtomicValue<int> samplers_access_counter_; |
| 289 }; | 288 }; |
| 290 | 289 |
| 291 base::LazyInstance<HashMap, SamplerManager::HashMapCreateTrait>::type | 290 base::LazyInstance<base::HashMap, SamplerManager::HashMapCreateTrait>::type |
| 292 SamplerManager::sampler_map_ = LAZY_INSTANCE_INITIALIZER; | 291 SamplerManager::sampler_map_ = LAZY_INSTANCE_INITIALIZER; |
| 293 base::AtomicValue<int> SamplerManager::samplers_access_counter_(0); | 292 base::AtomicValue<int> SamplerManager::samplers_access_counter_(0); |
| 294 | 293 |
| 295 | 294 |
| 296 #elif V8_OS_WIN || V8_OS_CYGWIN | 295 #elif V8_OS_WIN || V8_OS_CYGWIN |
| 297 | 296 |
| 298 // ---------------------------------------------------------------------------- | 297 // ---------------------------------------------------------------------------- |
| 299 // Win32 profiler support. On Cygwin we use the same sampler implementation as | 298 // Win32 profiler support. On Cygwin we use the same sampler implementation as |
| 300 // on Win32. | 299 // on Win32. |
| 301 | 300 |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 394 | 393 |
| 395 // As Native Client does not support signal handling, profiling is disabled. | 394 // As Native Client does not support signal handling, profiling is disabled. |
| 396 #if !V8_OS_NACL | 395 #if !V8_OS_NACL |
| 397 void SignalHandler::HandleProfilerSignal(int signal, siginfo_t* info, | 396 void SignalHandler::HandleProfilerSignal(int signal, siginfo_t* info, |
| 398 void* context) { | 397 void* context) { |
| 399 USE(info); | 398 USE(info); |
| 400 if (signal != SIGPROF) return; | 399 if (signal != SIGPROF) return; |
| 401 AtomicGuard atomic_guard(&SamplerManager::samplers_access_counter_, false); | 400 AtomicGuard atomic_guard(&SamplerManager::samplers_access_counter_, false); |
| 402 if (!atomic_guard.is_success()) return; | 401 if (!atomic_guard.is_success()) return; |
| 403 pthread_t thread_id = pthread_self(); | 402 pthread_t thread_id = pthread_self(); |
| 404 HashMap::Entry* entry = | 403 base::HashMap::Entry* entry = SamplerManager::sampler_map_.Pointer()->Lookup( |
| 405 SamplerManager::sampler_map_.Pointer()->Lookup(ThreadKey(thread_id), | 404 ThreadKey(thread_id), ThreadHash(thread_id)); |
| 406 ThreadHash(thread_id)); | |
| 407 if (entry == NULL) return; | 405 if (entry == NULL) return; |
| 408 SamplerList* samplers = reinterpret_cast<SamplerList*>(entry->value); | 406 SamplerList* samplers = reinterpret_cast<SamplerList*>(entry->value); |
| 409 | 407 |
| 410 v8::RegisterState state; | 408 v8::RegisterState state; |
| 411 FillRegisterState(context, &state); | 409 FillRegisterState(context, &state); |
| 412 | 410 |
| 413 for (int i = 0; i < samplers->size(); ++i) { | 411 for (int i = 0; i < samplers->size(); ++i) { |
| 414 Sampler* sampler = (*samplers)[i]; | 412 Sampler* sampler = (*samplers)[i]; |
| 415 Isolate* isolate = sampler->isolate(); | 413 Isolate* isolate = sampler->isolate(); |
| 416 | 414 |
| (...skipping 253 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 670 #endif | 668 #endif |
| 671 SampleStack(state); | 669 SampleStack(state); |
| 672 } | 670 } |
| 673 ResumeThread(profiled_thread); | 671 ResumeThread(profiled_thread); |
| 674 } | 672 } |
| 675 | 673 |
| 676 #endif // USE_SIGNALS | 674 #endif // USE_SIGNALS |
| 677 | 675 |
| 678 } // namespace sampler | 676 } // namespace sampler |
| 679 } // namespace v8 | 677 } // namespace v8 |
| OLD | NEW |