1 /* 2 * Copyright (c) 2016, Google Inc. 3 * All rights reserved. 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7 8 #ifndef PERFTOOLS_PROFILES_PROTO_BUILDER_H_ 9 #define PERFTOOLS_PROFILES_PROTO_BUILDER_H_ 10 11 #include <stddef.h> 12 #include <algorithm> 13 #include <memory> 14 #include <string> 15 #include <tuple> 16 #include <unordered_map> 17 namespace perftools { 18 namespace profiles { 19 20 typedef int64_t int64; 21 typedef uint64_t uint64; 22 typedef std::string string; 23 24 } 25 } 26 #include "profile.pb.h" 27 28 namespace perftools { 29 namespace profiles { 30 31 // Provides mechanisms to facilitate the generation of profiles 32 // on a compressed protobuf: 33 // - Manages the creation of the string table. 34 // - Manages the creation of Functions for symbolized profiles. 35 // - Creates the association between locations and mappings. 36 // The caller should populate the profile with samples and their 37 // corresponding sample types, and any other optional fields. 38 class Builder { 39 public: 40 Builder(); 41 42 // Adds a string to the profile string table if not already present. 43 // Returns a unique integer id for this string. 44 int64 StringId(const char *str); 45 46 // Adds a function with these attributes to the profile function 47 // table, if not already present. Returns a unique integer id for 48 // this function. 49 uint64 FunctionId(const char *name, const char *system_name, 50 const char *file, int64 start_line); 51 52 // Adds mappings for the currently running binary to the profile. 53 void AddCurrentMappings(); 54 55 // Prepares the profile for encoding. Returns true on success. 56 // If the profile has no locations, inserts location using the 57 // location_ids from the samples as addresses. 58 // Associates the locations to mappings by comparing the location 59 // address into the mapping address range. 60 bool Finalize(); 61 62 // Serializes and compresses the profile into a string, replacing 63 // its contents. It calls Finalize() and returns whether the 64 // encoding was successful. 65 bool Emit(string *output); 66 67 // Serializes and compresses a profile into a string, replacing its 68 // contents. Returns false if there were errors on the serialization 69 // or compression, and the output string will not contain valid data. 70 static bool Marshal(const Profile &profile, string *output); 71 72 // Serializes and compresses a profile into a file represented by a 73 // file descriptor. Returns false if there were errors on the 74 // serialization or compression. 75 static bool MarshalToFile(const Profile &profile, int fd); 76 77 // Serializes and compresses a profile into a file, creating a new 78 // file or replacing its contents if it already exists. 79 static bool MarshalToFile(const Profile &profile, const char *filename); 80 81 // Determines if the profile is internally consistent (suitable for 82 // serialization). Returns true if no errors were encountered. 83 static bool CheckValid(const Profile &profile); 84 85 // Extract the profile from the builder object. No further calls 86 // should be made to the builder after this. Consume()87 std::unique_ptr<Profile> Consume() { return std::move(profile_); } 88 89 // Returns the underlying profile, to populate any fields not 90 // managed by the builder. The fields function and string_table 91 // should be populated through Builder::StringId and 92 // Builder::FunctionId. mutable_profile()93 Profile *mutable_profile() { return profile_.get(); } 94 95 private: 96 // Holds the information about a function to facilitate deduplication. 97 typedef std::tuple<int64, int64, int64, int64> Function; 98 class FunctionHasher { 99 public: operator()100 size_t operator()(const Function &f) const { 101 int64 hash = std::get<0>(f); 102 hash = hash + ((hash << 8) ^ std::get<1>(f)); 103 hash = hash + ((hash << 8) ^ std::get<2>(f)); 104 hash = hash + ((hash << 8) ^ std::get<3>(f)); 105 return static_cast<size_t>(hash); 106 } 107 }; 108 109 // Hashes to deduplicate strings and functions. 110 std::unordered_map<string, int64> strings_; 111 std::unordered_map<Function, int64, FunctionHasher> functions_; 112 113 // Actual profile being updated. 114 std::unique_ptr<Profile> profile_; 115 }; 116 117 } // namespace profiles 118 } // namespace perftools 119 120 #endif // PERFTOOLS_PROFILES_PROTO_BUILDER_H_ 121