Home | History | Annotate | Download | only in src
      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.
     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.
     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:
    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