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 |