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

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

Issue 2052803002: Alternative heap dumping scheme. Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: New stackFrames format Created 4 years, 3 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
« no previous file with comments | « base/trace_event/heap_profiler_stack_frame_deduplicator.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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_stack_frame_deduplicator.h" 5 #include "base/trace_event/heap_profiler_stack_frame_deduplicator.h"
6 6
7 #include <inttypes.h> 7 #include <inttypes.h>
8 #include <stddef.h> 8 #include <stddef.h>
9 9
10 #include <string> 10 #include <string>
11 #include <utility> 11 #include <utility>
12 12
13 #include "base/strings/stringprintf.h" 13 #include "base/strings/stringprintf.h"
14 #include "base/trace_event/trace_event_argument.h" 14 #include "base/trace_event/trace_event_argument.h"
15 #include "base/trace_event/trace_event_memory_overhead.h" 15 #include "base/trace_event/trace_event_memory_overhead.h"
16 16
17 namespace base { 17 namespace base {
18 namespace trace_event { 18 namespace trace_event {
19 19
20 StackFrameDeduplicator::FrameNode::FrameNode(StackFrame frame, 20 StackFrameDeduplicator::FrameNode::FrameNode(StackFrame frame,
21 int parent_frame_index) 21 int parent_frame_index)
22 : frame(frame), parent_frame_index(parent_frame_index) {} 22 : frame(frame), parent_frame_index(parent_frame_index), indexed(false) {}
23 StackFrameDeduplicator::FrameNode::FrameNode(const FrameNode& other) = default; 23 StackFrameDeduplicator::FrameNode::FrameNode(const FrameNode& other) = default;
24 StackFrameDeduplicator::FrameNode::~FrameNode() {} 24 StackFrameDeduplicator::FrameNode::~FrameNode() {}
25 25
26 StackFrameDeduplicator::StackFrameDeduplicator() {} 26 StackFrameDeduplicator::StackFrameDeduplicator() {}
27 StackFrameDeduplicator::~StackFrameDeduplicator() {} 27 StackFrameDeduplicator::~StackFrameDeduplicator() {}
28 28
29 int StackFrameDeduplicator::Insert(const StackFrame* beginFrame, 29 int StackFrameDeduplicator::Insert(const StackFrame* beginFrame,
30 const StackFrame* endFrame) { 30 const StackFrame* endFrame) {
31 int frame_index = -1; 31 int frame_index = -1;
32 std::map<StackFrame, int>* nodes = &roots_; 32 std::map<StackFrame, int>* nodes = &roots_;
(...skipping 19 matching lines...) Expand all
52 // might need to resize, and this invalidates the |nodes| pointer. 52 // might need to resize, and this invalidates the |nodes| pointer.
53 frames_.push_back(frame_node); 53 frames_.push_back(frame_node);
54 } else { 54 } else {
55 // A tree node for this frame exists. Look for the next one. 55 // A tree node for this frame exists. Look for the next one.
56 frame_index = node->second; 56 frame_index = node->second;
57 } 57 }
58 58
59 nodes = &frames_[frame_index].children; 59 nodes = &frames_[frame_index].children;
60 } 60 }
61 61
62 if (frame_index != -1) {
63 frames_[frame_index].indexed = true;
64 }
65
62 return frame_index; 66 return frame_index;
63 } 67 }
64 68
65 void StackFrameDeduplicator::AppendAsTraceFormat(std::string* out) const { 69 void StackFrameDeduplicator::AppendAsTraceFormat(std::string* out) const {
70 #if defined(NEW_TRACE_FORMAT)
71 std::string stringify_buffer;
72 std::unique_ptr<TracedValue> traced_value(new TracedValue);
73
74 std::map<StackFrame, size_t> unique_frame_indexes;
75 traced_value->BeginDictionary("hierarchy");
76 {
77 std::function<void(const std::map<StackFrame, int>&)> append_level =
78 [&](const std::map<StackFrame, int>& level) {
79 for (const auto& frame_and_index: level) {
80 int node_index = frame_and_index.second;
81 const FrameNode& node = frames_[node_index];
82
83 size_t unique_index = unique_frame_indexes.insert(
84 {node.frame, unique_frame_indexes.size()}).first->second;
85 SStringPrintf(&stringify_buffer, "%zu", unique_index);
86 traced_value->BeginDictionaryWithCopiedName(stringify_buffer);
87
88 if (node.indexed) {
89 SStringPrintf(&stringify_buffer, "%d", node_index);
90 traced_value->SetString("bt", stringify_buffer);
91 }
92
93 append_level(node.children);
94
95 traced_value->EndDictionary();
96 }
97 };
98
99 append_level(roots_);
100 }
101 traced_value->EndDictionary();
102
103 traced_value->BeginArray("names");
104 {
105 std::vector<StackFrame> unique_frames;
106 unique_frames.resize(unique_frame_indexes.size());
107 for (const auto& frame_and_index: unique_frame_indexes) {
108 DCHECK(frame_and_index.second < unique_frames.size());
109 unique_frames[frame_and_index.second] = frame_and_index.first;
110 }
111 for (const auto& frame: unique_frames) {
112 switch (frame.type) {
113 case StackFrame::Type::TRACE_EVENT_NAME:
114 traced_value->AppendString(static_cast<const char*>(frame.value));
115 break;
116 case StackFrame::Type::THREAD_NAME:
117 SStringPrintf(&stringify_buffer,
118 "[Thread: %s]",
119 static_cast<const char*>(frame.value));
120 traced_value->AppendString(stringify_buffer);
121 break;
122 case StackFrame::Type::PROGRAM_COUNTER:
123 SStringPrintf(&stringify_buffer,
124 "pc:%" PRIxPTR,
125 reinterpret_cast<uintptr_t>(frame.value));
126 traced_value->AppendString(stringify_buffer);
127 break;
128 }
129 }
130 }
131 traced_value->EndArray();
132
133 std::string trace;
134 traced_value->AppendAsTraceFormat(out);
135
136 #else // !defined(NEW_TRACE_FORMAT)
137
66 out->append("{"); // Begin the |stackFrames| dictionary. 138 out->append("{"); // Begin the |stackFrames| dictionary.
67 139
68 int i = 0; 140 int i = 0;
69 auto frame_node = begin(); 141 auto frame_node = begin();
70 auto it_end = end(); 142 auto it_end = end();
71 std::string stringify_buffer; 143 std::string stringify_buffer;
72 144
73 while (frame_node != it_end) { 145 while (frame_node != it_end) {
74 // The |stackFrames| format is a dictionary, not an array, so the 146 // The |stackFrames| format is a dictionary, not an array, so the
75 // keys are stringified indices. Write the index manually, then use 147 // keys are stringified indices. Write the index manually, then use
(...skipping 29 matching lines...) Expand all
105 frame_node_value->AppendAsTraceFormat(out); 177 frame_node_value->AppendAsTraceFormat(out);
106 178
107 i++; 179 i++;
108 frame_node++; 180 frame_node++;
109 181
110 if (frame_node != it_end) 182 if (frame_node != it_end)
111 out->append(","); 183 out->append(",");
112 } 184 }
113 185
114 out->append("}"); // End the |stackFrames| dictionary. 186 out->append("}"); // End the |stackFrames| dictionary.
187
188 #endif // defined(NEW_TRACE_FORMAT)
115 } 189 }
116 190
117 void StackFrameDeduplicator::EstimateTraceMemoryOverhead( 191 void StackFrameDeduplicator::EstimateTraceMemoryOverhead(
118 TraceEventMemoryOverhead* overhead) { 192 TraceEventMemoryOverhead* overhead) {
119 // The sizes here are only estimates; they fail to take into account the 193 // The sizes here are only estimates; they fail to take into account the
120 // overhead of the tree nodes for the map, but as an estimate this should be 194 // overhead of the tree nodes for the map, but as an estimate this should be
121 // fine. 195 // fine.
122 size_t maps_size = roots_.size() * sizeof(std::pair<StackFrame, int>); 196 size_t maps_size = roots_.size() * sizeof(std::pair<StackFrame, int>);
123 size_t frames_allocated = frames_.capacity() * sizeof(FrameNode); 197 size_t frames_allocated = frames_.capacity() * sizeof(FrameNode);
124 size_t frames_resident = frames_.size() * sizeof(FrameNode); 198 size_t frames_resident = frames_.size() * sizeof(FrameNode);
125 199
126 for (const FrameNode& node : frames_) 200 for (const FrameNode& node : frames_)
127 maps_size += node.children.size() * sizeof(std::pair<StackFrame, int>); 201 maps_size += node.children.size() * sizeof(std::pair<StackFrame, int>);
128 202
129 overhead->Add("StackFrameDeduplicator", 203 overhead->Add("StackFrameDeduplicator",
130 sizeof(StackFrameDeduplicator) + maps_size + frames_allocated, 204 sizeof(StackFrameDeduplicator) + maps_size + frames_allocated,
131 sizeof(StackFrameDeduplicator) + maps_size + frames_resident); 205 sizeof(StackFrameDeduplicator) + maps_size + frames_resident);
132 } 206 }
133 207
134 } // namespace trace_event 208 } // namespace trace_event
135 } // namespace base 209 } // namespace base
OLDNEW
« no previous file with comments | « base/trace_event/heap_profiler_stack_frame_deduplicator.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698