Index: base/trace_event/heap_profiler_stack_frame_deduplicator.cc |
diff --git a/base/trace_event/heap_profiler_stack_frame_deduplicator.cc b/base/trace_event/heap_profiler_stack_frame_deduplicator.cc |
index fc5da0d1dde9ed15498e1d03574d737c5f004460..a230c62bf4e71546890ea8a2bf9bbda84ef79ca7 100644 |
--- a/base/trace_event/heap_profiler_stack_frame_deduplicator.cc |
+++ b/base/trace_event/heap_profiler_stack_frame_deduplicator.cc |
@@ -11,6 +11,7 @@ |
#include <utility> |
#include "base/strings/stringprintf.h" |
+#include "base/trace_event/heap_profiler_string_deduplicator.h" |
#include "base/trace_event/memory_usage_estimator.h" |
#include "base/trace_event/trace_event_argument.h" |
#include "base/trace_event/trace_event_memory_overhead.h" |
@@ -28,11 +29,21 @@ size_t StackFrameDeduplicator::FrameNode::EstimateMemoryUsage() const { |
return base::trace_event::EstimateMemoryUsage(children); |
} |
-StackFrameDeduplicator::StackFrameDeduplicator() {} |
+StackFrameDeduplicator::StackFrameDeduplicator( |
+ StringDeduplicator* string_deduplicator) |
+ : string_deduplicator_(string_deduplicator), last_exported_index_(0) { |
+ // Add implicit entry for id 0 (empty backtraces). |
+ frames_.push_back({StackFrame::FromTraceEventName(nullptr), -1}); |
+} |
StackFrameDeduplicator::~StackFrameDeduplicator() {} |
int StackFrameDeduplicator::Insert(const StackFrame* beginFrame, |
const StackFrame* endFrame) { |
+ if (beginFrame == endFrame) { |
+ // Empty backtraces are mapped to id 0. |
+ return 0; |
+ } |
+ |
int frame_index = -1; |
std::map<StackFrame, int>* nodes = &roots_; |
@@ -67,56 +78,43 @@ int StackFrameDeduplicator::Insert(const StackFrame* beginFrame, |
return frame_index; |
} |
-void StackFrameDeduplicator::AppendAsTraceFormat(std::string* out) const { |
- out->append("{"); // Begin the |stackFrames| dictionary. |
- |
- int i = 0; |
- auto frame_node = begin(); |
- auto it_end = end(); |
+void StackFrameDeduplicator::ExportIncrementally(TracedValue* traced_value) { |
std::string stringify_buffer; |
- while (frame_node != it_end) { |
- // The |stackFrames| format is a dictionary, not an array, so the |
- // keys are stringified indices. Write the index manually, then use |
- // |TracedValue| to format the object. This is to avoid building the |
- // entire dictionary as a |TracedValue| in memory. |
- SStringPrintf(&stringify_buffer, "\"%d\":", i); |
- out->append(stringify_buffer); |
+ for (; last_exported_index_ < frames_.size(); ++last_exported_index_) { |
+ const auto& frame_node = frames_[last_exported_index_]; |
+ traced_value->BeginDictionary(); |
- std::unique_ptr<TracedValue> frame_node_value(new TracedValue); |
- const StackFrame& frame = frame_node->frame; |
+ traced_value->SetInteger("id", last_exported_index_); |
+ |
+ int name_string_id = 0; |
+ const StackFrame& frame = frame_node.frame; |
switch (frame.type) { |
case StackFrame::Type::TRACE_EVENT_NAME: |
- frame_node_value->SetString( |
- "name", static_cast<const char*>(frame.value)); |
+ name_string_id = |
+ string_deduplicator_->Insert(static_cast<const char*>(frame.value)); |
break; |
case StackFrame::Type::THREAD_NAME: |
SStringPrintf(&stringify_buffer, |
"[Thread: %s]", |
static_cast<const char*>(frame.value)); |
- frame_node_value->SetString("name", stringify_buffer); |
+ name_string_id = string_deduplicator_->Insert(stringify_buffer); |
break; |
case StackFrame::Type::PROGRAM_COUNTER: |
SStringPrintf(&stringify_buffer, |
"pc:%" PRIxPTR, |
reinterpret_cast<uintptr_t>(frame.value)); |
- frame_node_value->SetString("name", stringify_buffer); |
+ name_string_id = string_deduplicator_->Insert(stringify_buffer); |
break; |
} |
- if (frame_node->parent_frame_index >= 0) { |
- SStringPrintf(&stringify_buffer, "%d", frame_node->parent_frame_index); |
- frame_node_value->SetString("parent", stringify_buffer); |
- } |
- frame_node_value->AppendAsTraceFormat(out); |
+ traced_value->SetInteger("name_sid", name_string_id); |
- i++; |
- frame_node++; |
+ if (frame_node.parent_frame_index >= 0) { |
+ traced_value->SetInteger("parent", frame_node.parent_frame_index); |
+ } |
- if (frame_node != it_end) |
- out->append(","); |
+ traced_value->EndDictionary(); |
} |
- |
- out->append("}"); // End the |stackFrames| dictionary. |
} |
void StackFrameDeduplicator::EstimateTraceMemoryOverhead( |