| 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(
|
|
|