blob: 30d3357e6cace89cacb81ba419013c9dcc8ceb01 [file] [log] [blame]
/*
* Copyright (c) 2016, Google Inc.
* All rights reserved.
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#ifndef PERFTOOLS_PROFILES_PROTO_BUILDER_H_
#define PERFTOOLS_PROFILES_PROTO_BUILDER_H_
#include <stddef.h>
#include <algorithm>
#include <memory>
#include <string>
#include <tuple>
#include <unordered_map>
namespace perftools {
namespace profiles {
typedef int64_t int64;
typedef uint64_t uint64;
typedef std::string string;
}
}
#include "profile.pb.h"
namespace perftools {
namespace profiles {
// Provides mechanisms to facilitate the generation of profiles
// on a compressed protobuf:
// - Manages the creation of the string table.
// - Manages the creation of Functions for symbolized profiles.
// - Creates the association between locations and mappings.
// The caller should populate the profile with samples and their
// corresponding sample types, and any other optional fields.
class Builder {
public:
Builder();
// Adds a string to the profile string table if not already present.
// Returns a unique integer id for this string.
int64 StringId(const char *str);
// Adds a function with these attributes to the profile function
// table, if not already present. Returns a unique integer id for
// this function.
uint64 FunctionId(const char *name, const char *system_name,
const char *file, int64 start_line);
// Adds mappings for the currently running binary to the profile.
void AddCurrentMappings();
// Prepares the profile for encoding. Returns true on success.
// If the profile has no locations, inserts location using the
// location_ids from the samples as addresses.
// Associates the locations to mappings by comparing the location
// address into the mapping address range.
bool Finalize();
// Serializes and compresses the profile into a string, replacing
// its contents. It calls Finalize() and returns whether the
// encoding was successful.
bool Emit(string *output);
// Serializes and compresses a profile into a string, replacing its
// contents. Returns false if there were errors on the serialization
// or compression, and the output string will not contain valid data.
static bool Marshal(const Profile &profile, string *output);
// Serializes and compresses a profile into a file represented by a
// file descriptor. Returns false if there were errors on the
// serialization or compression.
static bool MarshalToFile(const Profile &profile, int fd);
// Serializes and compresses a profile into a file, creating a new
// file or replacing its contents if it already exists.
static bool MarshalToFile(const Profile &profile, const char *filename);
// Determines if the profile is internally consistent (suitable for
// serialization). Returns true if no errors were encountered.
static bool CheckValid(const Profile &profile);
// Extract the profile from the builder object. No further calls
// should be made to the builder after this.
std::unique_ptr<Profile> Consume() { return std::move(profile_); }
// Returns the underlying profile, to populate any fields not
// managed by the builder. The fields function and string_table
// should be populated through Builder::StringId and
// Builder::FunctionId.
Profile *mutable_profile() { return profile_.get(); }
private:
// Holds the information about a function to facilitate deduplication.
typedef std::tuple<int64, int64, int64, int64> Function;
class FunctionHasher {
public:
size_t operator()(const Function &f) const {
int64 hash = std::get<0>(f);
hash = hash + ((hash << 8) ^ std::get<1>(f));
hash = hash + ((hash << 8) ^ std::get<2>(f));
hash = hash + ((hash << 8) ^ std::get<3>(f));
return static_cast<size_t>(hash);
}
};
// Hashes to deduplicate strings and functions.
std::unordered_map<string, int64> strings_;
std::unordered_map<Function, int64, FunctionHasher> functions_;
// Actual profile being updated.
std::unique_ptr<Profile> profile_;
};
} // namespace profiles
} // namespace perftools
#endif // PERFTOOLS_PROFILES_PROTO_BUILDER_H_