1 // Copyright 2019 The Chromium Authors 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef COMPONENTS_METRICS_CALL_STACKS_CALL_STACK_PROFILE_METADATA_H_ 6 #define COMPONENTS_METRICS_CALL_STACKS_CALL_STACK_PROFILE_METADATA_H_ 7 8 #include <map> 9 #include <optional> 10 #include <unordered_map> 11 #include <utility> 12 13 #include "base/profiler/metadata_recorder.h" 14 #include "third_party/metrics_proto/sampled_profile.pb.h" 15 16 namespace metrics { 17 18 // Helper class for maintaining metadata state across samples and generating 19 // metadata proto messages. 20 class CallStackProfileMetadata { 21 public: 22 CallStackProfileMetadata(); 23 ~CallStackProfileMetadata(); 24 25 CallStackProfileMetadata(const CallStackProfileMetadata& other) = delete; 26 CallStackProfileMetadata& operator=(const CallStackProfileMetadata& other) = 27 delete; 28 29 // Records the metadata for the next sample. 30 void RecordMetadata( 31 const base::MetadataRecorder::MetadataProvider& metadata_provider); 32 33 // Creates MetadataItems for the currently active metadata, adding new name 34 // hashes to |metadata_name_hashes| if necessary. The same 35 // |metadata_name_hashes| must be passed to each invocation, and must not be 36 // modified outside this function. 37 google::protobuf::RepeatedPtrField<CallStackProfile::MetadataItem> 38 CreateSampleMetadata( 39 google::protobuf::RepeatedField<uint64_t>* metadata_name_hashes); 40 41 // Applies the |item| to the samples between |begin| and |end| in 42 // |stack_samples|. Overwrites any existing metadata item with the same key 43 // and value that are already applied to the samples. 44 void ApplyMetadata( 45 const base::MetadataRecorder::Item& item, 46 google::protobuf::RepeatedPtrField< 47 CallStackProfile::StackSample>::iterator begin, 48 google::protobuf::RepeatedPtrField< 49 CallStackProfile::StackSample>::iterator end, 50 google::protobuf::RepeatedPtrField<CallStackProfile::StackSample>* 51 stack_samples, 52 google::protobuf::RepeatedField<uint64_t>* metadata_name_hashes); 53 54 // Set the value provided in |src_item| to |dest_item|, where |src_item| is 55 // in chromium format, and |dest_item| is in proto format. Intended for 56 // setting profile-global metadata items. Setting per-sample metadata should 57 // be done via the functions above. 58 void SetMetadata( 59 const base::MetadataRecorder::Item& src_item, 60 CallStackProfile::MetadataItem* dest_item, 61 google::protobuf::RepeatedField<uint64_t>* metadata_name_hashes); 62 63 private: 64 // Comparison function for the metadata map. 65 struct MetadataKey; 66 struct MetadataKeyCompare { 67 bool operator()(const MetadataKey& a, const MetadataKey& b) const; 68 }; 69 70 // Definitions for a map-based representation of sample metadata. 71 struct MetadataKey { 72 MetadataKey(uint64_t name_hash, std::optional<int64_t> key); 73 74 MetadataKey(const MetadataKey& other); 75 MetadataKey& operator=(const MetadataKey& other); 76 77 // The name_hash and optional user-specified key uniquely identifies a 78 // metadata value. See base::MetadataRecorder for details. 79 uint64_t name_hash; 80 std::optional<int64_t> key; 81 }; 82 using MetadataMap = std::map<MetadataKey, int64_t, MetadataKeyCompare>; 83 84 // Creates the metadata map from the array of items. 85 MetadataMap CreateMetadataMap(base::MetadataRecorder::ItemArray items, 86 size_t item_count); 87 88 // Returns all metadata items with new values in the current sample. 89 MetadataMap GetNewOrModifiedMetadataItems(const MetadataMap& current_items, 90 const MetadataMap& previous_items); 91 92 // Returns all metadata items deleted since the previous sample. 93 MetadataMap GetDeletedMetadataItems(const MetadataMap& current_items, 94 const MetadataMap& previous_items); 95 96 // Appends the |name_hash| to |name_hashes| if it's not already 97 // present. Returns its index in |name_hashes|. 98 size_t MaybeAppendNameHash( 99 uint64_t name_hash, 100 google::protobuf::RepeatedField<uint64_t>* metadata_name_hashes); 101 102 // The data provided for the next sample. 103 base::MetadataRecorder::ItemArray metadata_items_; 104 size_t metadata_item_count_ = 0; 105 106 // The data provided for the previous sample. 107 MetadataMap previous_items_; 108 109 // Maps metadata hash to index in |metadata_name_hash| array. 110 std::unordered_map<uint64_t, int> metadata_hashes_cache_; 111 }; 112 113 } // namespace metrics 114 115 #endif // COMPONENTS_METRICS_CALL_STACKS_CALL_STACK_PROFILE_METADATA_H_ 116