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

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

Issue 2650863003: [tracing] Switch to new heap dump format. (Closed)
Patch Set: DCHECK for continuous mode Created 3 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_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/heap_profiler_string_deduplicator.h"
14 #include "base/trace_event/memory_usage_estimator.h" 15 #include "base/trace_event/memory_usage_estimator.h"
15 #include "base/trace_event/trace_event_argument.h" 16 #include "base/trace_event/trace_event_argument.h"
16 #include "base/trace_event/trace_event_memory_overhead.h" 17 #include "base/trace_event/trace_event_memory_overhead.h"
17 18
18 namespace base { 19 namespace base {
19 namespace trace_event { 20 namespace trace_event {
20 21
21 StackFrameDeduplicator::FrameNode::FrameNode(StackFrame frame, 22 StackFrameDeduplicator::FrameNode::FrameNode(StackFrame frame,
22 int parent_frame_index) 23 int parent_frame_index)
23 : frame(frame), parent_frame_index(parent_frame_index) {} 24 : frame(frame), parent_frame_index(parent_frame_index) {}
24 StackFrameDeduplicator::FrameNode::FrameNode(const FrameNode& other) = default; 25 StackFrameDeduplicator::FrameNode::FrameNode(const FrameNode& other) = default;
25 StackFrameDeduplicator::FrameNode::~FrameNode() {} 26 StackFrameDeduplicator::FrameNode::~FrameNode() {}
26 27
27 size_t StackFrameDeduplicator::FrameNode::EstimateMemoryUsage() const { 28 size_t StackFrameDeduplicator::FrameNode::EstimateMemoryUsage() const {
28 return base::trace_event::EstimateMemoryUsage(children); 29 return base::trace_event::EstimateMemoryUsage(children);
29 } 30 }
30 31
31 StackFrameDeduplicator::StackFrameDeduplicator() {} 32 StackFrameDeduplicator::StackFrameDeduplicator(
33 StringDeduplicator* string_deduplicator)
34 : string_deduplicator_(string_deduplicator), last_exported_index_(0) {
35 // Add implicit entry for id 0 (empty backtraces).
36 frames_.push_back({StackFrame::FromTraceEventName(nullptr), -1});
Primiano Tucci (use gerrit) 2017/03/09 11:47:44 you say 0 above but push -1 here?
DmitrySkiba 2017/03/14 22:12:47 Oh, the joy of unnamed constants :) This -1 means
37 }
32 StackFrameDeduplicator::~StackFrameDeduplicator() {} 38 StackFrameDeduplicator::~StackFrameDeduplicator() {}
33 39
34 int StackFrameDeduplicator::Insert(const StackFrame* beginFrame, 40 int StackFrameDeduplicator::Insert(const StackFrame* beginFrame,
35 const StackFrame* endFrame) { 41 const StackFrame* endFrame) {
42 if (beginFrame == endFrame) {
43 // Empty backtraces are mapped to id 0.
44 return 0;
45 }
46
36 int frame_index = -1; 47 int frame_index = -1;
37 std::map<StackFrame, int>* nodes = &roots_; 48 std::map<StackFrame, int>* nodes = &roots_;
38 49
39 // Loop through the frames, early out when a frame is null. 50 // Loop through the frames, early out when a frame is null.
40 for (const StackFrame* it = beginFrame; it != endFrame; it++) { 51 for (const StackFrame* it = beginFrame; it != endFrame; it++) {
41 StackFrame frame = *it; 52 StackFrame frame = *it;
42 53
43 auto node = nodes->find(frame); 54 auto node = nodes->find(frame);
44 if (node == nodes->end()) { 55 if (node == nodes->end()) {
45 // There is no tree node for this frame yet, create it. The parent node 56 // There is no tree node for this frame yet, create it. The parent node
(...skipping 14 matching lines...) Expand all
60 // A tree node for this frame exists. Look for the next one. 71 // A tree node for this frame exists. Look for the next one.
61 frame_index = node->second; 72 frame_index = node->second;
62 } 73 }
63 74
64 nodes = &frames_[frame_index].children; 75 nodes = &frames_[frame_index].children;
65 } 76 }
66 77
67 return frame_index; 78 return frame_index;
68 } 79 }
69 80
70 void StackFrameDeduplicator::AppendAsTraceFormat(std::string* out) const { 81 void StackFrameDeduplicator::ExportIncrementally(TracedValue* traced_value) {
71 out->append("{"); // Begin the |stackFrames| dictionary.
72
73 int i = 0;
74 auto frame_node = begin();
75 auto it_end = end();
76 std::string stringify_buffer; 82 std::string stringify_buffer;
77 83
78 while (frame_node != it_end) { 84 for (; last_exported_index_ < frames_.size(); ++last_exported_index_) {
79 // The |stackFrames| format is a dictionary, not an array, so the 85 const auto& frame_node = frames_[last_exported_index_];
80 // keys are stringified indices. Write the index manually, then use 86 traced_value->BeginDictionary();
81 // |TracedValue| to format the object. This is to avoid building the
82 // entire dictionary as a |TracedValue| in memory.
83 SStringPrintf(&stringify_buffer, "\"%d\":", i);
84 out->append(stringify_buffer);
85 87
86 std::unique_ptr<TracedValue> frame_node_value(new TracedValue); 88 traced_value->SetInteger("id", last_exported_index_);
87 const StackFrame& frame = frame_node->frame; 89
90 int name_string_id = 0;
91 const StackFrame& frame = frame_node.frame;
88 switch (frame.type) { 92 switch (frame.type) {
89 case StackFrame::Type::TRACE_EVENT_NAME: 93 case StackFrame::Type::TRACE_EVENT_NAME:
90 frame_node_value->SetString( 94 name_string_id =
91 "name", static_cast<const char*>(frame.value)); 95 string_deduplicator_->Insert(static_cast<const char*>(frame.value));
92 break; 96 break;
93 case StackFrame::Type::THREAD_NAME: 97 case StackFrame::Type::THREAD_NAME:
94 SStringPrintf(&stringify_buffer, 98 SStringPrintf(&stringify_buffer,
95 "[Thread: %s]", 99 "[Thread: %s]",
96 static_cast<const char*>(frame.value)); 100 static_cast<const char*>(frame.value));
97 frame_node_value->SetString("name", stringify_buffer); 101 name_string_id = string_deduplicator_->Insert(stringify_buffer);
98 break; 102 break;
99 case StackFrame::Type::PROGRAM_COUNTER: 103 case StackFrame::Type::PROGRAM_COUNTER:
100 SStringPrintf(&stringify_buffer, 104 SStringPrintf(&stringify_buffer,
101 "pc:%" PRIxPTR, 105 "pc:%" PRIxPTR,
102 reinterpret_cast<uintptr_t>(frame.value)); 106 reinterpret_cast<uintptr_t>(frame.value));
103 frame_node_value->SetString("name", stringify_buffer); 107 name_string_id = string_deduplicator_->Insert(stringify_buffer);
104 break; 108 break;
105 } 109 }
106 if (frame_node->parent_frame_index >= 0) { 110 traced_value->SetInteger("name_sid", name_string_id);
Primiano Tucci (use gerrit) 2017/03/09 11:47:44 see my comment above about shortening these to "n"
107 SStringPrintf(&stringify_buffer, "%d", frame_node->parent_frame_index); 111
108 frame_node_value->SetString("parent", stringify_buffer); 112 if (frame_node.parent_frame_index >= 0) {
113 traced_value->SetInteger("parent", frame_node.parent_frame_index);
109 } 114 }
110 frame_node_value->AppendAsTraceFormat(out);
111 115
112 i++; 116 traced_value->EndDictionary();
113 frame_node++;
114
115 if (frame_node != it_end)
116 out->append(",");
117 } 117 }
118
119 out->append("}"); // End the |stackFrames| dictionary.
120 } 118 }
121 119
122 void StackFrameDeduplicator::EstimateTraceMemoryOverhead( 120 void StackFrameDeduplicator::EstimateTraceMemoryOverhead(
123 TraceEventMemoryOverhead* overhead) { 121 TraceEventMemoryOverhead* overhead) {
124 size_t memory_usage = 122 size_t memory_usage =
125 EstimateMemoryUsage(frames_) + EstimateMemoryUsage(roots_); 123 EstimateMemoryUsage(frames_) + EstimateMemoryUsage(roots_);
126 overhead->Add("StackFrameDeduplicator", 124 overhead->Add("StackFrameDeduplicator",
127 sizeof(StackFrameDeduplicator) + memory_usage); 125 sizeof(StackFrameDeduplicator) + memory_usage);
128 } 126 }
129 127
130 } // namespace trace_event 128 } // namespace trace_event
131 } // namespace base 129 } // namespace base
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698