Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 Loading... | |
| 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 Loading... | |
| 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_ |
| OLD | NEW |