Index: base/trace_event/memory_profiler_heap_dumper.cc |
diff --git a/base/trace_event/memory_profiler_heap_dumper.cc b/base/trace_event/memory_profiler_heap_dumper.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..03647e069edf306ace2fee972952f64d85cbe6e4 |
--- /dev/null |
+++ b/base/trace_event/memory_profiler_heap_dumper.cc |
@@ -0,0 +1,83 @@ |
+// Copyright 2015 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#include "base/trace_event/memory_profiler_heap_dumper.h" |
+ |
+#include <numeric> |
+ |
+#include "base/format_macros.h" |
+#include "base/strings/stringprintf.h" |
+#include "base/trace_event/memory_profiler_allocation_register.h" |
+ |
+namespace base { |
+namespace trace_event { |
+ |
+namespace { |
+ |
+template <typename T> |
+bool PairSizeGt(const std::pair<T, size_t>& lhs, |
+ const std::pair<T, size_t>& rhs) { |
+ return lhs.second > rhs.second; |
+} |
+ |
+template <typename T> |
+size_t PairSizeAdd(size_t acc, const std::pair<T, size_t>& rhs) { |
+ return acc + rhs.second; |
+} |
+ |
+} // namespace |
+ |
+HeapDumper::HeapDumper(scoped_refptr<TracedValue> traced_value, |
+ StackFrameDeduplicator* sf_deduplicator) |
+ : traced_value_(traced_value), sf_deduplicator_(sf_deduplicator) {} |
+HeapDumper::~HeapDumper() {} |
+ |
+void HeapDumper::Fill(const AllocationRegister& allocation_register) { |
+ for (auto alloc : allocation_register) |
+ acc_by_backtrace_[alloc.context.backtrace] += alloc.size; |
+} |
+ |
+void HeapDumper::WriteHeapDump() { |
+ // Sort the backtraces by size in descending order. |
+ std::vector<std::pair<Backtrace, size_t>> sorted_by_backtrace; |
+ |
+ std::copy(acc_by_backtrace_.begin(), acc_by_backtrace_.end(), |
+ std::back_inserter(sorted_by_backtrace)); |
+ std::sort(sorted_by_backtrace.begin(), sorted_by_backtrace.end(), |
+ PairSizeGt<Backtrace>); |
+ |
+ traced_value_->BeginArray("heap"); |
+ |
+ // The global size, no column specified. |
+ { |
+ size_t total_size = |
+ std::accumulate(sorted_by_backtrace.begin(), sorted_by_backtrace.end(), |
+ size_t(0), PairSizeAdd<Backtrace>); |
+ traced_value_->BeginDictionary(); |
+ WriteSize(total_size); |
+ traced_value_->EndDictionary(); |
+ } |
+ |
+ // Size per backtrace. |
+ for (auto bt_sz = sorted_by_backtrace.begin(); |
+ bt_sz != sorted_by_backtrace.end(); bt_sz++) { |
+ traced_value_->BeginDictionary(); |
+ // Insert a forward reference to the backtrace that will be written to the |
+ // |stackFrames| dictionary later on. |
+ traced_value_->SetInteger("bt", sf_deduplicator_->Insert(bt_sz->first)); |
+ WriteSize(bt_sz->second); |
+ traced_value_->EndDictionary(); |
+ } |
+ |
+ traced_value_->EndArray(); // heap |
+} |
+ |
+void HeapDumper::WriteSize(size_t size) { |
+ // Format size as hexadecimal string into |buffer_|. |
+ SStringPrintf(&buffer_, "%" PRIx64, static_cast<uint64_t>(size)); |
+ traced_value_->SetString("size", buffer_); |
+} |
+ |
+} // namespace trace_event |
+} // namespace base |