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