Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(202)

Side by Side Diff: base/trace_event/heap_profiler_allocation_context_tracker.cc

Issue 1784133002: [tracing] Adding task information to heap profiler (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: nits. Created 4 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 The Chromium 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 "base/trace_event/heap_profiler_allocation_context_tracker.h" 5 #include "base/trace_event/heap_profiler_allocation_context_tracker.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <iterator> 8 #include <iterator>
9 9
10 #include "base/atomicops.h" 10 #include "base/atomicops.h"
11 #include "base/compiler_specific.h"
11 #include "base/threading/thread_local_storage.h" 12 #include "base/threading/thread_local_storage.h"
12 #include "base/trace_event/heap_profiler_allocation_context.h" 13 #include "base/trace_event/heap_profiler_allocation_context.h"
13 14
14 namespace base { 15 namespace base {
15 namespace trace_event { 16 namespace trace_event {
16 17
17 subtle::Atomic32 AllocationContextTracker::capture_enabled_ = 0; 18 subtle::Atomic32 AllocationContextTracker::capture_enabled_ = 0;
18 19
19 namespace { 20 namespace {
20 21
21 const size_t kMaxStackDepth = 128u; 22 const size_t kMaxStackDepth = 128u;
23 const size_t kMaxTaskDepth = 16u;
22 AllocationContextTracker* const kInitializingSentinel = 24 AllocationContextTracker* const kInitializingSentinel =
23 reinterpret_cast<AllocationContextTracker*>(-1); 25 reinterpret_cast<AllocationContextTracker*>(-1);
24 26
25 ThreadLocalStorage::StaticSlot g_tls_alloc_ctx_tracker = TLS_INITIALIZER; 27 ThreadLocalStorage::StaticSlot g_tls_alloc_ctx_tracker = TLS_INITIALIZER;
26 28
27 // This function is added to the TLS slot to clean up the instance when the 29 // This function is added to the TLS slot to clean up the instance when the
28 // thread exits. 30 // thread exits.
29 void DestructAllocationContextTracker(void* alloc_ctx_tracker) { 31 void DestructAllocationContextTracker(void* alloc_ctx_tracker) {
30 delete static_cast<AllocationContextTracker*>(alloc_ctx_tracker); 32 delete static_cast<AllocationContextTracker*>(alloc_ctx_tracker);
31 } 33 }
32 34
33 } // namespace 35 } // namespace
34 36
37 AllocationContextTracker::ScopedTaskExecutionEvent::ScopedTaskExecutionEvent(
38 const char* category_group,
39 const char* posted_reason)
40 : category_(category_group) {
41 if (UNLIKELY(capture_enabled())) {
42 AllocationContextTracker* tracker = GetInstanceForCurrentThread();
43 tracker->PushCurrentCategoryName(category_);
44 }
45 }
46
47 AllocationContextTracker::ScopedTaskExecutionEvent::
48 ~ScopedTaskExecutionEvent() {
49 if (UNLIKELY(capture_enabled())) {
50 AllocationContextTracker* tracker = GetInstanceForCurrentThread();
51 tracker->PopCurrentCategoryName(category_);
52 }
53 }
54
35 // static 55 // static
36 AllocationContextTracker* 56 AllocationContextTracker*
37 AllocationContextTracker::GetInstanceForCurrentThread() { 57 AllocationContextTracker::GetInstanceForCurrentThread() {
38 AllocationContextTracker* tracker = 58 AllocationContextTracker* tracker =
39 static_cast<AllocationContextTracker*>(g_tls_alloc_ctx_tracker.Get()); 59 static_cast<AllocationContextTracker*>(g_tls_alloc_ctx_tracker.Get());
40 if (tracker == kInitializingSentinel) 60 if (tracker == kInitializingSentinel)
41 return nullptr; // Re-entrancy case. 61 return nullptr; // Re-entrancy case.
42 62
43 if (!tracker) { 63 if (!tracker) {
44 g_tls_alloc_ctx_tracker.Set(kInitializingSentinel); 64 g_tls_alloc_ctx_tracker.Set(kInitializingSentinel);
45 tracker = new AllocationContextTracker(); 65 tracker = new AllocationContextTracker();
46 g_tls_alloc_ctx_tracker.Set(tracker); 66 g_tls_alloc_ctx_tracker.Set(tracker);
47 } 67 }
48 68
49 return tracker; 69 return tracker;
50 } 70 }
51 71
52 AllocationContextTracker::AllocationContextTracker() { 72 AllocationContextTracker::AllocationContextTracker() {
53 pseudo_stack_.reserve(kMaxStackDepth); 73 pseudo_stack_.reserve(kMaxStackDepth);
74 categories_.reserve(kMaxTaskDepth);
54 } 75 }
55 AllocationContextTracker::~AllocationContextTracker() {} 76 AllocationContextTracker::~AllocationContextTracker() {}
56 77
57 // static 78 // static
58 void AllocationContextTracker::SetCaptureEnabled(bool enabled) { 79 void AllocationContextTracker::SetCaptureEnabled(bool enabled) {
59 // When enabling capturing, also initialize the TLS slot. This does not create 80 // When enabling capturing, also initialize the TLS slot. This does not create
60 // a TLS instance yet. 81 // a TLS instance yet.
61 if (enabled && !g_tls_alloc_ctx_tracker.initialized()) 82 if (enabled && !g_tls_alloc_ctx_tracker.initialized())
62 g_tls_alloc_ctx_tracker.Initialize(DestructAllocationContextTracker); 83 g_tls_alloc_ctx_tracker.Initialize(DestructAllocationContextTracker);
63 84
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
115 136
116 // Copy as much of the bottom of the pseudo stack into the backtrace as 137 // Copy as much of the bottom of the pseudo stack into the backtrace as
117 // possible. 138 // possible.
118 for (; src != src_end && dst != dst_end; src++, dst++) 139 for (; src != src_end && dst != dst_end; src++, dst++)
119 *dst = *src; 140 *dst = *src;
120 141
121 // If there is room for more, fill the remaining slots with empty frames. 142 // If there is room for more, fill the remaining slots with empty frames.
122 std::fill(dst, dst_end, nullptr); 143 std::fill(dst, dst_end, nullptr);
123 } 144 }
124 145
125 ctx.type_name = nullptr; 146 // Set the default type name to file name where the task was posted from.
147 // TODO(ssid): Fix crbug.com/594803 to add file name as 3rd dimension
148 // (component name) in the heap profiler and not piggy back on the type name.
149 ctx.type_name = categories_.empty() ? nullptr : categories_.back();
126 150
127 return ctx; 151 return ctx;
128 } 152 }
129 153
154 void AllocationContextTracker::PushCurrentCategoryName(const char* category) {
155 DCHECK(category != nullptr);
Primiano Tucci (use gerrit) 2016/03/25 01:56:31 I think as a general stylistic pattern we don't bo
ssid 2016/03/28 18:14:49 Done.
156 if (categories_.size() < kMaxTaskDepth)
157 categories_.push_back(category);
158 else
159 NOTREACHED();
160 }
161
162 void AllocationContextTracker::PopCurrentCategoryName(const char* category) {
163 DCHECK_EQ(category, categories_.back())
164 << "Encountered an unmatched category end";
165 categories_.pop_back();
166 }
167
130 } // namespace trace_event 168 } // namespace trace_event
131 } // namespace base 169 } // namespace base
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698