/*
|
* 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_
|