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

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

Issue 2452713003: [Sync] Implement MemoryDumpProvider. (Closed)
Patch Set: Created 4 years, 2 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 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..39e9b7f962f19de7e06e43236754542393deb4a3
--- /dev/null
+++ b/components/sync/protocol/proto_memory_estimations.cc
@@ -0,0 +1,191 @@
+// 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/estimate_memory_usage.h"
+// This include is here so that I don't forget to remove test-only
+// instantiations at the end.
+#include "components/sync/protocol/proto_unittest_serialized_data.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)
+
+// TODO(dskiba): needed only for testing, remove
+
+INSTANTIATE(EncryptedData)
+INSTANTIATE(AppListSpecifics)
+INSTANTIATE(AppNotificationSettings)
+INSTANTIATE(LinkedAppIconInfo)
+INSTANTIATE(ArcPackageSpecifics)
+INSTANTIATE(SessionHeader)
+INSTANTIATE(SessionTab)
+INSTANTIATE(SessionWindow)
+INSTANTIATE(TabNavigation)
+INSTANTIATE(NavigationRedirect)
+INSTANTIATE(PasswordSpecificsData)
+INSTANTIATE(GlobalIdDirective)
+INSTANTIATE(TimeRangeDirective)
+INSTANTIATE(SessionSpecifics)
+INSTANTIATE(PrinterPPDReference)
+INSTANTIATE(AppNotification)
+INSTANTIATE(AppSettingSpecifics)
+INSTANTIATE(AppSpecifics)
+INSTANTIATE(ArticleSpecifics)
+INSTANTIATE(AutofillSpecifics)
+INSTANTIATE(AutofillProfileSpecifics)
+INSTANTIATE(WalletMetadataSpecifics)
+INSTANTIATE(AutofillWalletSpecifics)
+INSTANTIATE(BookmarkSpecifics)
+INSTANTIATE(DeviceInfoSpecifics)
+INSTANTIATE(DictionarySpecifics)
+INSTANTIATE(ExperimentsSpecifics)
+INSTANTIATE(PriorityPreferenceSpecifics)
+INSTANTIATE(ExtensionSettingSpecifics)
+INSTANTIATE(ExtensionSpecifics)
+INSTANTIATE(FaviconImageSpecifics)
+INSTANTIATE(FaviconTrackingSpecifics)
+INSTANTIATE(HistoryDeleteDirectiveSpecifics)
+INSTANTIATE(ManagedUserSettingSpecifics)
+INSTANTIATE(ManagedUserSpecifics)
+INSTANTIATE(ManagedUserSharedSettingSpecifics)
+INSTANTIATE(ManagedUserWhitelistSpecifics)
+INSTANTIATE(NigoriSpecifics)
+INSTANTIATE(PasswordSpecifics)
+INSTANTIATE(PreferenceSpecifics)
+INSTANTIATE(PrinterSpecifics)
+INSTANTIATE(ReadingListSpecifics)
+INSTANTIATE(SyncedNotificationAppInfoSpecifics)
+INSTANTIATE(SyncedNotificationSpecifics)
+INSTANTIATE(SearchEngineSpecifics)
+INSTANTIATE(ThemeSpecifics)
+INSTANTIATE(TypedUrlSpecifics)
+INSTANTIATE(WalletMaskedCreditCard)
+INSTANTIATE(WalletPostalAddress)
+INSTANTIATE(WifiCredentialSpecifics)
+INSTANTIATE(SyncEntity)
+INSTANTIATE(ClientToServerMessage)
+INSTANTIATE(ClientToServerResponse)
+INSTANTIATE(DatatypeAssociationStats)
+INSTANTIATE(DebugEventInfo)
+INSTANTIATE(DebugInfo)
+INSTANTIATE(SyncCycleCompletedEventInfo)
+INSTANTIATE(ClientConfigParams)
+INSTANTIATE(AttachmentIdProto)
+INSTANTIATE(EntityMetadata)
+
+#undef INSTANTIATE
+
+} // namespace sync_pb

Powered by Google App Engine
This is Rietveld 408576698