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

Unified Diff: components/sync/protocol/proto_memory_estimations.cc

Issue 2452713003: [Sync] Implement MemoryDumpProvider. (Closed)
Patch Set: Fix presumit; fix Windows; git cl format Created 4 years, 1 month 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 side-by-side diff with in-line comments
Download patch
Index: components/sync/protocol/proto_memory_estimations.cc
diff --git a/components/sync/protocol/proto_memory_estimations.cc b/components/sync/protocol/proto_memory_estimations.cc
new file mode 100644
index 0000000000000000000000000000000000000000..f759f986d8f6482ca5100632aa6674e1ec8c8caa
--- /dev/null
+++ b/components/sync/protocol/proto_memory_estimations.cc
@@ -0,0 +1,126 @@
+// Copyright (c) 2016 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.
+
+// Keep this file in sync with the .proto files in this directory.
+
+#include "components/sync/protocol/proto_memory_estimations.h"
+
+#include "base/trace_event/memory_usage_estimator.h"
+#include "components/sync/protocol/proto_visitors.h"
+
+namespace {
+
+// This class is a VisitProtoFields()-compatible visitor that estimates
+// proto's memory usage:
+//
+// MemoryUsageVisitor visitor;
+// VisitProtoFields(visitor, proto);
+// size_t memory_usage = visitor.memory_usage();
+//
+class MemoryUsageVisitor {
+ public:
+ MemoryUsageVisitor() : memory_usage_(0) {}
+
+ size_t memory_usage() const { return memory_usage_; }
+
+ template <class P>
+ void VisitBytes(const P& parent_proto,
+ const char* field_name,
+ const std::string& field) {
+ // Delegate to Visit(..., const std::string&) below.
+ Visit(parent_proto, field_name, field);
+ }
+
+ template <class P, class E>
+ void VisitEnum(const P&, const char* field_name, E field) {}
+
+ // Types derived from MessageLite (i.e. protos)
+ template <class P, class F>
+ typename std::enable_if<
+ std::is_base_of<google::protobuf::MessageLite, F>::value>::type
+ Visit(const P&, const char* field_name, const F& field) {
+ using base::trace_event::EstimateMemoryUsage;
+ // All object fields are dynamically allocated.
+ memory_usage_ += sizeof(F) + EstimateMemoryUsage(field);
+ }
+
+ // Integral types
+ template <class P, class F>
+ typename std::enable_if<std::is_integral<F>::value>::type
+ Visit(const P&, const char* field_name, const F& field) {
+ // Integral fields (integers, floats & bool) don't allocate.
+ }
+
+ // std::string
+ template <class P>
+ void Visit(const P&, const char* field_name, const std::string& field) {
+ using base::trace_event::EstimateMemoryUsage;
+ // All strings are of type ArenaStringPtr, which essentially
+ // is std::string*.
+ memory_usage_ += sizeof(std::string) + EstimateMemoryUsage(field);
+ }
+
+ // RepeatedPtrField
+ template <class P, class F>
+ void Visit(const P&,
+ const char* field_name,
+ const google::protobuf::RepeatedPtrField<F>& fields) {
+ using base::trace_event::EstimateMemoryUsage;
+ // Can't use RepeatedPtrField::SpaceUsedExcludingSelf() because it will
+ // end up calling undefined TypeHandler::SpaceUsed() method.
+ memory_usage_ += fields.Capacity() ? sizeof(void*) : 0; // header
+ memory_usage_ += fields.Capacity() * sizeof(void*);
+ for (const auto& field : fields) {
+ memory_usage_ += sizeof(F) + EstimateMemoryUsage(field);
+ }
+ }
+
+ // RepeatedField<integral type>
+ template <class P, class F>
+ typename std::enable_if<std::is_integral<F>::value>::type Visit(
+ const P&,
+ const char* field_name,
+ const google::protobuf::RepeatedField<F>& fields) {
+ memory_usage_ += fields.SpaceUsedExcludingSelf();
+ // Integral fields (integers, floats & bool) don't allocate, so no
+ // point in iterating over |fields|.
+ }
+
+ // RepeatedField<std::string>
+ template <class P>
+ void Visit(const P&,
+ const char* field_name,
+ const google::protobuf::RepeatedField<std::string>& fields) {
+ using base::trace_event::EstimateMemoryUsage;
+ memory_usage_ += fields.SpaceUsedExcludingSelf();
+ for (const auto& field : fields) {
+ memory_usage_ += EstimateMemoryUsage(field);
+ }
+ }
+
+ private:
+ size_t memory_usage_;
+};
+
+} // namespace
+
+namespace sync_pb {
+
+template <class P>
+size_t EstimateMemoryUsage(const P& proto) {
+ MemoryUsageVisitor visitor;
+ syncer::VisitProtoFields(visitor, proto);
+ return visitor.memory_usage();
+}
+
+// Explicit instantiations
+
+#define INSTANTIATE(Proto) \
+ template size_t EstimateMemoryUsage<Proto>(const Proto&);
+
+INSTANTIATE(EntitySpecifics)
+INSTANTIATE(AttachmentMetadata)
+INSTANTIATE(DataTypeContext)
+
+} // namespace sync_pb
« no previous file with comments | « components/sync/protocol/proto_memory_estimations.h ('k') | components/sync/protocol/proto_value_conversions.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698