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

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: Fix rebase damage Created 3 years, 7 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(FrameNode(StackFrame::FromTraceEventName(nullptr),
37 FrameNode::kInvalidFrameIndex));
38 }
32 StackFrameDeduplicator::~StackFrameDeduplicator() {} 39 StackFrameDeduplicator::~StackFrameDeduplicator() {}
33 40
34 int StackFrameDeduplicator::Insert(const StackFrame* beginFrame, 41 int StackFrameDeduplicator::Insert(const StackFrame* beginFrame,
35 const StackFrame* endFrame) { 42 const StackFrame* endFrame) {
36 int frame_index = -1; 43 if (beginFrame == endFrame) {
44 // Empty backtraces are mapped to id 0.
45 return 0;
46 }
47
48 int frame_index = FrameNode::kInvalidFrameIndex;
37 std::map<StackFrame, int>* nodes = &roots_; 49 std::map<StackFrame, int>* nodes = &roots_;
38 50
39 // Loop through the frames, early out when a frame is null. 51 // Loop through the frames, early out when a frame is null.
40 for (const StackFrame* it = beginFrame; it != endFrame; it++) { 52 for (const StackFrame* it = beginFrame; it != endFrame; it++) {
41 StackFrame frame = *it; 53 StackFrame frame = *it;
42 54
43 auto node = nodes->find(frame); 55 auto node = nodes->find(frame);
44 if (node == nodes->end()) { 56 if (node == nodes->end()) {
45 // There is no tree node for this frame yet, create it. The parent node 57 // There is no tree node for this frame yet, create it. The parent node
46 // is the node associated with the previous frame. 58 // is the node associated with the previous frame.
(...skipping 13 matching lines...) Expand all
60 // A tree node for this frame exists. Look for the next one. 72 // A tree node for this frame exists. Look for the next one.
61 frame_index = node->second; 73 frame_index = node->second;
62 } 74 }
63 75
64 nodes = &frames_[frame_index].children; 76 nodes = &frames_[frame_index].children;
65 } 77 }
66 78
67 return frame_index; 79 return frame_index;
68 } 80 }
69 81
70 void StackFrameDeduplicator::AppendAsTraceFormat(std::string* out) const { 82 void StackFrameDeduplicator::SerializeIncrementally(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; 83 std::string stringify_buffer;
77 84
78 while (frame_node != it_end) { 85 for (; last_exported_index_ < frames_.size(); ++last_exported_index_) {
79 // The |stackFrames| format is a dictionary, not an array, so the 86 const auto& frame_node = frames_[last_exported_index_];
80 // keys are stringified indices. Write the index manually, then use 87 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 88
86 std::unique_ptr<TracedValue> frame_node_value(new TracedValue); 89 traced_value->SetInteger("id", last_exported_index_);
87 const StackFrame& frame = frame_node->frame; 90
91 int name_string_id = 0;
92 const StackFrame& frame = frame_node.frame;
88 switch (frame.type) { 93 switch (frame.type) {
89 case StackFrame::Type::TRACE_EVENT_NAME: 94 case StackFrame::Type::TRACE_EVENT_NAME:
90 frame_node_value->SetString( 95 name_string_id =
91 "name", static_cast<const char*>(frame.value)); 96 string_deduplicator_->Insert(static_cast<const char*>(frame.value));
92 break; 97 break;
93 case StackFrame::Type::THREAD_NAME: 98 case StackFrame::Type::THREAD_NAME:
94 SStringPrintf(&stringify_buffer, 99 SStringPrintf(&stringify_buffer,
95 "[Thread: %s]", 100 "[Thread: %s]",
96 static_cast<const char*>(frame.value)); 101 static_cast<const char*>(frame.value));
97 frame_node_value->SetString("name", stringify_buffer); 102 name_string_id = string_deduplicator_->Insert(stringify_buffer);
98 break; 103 break;
99 case StackFrame::Type::PROGRAM_COUNTER: 104 case StackFrame::Type::PROGRAM_COUNTER:
100 SStringPrintf(&stringify_buffer, 105 SStringPrintf(&stringify_buffer,
101 "pc:%" PRIxPTR, 106 "pc:%" PRIxPTR,
102 reinterpret_cast<uintptr_t>(frame.value)); 107 reinterpret_cast<uintptr_t>(frame.value));
103 frame_node_value->SetString("name", stringify_buffer); 108 name_string_id = string_deduplicator_->Insert(stringify_buffer);
104 break; 109 break;
105 } 110 }
106 if (frame_node->parent_frame_index >= 0) { 111 traced_value->SetInteger("name_sid", name_string_id);
107 SStringPrintf(&stringify_buffer, "%d", frame_node->parent_frame_index); 112
108 frame_node_value->SetString("parent", stringify_buffer); 113 if (frame_node.parent_frame_index != FrameNode::kInvalidFrameIndex) {
114 traced_value->SetInteger("parent", frame_node.parent_frame_index);
109 } 115 }
110 frame_node_value->AppendAsTraceFormat(out);
111 116
112 i++; 117 traced_value->EndDictionary();
113 frame_node++;
114
115 if (frame_node != it_end)
116 out->append(",");
117 } 118 }
118
119 out->append("}"); // End the |stackFrames| dictionary.
120 } 119 }
121 120
122 void StackFrameDeduplicator::EstimateTraceMemoryOverhead( 121 void StackFrameDeduplicator::EstimateTraceMemoryOverhead(
123 TraceEventMemoryOverhead* overhead) { 122 TraceEventMemoryOverhead* overhead) {
124 size_t memory_usage = 123 size_t memory_usage =
125 EstimateMemoryUsage(frames_) + EstimateMemoryUsage(roots_); 124 EstimateMemoryUsage(frames_) + EstimateMemoryUsage(roots_);
126 overhead->Add(TraceEventMemoryOverhead::kHeapProfilerStackFrameDeduplicator, 125 overhead->Add(TraceEventMemoryOverhead::kHeapProfilerStackFrameDeduplicator,
127 sizeof(StackFrameDeduplicator) + memory_usage); 126 sizeof(StackFrameDeduplicator) + memory_usage);
128 } 127 }
129 128
130 } // namespace trace_event 129 } // namespace trace_event
131 } // namespace base 130 } // namespace base
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698