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

Side by Side Diff: base/trace_event/memory_profiler_allocation_context.h

Issue 1372523002: [tracing] Implement trace_event::AllocationContext (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@alloccontext
Patch Set: Fix string interning bug, extract backtrace into struct Created 5 years, 2 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 #ifndef BASE_TRACE_EVENT_MEMORY_PROFILER_ALLOCATION_CONTEXT_H_ 5 #ifndef BASE_TRACE_EVENT_MEMORY_PROFILER_ALLOCATION_CONTEXT_H_
6 #define BASE_TRACE_EVENT_MEMORY_PROFILER_ALLOCATION_CONTEXT_H_ 6 #define BASE_TRACE_EVENT_MEMORY_PROFILER_ALLOCATION_CONTEXT_H_
7 7
8 #include <vector> 8 #include <vector>
9 9
10 #include "base/atomicops.h" 10 #include "base/atomicops.h"
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
45 if (!stack_.empty()) 45 if (!stack_.empty())
46 stack_.pop_back(); 46 stack_.pop_back();
47 } 47 }
48 48
49 private: 49 private:
50 std::vector<StackFrame> stack_; 50 std::vector<StackFrame> stack_;
51 51
52 DISALLOW_COPY_AND_ASSIGN(AllocationStack); 52 DISALLOW_COPY_AND_ASSIGN(AllocationStack);
53 }; 53 };
54 54
55 class BASE_EXPORT AllocationContext { 55 // The backtrace in the allocation context is a snapshot of the stack. For now,
56 // TODO(ruuda): Fill this in a follow-up CL. 56 // this is the pseudo stack where frames are created by trace event macros. In
57 // the future, we might add the option to use the native call stack. In that
58 // case, |Backtrace| and |AllocationContextTracker::GetContext| might have
59 // different implementations that can be selected by a compile time flag.
60
61 // The number of stack frames stored in the backtrace is a trade off between
62 // memory used for tracing and accuracy. Measurements on a prototype revealed
63 // that the stack depth sampled at every allocation has the following
64 // distribution. (Columns are depth and percentage.)
65 //
66 // 0 0.8 #
Primiano Tucci (use gerrit) 2015/10/05 12:35:38 The histogram is nice but it's probably too much f
Ruud van Asseldonk 2015/10/05 14:20:45 Done.
67 // 1 2.1 ##
68 // 2 2.3 ##
69 // 3 8.4 ########
70 // 4 8.8 ########
71 // 5 7.6 #######
72 // 6 8.7 ########
73 // 7 21.7 ####################
74 // 8 14.2 ##############
75 // 9 10.2 ##########
76 // 10 5.7 ######
77 // 11 1.8 ##
78 // 12 1.2 #
79 // 13 0.2
80 // 14 0.4
81 // 15 0.3
82 // 16 0.3
83 // 17 0.5 #
84 // 18 0.4
85 // 19 0.3
86 // 20 0.4
87 // 21 0.4
88 //
89 // In 60 percent of the cases, stack depth <= 7.
90 // In 87 percent of the cases, stack depth <= 9.
91 // In 95 percent of the cases, stack depth <= 11.
92
93 struct BASE_EXPORT Backtrace {
94 // Unused backtrace frames are filled with nullptr frames. If the stack is
95 // higher than what can be stored here, the topmost frames are stored. Based
96 // on the data above, a depth of 8 captures the full stack in the vast
97 // majority of the cases, and missing frames at the bottom can often be
98 // reconstructed given the top frames.
99 StackFrame frames[8];
Primiano Tucci (use gerrit) 2015/10/05 12:35:38 Looking at the data above, shouldn't this be 10-12
Ruud van Asseldonk 2015/10/05 14:20:45 The thing with statistics is that you can often us
100 };
101
102 // The allocation context is what is stored in the bookkeeping structure with
Primiano Tucci (use gerrit) 2015/10/05 12:35:38 I'd probably word it as "The allocation context is
Ruud van Asseldonk 2015/10/05 14:20:45 Done.
103 // every allocation. To simplify memory management for bookkeeping, this struct
104 // has a fixed size. All |const char*|s here must have static lifetime. The
105 // struct is designed such that a memzero'd instance is a valid context with
Primiano Tucci (use gerrit) 2015/10/05 12:35:38 As discussed remove the memzero comment
Ruud van Asseldonk 2015/10/05 14:20:45 Done.
106 // empty backtrace and no context fields.
107 struct BASE_EXPORT AllocationContext {
108 Backtrace backtrace;
109
110 // There is room for two arbitrary context fields, which can be set by the
111 // |TRACE_ALLOCATION_CONTEXT| macro. A nullptr key indicates that the field is
112 // unused.
113 std::pair<const char*, const char*> fields[2];
57 }; 114 };
58 115
59 // The allocation context tracker keeps track of thread-local context for heap 116 // The allocation context tracker keeps track of thread-local context for heap
60 // profiling. It includes a pseudo stack of trace events, and it might contain 117 // profiling. It includes a pseudo stack of trace events, and it might contain
61 // arbitrary (key, value) context. On every allocation the tracker provides a 118 // arbitrary (key, value) context. On every allocation the tracker provides a
62 // snapshot of its context in the form of an |AllocationContext| that is to be 119 // snapshot of its context in the form of an |AllocationContext| that is to be
63 // stored together with the allocation details. 120 // stored together with the allocation details.
64 class BASE_EXPORT AllocationContextTracker { 121 class BASE_EXPORT AllocationContextTracker {
65 public: 122 public:
66 // Globally enables capturing allocation context. 123 // Globally enables capturing allocation context.
(...skipping 18 matching lines...) Expand all
85 // Sets a thread-local (key, value) pair. 142 // Sets a thread-local (key, value) pair.
86 static void SetContextField(const char* key, const char* value); 143 static void SetContextField(const char* key, const char* value);
87 144
88 // Removes the (key, value) pair with the specified key from the thread-local 145 // Removes the (key, value) pair with the specified key from the thread-local
89 // context. 146 // context.
90 static void UnsetContextField(const char* key); 147 static void UnsetContextField(const char* key);
91 148
92 // Returns a snapshot of the current thread-local context. 149 // Returns a snapshot of the current thread-local context.
93 static AllocationContext GetContext(); 150 static AllocationContext GetContext();
94 151
95 // TODO(ruuda): Remove in a follow-up CL, this is only used for testing now.
96 static AllocationStack* GetPseudoStackForTesting();
97
98 ~AllocationContextTracker(); 152 ~AllocationContextTracker();
99 153
100 private: 154 private:
101 AllocationContextTracker(); 155 AllocationContextTracker();
102 156
103 static AllocationContextTracker* GetThreadLocalTracker(); 157 static AllocationContextTracker* GetThreadLocalTracker();
104 158
105 static subtle::Atomic32 capture_enabled_; 159 static subtle::Atomic32 capture_enabled_;
106 160
107 // The pseudo stack where frames are |TRACE_EVENT| names. 161 // The pseudo stack where frames are |TRACE_EVENT| names.
108 AllocationStack pseudo_stack_; 162 AllocationStack pseudo_stack_;
109 163
110 // A dictionary of arbitrary context. 164 // A dictionary of arbitrary context.
111 SmallMap<std::map<const char*, const char*>> context_; 165 SmallMap<std::map<const char*, const char*>> context_;
112 166
113 DISALLOW_COPY_AND_ASSIGN(AllocationContextTracker); 167 DISALLOW_COPY_AND_ASSIGN(AllocationContextTracker);
114 }; 168 };
115 169
116 } // namespace trace_event 170 } // namespace trace_event
117 } // namespace base 171 } // namespace base
118 172
119 #endif // BASE_TRACE_EVENT_MEMORY_PROFILER_ALLOCATION_CONTEXT_H_ 173 #endif // BASE_TRACE_EVENT_MEMORY_PROFILER_ALLOCATION_CONTEXT_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698