• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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