blob: 035d18b719d7c3ddebef973b8e64d85ffd84d59b [file] [log] [blame]
Raul Silvera0c3c35e2016-09-21 13:14:55 -07001/*
2 * Copyright (c) 2016, Google Inc.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of Google Inc. nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL Google Inc. BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28#ifndef PERFTOOLS_PROFILES_BUILDER_H_
29#define PERFTOOLS_PROFILES_BUILDER_H_
30
31#include <stddef.h>
32#include <algorithm>
33#include <memory>
34#include <string>
35#include <tuple>
36#include <unordered_map>
37
38#include "int_compat.h"
39#include "profile.pb.h"
40#include "string_compat.h"
41
42namespace perftools {
43namespace profiles {
44// Provides mechanisms to facilitate the generation of profiles
45// on a compressed protobuf:
46// - Manages the creation of the string table.
47// - Manages the creation of Functions for symbolized profiles.
48// - Creates the association between locations and mappings.
49// The caller should populate the profile with samples and their
50// corresponding sample types, and any other optional fields.
51class Builder {
52 public:
53 Builder();
54
55 // Adds a string to the profile string table if not already present.
56 // Returns a unique integer id for this string.
57 int64 StringId(const char *str);
58
59 // Adds a function with these attributes to the profile function
60 // table, if not already present. Returns a unique integer id for
61 // this function.
62 uint64 FunctionId(const char *name, const char *system_name, const char *file,
63 int64 start_line);
64
65 // Adds mappings for the currently running binary to the profile.
66 void AddCurrentMappings();
67
68 // Prepares the profile for encoding. Returns true on success.
69 // If the profile has no locations, inserts location using the
70 // location_ids from the samples as addresses.
71 // Associates the locations to mappings by comparing the location
72 // address into the mapping address range.
73 bool Finalize();
74
75 // Serializes and compresses the profile into a string, replacing
76 // its contents. It calls Finalize() and returns whether the
77 // encoding was successful.
78 bool Emit(string *output);
79
80 // Serializes and compresses a profile into a string, replacing its
81 // contents. Returns false if there were errors on the serialization
82 // or compression, and the output string will not contain valid data.
83 static bool Marshal(const Profile &profile, string *output);
84
85 // Serializes and compresses a profile into a file represented by a
86 // file descriptor. Returns false if there were errors on the
87 // serialization or compression.
88 static bool MarshalToFile(const Profile &profile, int fd);
89
90 // Serializes and compresses a profile into a file, creating a new
91 // file or replacing its contents if it already exists.
92 static bool MarshalToFile(const Profile &profile, const char *filename);
93
94 // Determines if the profile is internally consistent (suitable for
95 // serialization). Returns true if no errors were encountered.
96 static bool CheckValid(const Profile &profile);
97
98 // Extract the profile from the builder object. No further calls
99 // should be made to the builder after this.
100 std::unique_ptr<Profile> Consume() { return std::move(profile_); }
101
102 // Returns the underlying profile, to populate any fields not
103 // managed by the builder. The fields function and string_table
104 // should be populated through Builder::StringId and
105 // Builder::FunctionId.
106 Profile *mutable_profile() { return profile_.get(); }
107
108 private:
109 // Holds the information about a function to facilitate deduplication.
110 typedef std::tuple<int64, int64, int64, int64> Function;
111 class FunctionHasher {
112 public:
113 size_t operator()(const Function &f) const {
114 int64 hash = std::get<0>(f);
115 hash = hash + ((hash << 8) ^ std::get<1>(f));
116 hash = hash + ((hash << 8) ^ std::get<2>(f));
117 hash = hash + ((hash << 8) ^ std::get<3>(f));
118 return static_cast<size_t>(hash);
119 }
120 };
121
122 // Hashes to deduplicate strings and functions.
123 std::unordered_map<string, int64> strings_;
124 std::unordered_map<Function, int64, FunctionHasher> functions_;
125
126 // Actual profile being updated.
127 std::unique_ptr<Profile> profile_;
128};
129
130} // namespace profiles
131} // namespace perftools
132
133#endif // PERFTOOLS_PROFILES_BUILDER_H_