Chromium Code Reviews| Index: base/trace_event/heap_profiler_allocation_context_tracker.cc |
| diff --git a/base/trace_event/heap_profiler_allocation_context_tracker.cc b/base/trace_event/heap_profiler_allocation_context_tracker.cc |
| index 791ab7a6fe1d46f6dbda2cc3f5bdaa849a5a5b6d..8a4dbc7d8ca8f22f698ed0de63c4b9a408dd57e1 100644 |
| --- a/base/trace_event/heap_profiler_allocation_context_tracker.cc |
| +++ b/base/trace_event/heap_profiler_allocation_context_tracker.cc |
| @@ -18,6 +18,10 @@ subtle::Atomic32 AllocationContextTracker::capture_enabled_ = 0; |
| namespace { |
| +const size_t kMaxStackDepth = 128u; |
| +AllocationContextTracker* const kInitializingSentinel = |
| + reinterpret_cast<AllocationContextTracker*>(-1); |
| + |
| ThreadLocalStorage::StaticSlot g_tls_alloc_ctx_tracker = TLS_INITIALIZER; |
| // This function is added to the TLS slot to clean up the instance when the |
| @@ -28,19 +32,40 @@ void DestructAllocationContextTracker(void* alloc_ctx_tracker) { |
| } // namespace |
| -AllocationContextTracker::AllocationContextTracker() {} |
| +AllocationContextTracker::AllocationContextTracker() { |
| + pseudo_stack_.reserve(kMaxStackDepth); |
| +} |
| AllocationContextTracker::~AllocationContextTracker() {} |
| // static |
| -AllocationContextTracker* AllocationContextTracker::GetThreadLocalTracker() { |
| +AllocationContextTracker::InitializationState |
| +AllocationContextTracker::GetStateForCurrentThread() { |
| auto tracker = |
| static_cast<AllocationContextTracker*>(g_tls_alloc_ctx_tracker.Get()); |
| + if (!tracker) |
| + return kNotInitialized; |
| + if (tracker == kInitializingSentinel) |
| + return kInitializing; |
| + return kInitialized; |
| +} |
| - if (!tracker) { |
| - tracker = new AllocationContextTracker(); |
| - g_tls_alloc_ctx_tracker.Set(tracker); |
| - } |
| +// static |
| +AllocationContextTracker* |
| +AllocationContextTracker::InitializeForCurrentThread() { |
| + DCHECK_EQ(kNotInitialized, GetStateForCurrentThread()); |
| + g_tls_alloc_ctx_tracker.Set(kInitializingSentinel); |
| + AllocationContextTracker* tracker = new AllocationContextTracker(); |
| + g_tls_alloc_ctx_tracker.Set(tracker); |
| + return tracker; |
| +} |
| +// static |
| +AllocationContextTracker* AllocationContextTracker::GetThreadLocalTracker() { |
| + auto tracker = |
| + static_cast<AllocationContextTracker*>(g_tls_alloc_ctx_tracker.Get()); |
| + DCHECK_NE(kInitializingSentinel, tracker); |
| + if (!tracker) |
| + tracker = InitializeForCurrentThread(); |
| return tracker; |
| } |
| @@ -62,8 +87,10 @@ void AllocationContextTracker::PushPseudoStackFrame(StackFrame frame) { |
| // Impose a limit on the height to verify that every push is popped, because |
| // in practice the pseudo stack never grows higher than ~20 frames. |
|
ssid
2016/03/11 19:51:10
It could happen when someone tries to trace recurs
Primiano Tucci (use gerrit)
2016/03/21 19:29:24
Never seen this happening in practice. If we do I
|
| - DCHECK_LT(tracker->pseudo_stack_.size(), 128u); |
| - tracker->pseudo_stack_.push_back(frame); |
| + if (tracker->pseudo_stack_.size() < kMaxStackDepth) |
| + tracker->pseudo_stack_.push_back(frame); |
| + else |
| + NOTREACHED(); |
| } |
| // static |