123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672 |
- // Copyright 2018 The Chromium Authors. All rights reserved.
- // Use of this source code is governed by a BSD-style license that can be
- // found in the LICENSE file.
- #ifndef BASE_TRACE_EVENT_TRACE_ARGUMENTS_H_
- #define BASE_TRACE_EVENT_TRACE_ARGUMENTS_H_
- #include <stdlib.h>
- #include <string.h>
- #include <algorithm>
- #include <memory>
- #include <string>
- #include "base/base_export.h"
- #include "base/macros.h"
- #include "base/trace_event/common/trace_event_common.h"
- // Trace macro can have one or two optional arguments, each one of them
- // identified by a name (a C string literal) and a value, which can be an
- // integer, enum, floating point, boolean, string pointer or reference, or
- // std::unique_ptr<ConvertableToTraceFormat> compatible values. Additionally,
- // custom data types need to be supported, like time values or WTF::CString.
- //
- // TraceArguments is a helper class used to store 0 to 2 named arguments
- // corresponding to an individual trace macro call. As efficiently as possible,
- // and with the minimal amount of generated machine code (since this affects
- // any TRACE macro call). Each argument has:
- //
- // - A name (C string literal, e.g "dumps")
- // - An 8-bit type value, corresponding to the TRACE_VALUE_TYPE_XXX macros.
- // - A value, stored in a TraceValue union
- //
- // IMPORTANT: For a TRACE_VALUE_TYPE_CONVERTABLE types, the TraceArguments
- // instance owns the pointed ConvertableToTraceFormat object, i.e. it will
- // delete it automatically on destruction.
- //
- // TraceArguments instances should be built using one of specialized
- // constructors declared below. One cannot modify an instance once it has
- // been built, except for move operations, Reset() and destruction. Examples:
- //
- // TraceArguments args; // No arguments.
- // // args.size() == 0
- //
- // TraceArguments("foo", 100);
- // // args.size() == 1
- // // args.types()[0] == TRACE_VALUE_TYPE_INT
- // // args.names()[0] == "foo"
- // // args.values()[0].as_int == 100
- //
- // TraceArguments("bar", 1ULL);
- // // args.size() == 1
- // // args.types()[0] == TRACE_VALUE_TYPE_UINT
- // // args.names()[0] == "bar"
- // // args.values()[0].as_uint == 100
- //
- // TraceArguments("foo", "Hello", "bar", "World");
- // // args.size() == 2
- // // args.types()[0] == TRACE_VALUE_TYPE_STRING
- // // args.types()[1] == TRACE_VALUE_TYPE_STRING
- // // args.names()[0] == "foo"
- // // args.names()[1] == "bar"
- // // args.values()[0].as_string == "Hello"
- // // args.values()[1].as_string == "World"
- //
- // std::string some_string = ...;
- // TraceArguments("str1", some_string);
- // // args.size() == 1
- // // args.types()[0] == TRACE_VALUE_TYPE_COPY_STRING
- // // args.names()[0] == "str1"
- // // args.values()[0].as_string == some_string.c_str()
- //
- // Note that TRACE_VALUE_TYPE_COPY_STRING corresponds to string pointers
- // that point to temporary values that may disappear soon. The
- // TraceArguments::CopyStringTo() method can be used to copy their content
- // into a StringStorage memory block, and update the |as_string| value pointers
- // to it to avoid keeping any dangling pointers. This is used by TraceEvent
- // to keep copies of such strings in the log after their initialization values
- // have disappeared.
- //
- // The TraceStringWithCopy helper class can be used to initialize a value
- // from a regular string pointer with TRACE_VALUE_TYPE_COPY_STRING too, as in:
- //
- // const char str[] = "....";
- // TraceArguments("foo", str, "bar", TraceStringWithCopy(str));
- // // args.size() == 2
- // // args.types()[0] == TRACE_VALUE_TYPE_STRING
- // // args.types()[1] == TRACE_VALUE_TYPE_COPY_STRING
- // // args.names()[0] == "foo"
- // // args.names()[1] == "bar"
- // // args.values()[0].as_string == str
- // // args.values()[1].as_string == str
- //
- // StringStorage storage;
- // args.CopyStringTo(&storage, false, nullptr, nullptr);
- // // args.size() == 2
- // // args.types()[0] == TRACE_VALUE_TYPE_STRING
- // // args.types()[1] == TRACE_VALUE_TYPE_COPY_STRING
- // // args.names()[0] == "foo"
- // // args.names()[1] == "bar"
- // // args.values()[0].as_string == str
- // // args.values()[1].as_string == Address inside |storage|.
- //
- // Initialization from a std::unique_ptr<ConvertableToTraceFormat>
- // is supported but will move ownership of the pointer objects to the
- // TraceArguments instance:
- //
- // class MyConvertableType :
- // public base::trace_event::AsConvertableToTraceFormat {
- // ...
- // };
- //
- // {
- // TraceArguments args("foo" , std::make_unique<MyConvertableType>(...));
- // // args.size() == 1
- // // args.values()[0].as_convertable == address of MyConvertable object.
- // } // Calls |args| destructor, which will delete the object too.
- //
- // Finally, it is possible to support initialization from custom values by
- // specializing the TraceValue::Helper<> template struct as described below.
- //
- // This is how values of custom types like WTF::CString can be passed directly
- // to trace macros.
- namespace base {
- class Time;
- class TimeTicks;
- class ThreadTicks;
- namespace trace_event {
- class TraceEventMemoryOverhead;
- // For any argument of type TRACE_VALUE_TYPE_CONVERTABLE the provided
- // class must implement this interface. Note that unlike other values,
- // these objects will be owned by the TraceArguments instance that points
- // to them.
- class BASE_EXPORT ConvertableToTraceFormat {
- public:
- ConvertableToTraceFormat() = default;
- virtual ~ConvertableToTraceFormat() = default;
- // Append the class info to the provided |out| string. The appended
- // data must be a valid JSON object. Strings must be properly quoted, and
- // escaped. There is no processing applied to the content after it is
- // appended.
- virtual void AppendAsTraceFormat(std::string* out) const = 0;
- // Append the class info directly into the Perfetto-defined proto
- // format; this is attempted first and if this returns true,
- // AppendAsTraceFormat is not called. The ProtoAppender interface
- // acts as a bridge to avoid proto/Perfetto dependencies in base.
- class BASE_EXPORT ProtoAppender {
- public:
- virtual ~ProtoAppender() = default;
- virtual void AddBuffer(uint8_t* begin, uint8_t* end) = 0;
- // Copy all of the previous buffers registered with AddBuffer
- // into the proto, with the given |field_id|.
- virtual size_t Finalize(uint32_t field_id) = 0;
- };
- virtual bool AppendToProto(ProtoAppender* appender);
- virtual void EstimateTraceMemoryOverhead(TraceEventMemoryOverhead* overhead);
- private:
- DISALLOW_COPY_AND_ASSIGN(ConvertableToTraceFormat);
- };
- const int kTraceMaxNumArgs = 2;
- // A union used to hold the values of individual trace arguments.
- //
- // This is a POD union for performance reason. Initialization from an
- // explicit C++ trace argument should be performed with the Init()
- // templated method described below.
- //
- // Initialization from custom types is possible by implementing a custom
- // TraceValue::Helper<> instantiation as described below.
- //
- // IMPORTANT: Pointer storage inside a TraceUnion follows specific rules:
- //
- // - |as_pointer| is for raw pointers that should be treated as a simple
- // address and will never be dereferenced. Associated with the
- // TRACE_VALUE_TYPE_POINTER type.
- //
- // - |as_string| is for C-string pointers, associated with both
- // TRACE_VALUE_TYPE_STRING and TRACE_VALUE_TYPE_COPY_STRING. The former
- // indicates that the string pointer is persistent (e.g. a C string
- // literal), while the second indicates that the pointer belongs to a
- // temporary variable that may disappear soon. The TraceArguments class
- // provides a CopyStringTo() method to copy these strings into a
- // StringStorage instance, which is useful if the instance needs to
- // survive longer than the temporaries.
- //
- // - |as_convertable| is equivalent to
- // std::unique_ptr<ConvertableToTraceFormat>, except that it is a pointer
- // to keep this union POD and avoid un-necessary declarations and potential
- // code generation. This means that its ownership is passed to the
- // TraceValue instance when Init(std::unique_ptr<ConvertableToTraceFormat>)
- // is called, and that it will be deleted by the containing TraceArguments
- // destructor, or Reset() method.
- //
- union BASE_EXPORT TraceValue {
- bool as_bool;
- unsigned long long as_uint;
- long long as_int;
- double as_double;
- const void* as_pointer;
- const char* as_string;
- ConvertableToTraceFormat* as_convertable;
- // There is no constructor to keep this structure POD intentionally.
- // This avoids un-needed initialization when only 0 or 1 arguments are
- // used to construct a TraceArguments instance. Use Init() instead to
- // perform explicit initialization from a given C++ value.
- // Initialize TraceValue instance from a C++ trace value.
- // This relies on the proper specialization of TraceValue::Helper<>
- // described below. Usage is simply:
- //
- // TraceValue v;
- // v.Init(<value>);
- //
- // NOTE: For ConvertableToTraceFormat values, see the note above and
- // the one for TraceValue::Helper for CONVERTABLE_TYPE below.
- template <typename T>
- void Init(T&& value) {
- using ValueType = typename InnerType<T>::type;
- Helper<ValueType>::SetValue(this, std::forward<T>(value));
- }
- // Static method to create a new TraceValue instance from a given
- // initialization value. Note that this deduces the TRACE_VALUE_TYPE_XXX
- // type but doesn't return it, use ForType<T>::value for this.
- //
- // Usage example:
- // auto v = TraceValue::Make(100);
- // auto v2 = TraceValue::Make("Some text string");
- //
- // IMPORTANT: Experience shows that the compiler generates worse code when
- // using this method rather than calling Init() directly on an existing
- // TraceValue union :-(
- //
- template <typename T>
- static TraceValue Make(T&& value) {
- TraceValue ret;
- ret.Init(std::forward<T>(value));
- return ret;
- }
- // Output current value as a JSON string. |type| must be a valid
- // TRACE_VALUE_TYPE_XXX value.
- void AppendAsJSON(unsigned char type, std::string* out) const;
- // Output current value as a string. If the output string is to be used
- // in a JSON format use AppendAsJSON instead. |type| must be valid
- // TRACE_VALUE_TYPE_XXX value.
- void AppendAsString(unsigned char type, std::string* out) const;
- private:
- void Append(unsigned char type, bool as_json, std::string* out) const;
- // InnerType<T>::type removes reference, cv-qualifications and decays
- // function and arrays into pointers. Only used internally.
- template <typename T>
- struct InnerType {
- using type = typename std::remove_cv<typename std::remove_reference<
- typename std::decay<T>::type>::type>::type;
- };
- public:
- // TraceValue::Helper is used to provide information about initialization
- // value types and an initialization function. It is a struct that should
- // provide the following for supported initialization value types:
- //
- // - kType: is a static TRACE_VALUE_TYPE_XXX constant.
- //
- // - SetValue(TraceValue*, T): is a static inline method that sets
- // TraceValue value from a given T value. Second parameter type
- // can also be const T& or T&& to restrict uses.
- //
- // IMPORTANT: The type T must be InnerType<Q>, where Q is the real C++
- // argument type. I.e. you should not have to deal with reference types
- // in your specialization.
- //
- // Specializations are defined for integers, enums, floating point, pointers,
- // constant C string literals and pointers, std::string, time values below.
- //
- // Specializations for custom types are possible provided that there exists
- // a corresponding Helper specialization, for example:
- //
- // template <>
- // struct base::trace_event::TraceValue::Helper<Foo> {
- // static constexpr unsigned char kTypes = TRACE_VALUE_TYPE_COPY_STRING;
- // static inline void SetValue(TraceValue* v, const Foo& value) {
- // v->as_string = value.c_str();
- // }
- // };
- //
- // Will allow code like:
- //
- // Foo foo = ...;
- // auto v = TraceValue::Make(foo);
- //
- // Or even:
- // Foo foo = ...;
- // TraceArguments args("foo_arg1", foo);
- //
- template <typename T, class = void>
- struct Helper {};
- // TraceValue::TypeFor<T>::value returns the TRACE_VALUE_TYPE_XXX
- // corresponding to initialization values of type T.
- template <typename T>
- struct TypeFor {
- using ValueType = typename InnerType<T>::type;
- static const unsigned char value = Helper<ValueType>::kType;
- };
- // TraceValue::TypeCheck<T>::value is only defined iff T can be used to
- // initialize a TraceValue instance. This is useful to restrict template
- // instantiation to only the appropriate type (see TraceArguments
- // constructors below).
- template <typename T,
- class = decltype(TraceValue::Helper<
- typename TraceValue::InnerType<T>::type>::kType)>
- struct TypeCheck {
- static const bool value = true;
- };
- };
- // TraceValue::Helper for integers and enums.
- template <typename T>
- struct TraceValue::Helper<
- T,
- typename std::enable_if<std::is_integral<T>::value ||
- std::is_enum<T>::value>::type> {
- static constexpr unsigned char kType =
- std::is_signed<T>::value ? TRACE_VALUE_TYPE_INT : TRACE_VALUE_TYPE_UINT;
- static inline void SetValue(TraceValue* v, T value) {
- v->as_uint = static_cast<unsigned long long>(value);
- }
- };
- // TraceValue::Helper for floating-point types
- template <typename T>
- struct TraceValue::
- Helper<T, typename std::enable_if<std::is_floating_point<T>::value>::type> {
- static constexpr unsigned char kType = TRACE_VALUE_TYPE_DOUBLE;
- static inline void SetValue(TraceValue* v, T value) { v->as_double = value; }
- };
- // TraceValue::Helper for bool.
- template <>
- struct TraceValue::Helper<bool> {
- static constexpr unsigned char kType = TRACE_VALUE_TYPE_BOOL;
- static inline void SetValue(TraceValue* v, bool value) { v->as_bool = value; }
- };
- // TraceValue::Helper for generic pointer types.
- template <typename T>
- struct TraceValue::Helper<T*> {
- static constexpr unsigned char kType = TRACE_VALUE_TYPE_POINTER;
- static inline void SetValue(TraceValue* v,
- const typename std::decay<T>::type* value) {
- v->as_pointer = value;
- }
- };
- // TraceValue::Helper for raw persistent C strings.
- template <>
- struct TraceValue::Helper<const char*> {
- static constexpr unsigned char kType = TRACE_VALUE_TYPE_STRING;
- static inline void SetValue(TraceValue* v, const char* value) {
- v->as_string = value;
- }
- };
- // TraceValue::Helper for std::string values.
- template <>
- struct TraceValue::Helper<std::string> {
- static constexpr unsigned char kType = TRACE_VALUE_TYPE_COPY_STRING;
- static inline void SetValue(TraceValue* v, const std::string& value) {
- v->as_string = value.c_str();
- }
- };
- // Special case for scoped pointers to convertables to trace format.
- // |CONVERTABLE_TYPE| must be a type whose pointers can be converted to a
- // ConvertableToTraceFormat* pointer as well (e.g. a derived class).
- // IMPORTANT: This takes an std::unique_ptr<CONVERTABLE_TYPE> value, and takes
- // ownership of the pointed object!
- template <typename CONVERTABLE_TYPE>
- struct TraceValue::Helper<std::unique_ptr<CONVERTABLE_TYPE>,
- typename std::enable_if<std::is_convertible<
- CONVERTABLE_TYPE*,
- ConvertableToTraceFormat*>::value>::type> {
- static constexpr unsigned char kType = TRACE_VALUE_TYPE_CONVERTABLE;
- static inline void SetValue(TraceValue* v,
- std::unique_ptr<CONVERTABLE_TYPE> value) {
- v->as_convertable = value.release();
- }
- };
- // Specialization for time-based values like base::Time, which provide a
- // a ToInternalValue() method.
- template <typename T>
- struct TraceValue::Helper<
- T,
- typename std::enable_if<std::is_same<T, base::Time>::value ||
- std::is_same<T, base::TimeTicks>::value ||
- std::is_same<T, base::ThreadTicks>::value>::type> {
- static constexpr unsigned char kType = TRACE_VALUE_TYPE_INT;
- static inline void SetValue(TraceValue* v, const T& value) {
- v->as_int = value.ToInternalValue();
- }
- };
- // Simple container for const char* that should be copied instead of retained.
- // The goal is to indicate that the C string is copyable, unlike the default
- // Init(const char*) implementation. Usage is:
- //
- // const char* str = ...;
- // v.Init(TraceStringWithCopy(str));
- //
- // Which will mark the string as TRACE_VALUE_TYPE_COPY_STRING, instead of
- // TRACE_VALUE_TYPE_STRING.
- //
- class TraceStringWithCopy {
- public:
- explicit TraceStringWithCopy(const char* str) : str_(str) {}
- const char* str() const { return str_; }
- private:
- const char* str_;
- };
- template <>
- struct TraceValue::Helper<TraceStringWithCopy> {
- static constexpr unsigned char kType = TRACE_VALUE_TYPE_COPY_STRING;
- static inline void SetValue(TraceValue* v, const TraceStringWithCopy& value) {
- v->as_string = value.str();
- }
- };
- class TraceArguments;
- // A small class used to store a copy of all strings from a given
- // TraceArguments instance (see below). When empty, this should only
- // take the size of a pointer. Otherwise, this will point to a heap
- // allocated block containing a size_t value followed by all characters
- // in the storage area. For most cases, this is more efficient
- // than using a std::unique_ptr<std::string> or an std::vector<char>.
- class BASE_EXPORT StringStorage {
- public:
- constexpr StringStorage() = default;
- explicit StringStorage(size_t alloc_size) { Reset(alloc_size); }
- ~StringStorage() {
- if (data_)
- ::free(data_);
- }
- StringStorage(StringStorage&& other) noexcept : data_(other.data_) {
- other.data_ = nullptr;
- }
- StringStorage& operator=(StringStorage&& other) noexcept {
- if (this != &other) {
- if (data_)
- ::free(data_);
- data_ = other.data_;
- other.data_ = nullptr;
- }
- return *this;
- }
- // Reset storage area to new allocation size. Existing content might not
- // be preserved. If |alloc_size| is 0, this will free the storage area
- // as well.
- void Reset(size_t alloc_size = 0);
- // Accessors.
- constexpr size_t size() const { return data_ ? data_->size : 0u; }
- constexpr const char* data() const { return data_ ? data_->chars : nullptr; }
- constexpr char* data() { return data_ ? data_->chars : nullptr; }
- constexpr const char* begin() const { return data(); }
- constexpr const char* end() const { return data() + size(); }
- inline char* begin() { return data(); }
- inline char* end() { return data() + size(); }
- // True iff storage is empty.
- constexpr bool empty() const { return size() == 0; }
- // Returns true if |ptr| is inside the storage area, false otherwise.
- // Used during unit-testing.
- constexpr bool Contains(const void* ptr) const {
- const char* char_ptr = static_cast<const char*>(ptr);
- return (char_ptr >= begin() && char_ptr < end());
- }
- // Returns true if all string pointers in |args| are contained in this
- // storage area.
- bool Contains(const TraceArguments& args) const;
- // Return an estimate of the memory overhead of this instance. This doesn't
- // count the size of |data_| itself.
- constexpr size_t EstimateTraceMemoryOverhead() const {
- return data_ ? sizeof(size_t) + data_->size : 0u;
- }
- private:
- // Heap allocated data block (variable size), made of:
- //
- // - size: a size_t field, giving the size of the following |chars| array.
- // - chars: an array of |size| characters, holding all zero-terminated
- // strings referenced from a TraceArguments instance.
- struct Data {
- size_t size = 0;
- char chars[1]; // really |size| character items in storage.
- };
- // This is an owning pointer. Normally, using a std::unique_ptr<> would be
- // enough, but the compiler will then complaing about inlined constructors
- // and destructors being too complex (!), resulting in larger code for no
- // good reason.
- Data* data_ = nullptr;
- };
- // TraceArguments models an array of kMaxSize trace-related items,
- // each one of them having:
- // - a name, which is a constant char array literal.
- // - a type, as described by TRACE_VALUE_TYPE_XXX macros.
- // - a value, stored in a TraceValue union.
- //
- // IMPORTANT: For TRACE_VALUE_TYPE_CONVERTABLE, the value holds an owning
- // pointer to an AsConvertableToTraceFormat instance, which will
- // be destroyed with the array (or moved out of it when passed
- // to a TraceEvent instance).
- //
- // For TRACE_VALUE_TYPE_COPY_STRING, the value holds a const char* pointer
- // whose content will be copied when creating a TraceEvent instance.
- //
- // IMPORTANT: Most constructors and the destructor are all inlined
- // intentionally, in order to let the compiler remove un-necessary operations
- // and reduce machine code.
- //
- class BASE_EXPORT TraceArguments {
- public:
- // Maximum number of arguments held by this structure.
- static constexpr size_t kMaxSize = 2;
- // Default constructor, no arguments.
- TraceArguments() : size_(0) {}
- // Constructor for a single argument.
- template <typename T, class = decltype(TraceValue::TypeCheck<T>::value)>
- TraceArguments(const char* arg1_name, T&& arg1_value) : size_(1) {
- types_[0] = TraceValue::TypeFor<T>::value;
- names_[0] = arg1_name;
- values_[0].Init(std::forward<T>(arg1_value));
- }
- // Constructor for two arguments.
- template <typename T1,
- typename T2,
- class = decltype(TraceValue::TypeCheck<T1>::value &&
- TraceValue::TypeCheck<T2>::value)>
- TraceArguments(const char* arg1_name,
- T1&& arg1_value,
- const char* arg2_name,
- T2&& arg2_value)
- : size_(2) {
- types_[0] = TraceValue::TypeFor<T1>::value;
- types_[1] = TraceValue::TypeFor<T2>::value;
- names_[0] = arg1_name;
- names_[1] = arg2_name;
- values_[0].Init(std::forward<T1>(arg1_value));
- values_[1].Init(std::forward<T2>(arg2_value));
- }
- // Constructor used to convert a legacy set of arguments when there
- // are no convertable values at all.
- TraceArguments(int num_args,
- const char* const* arg_names,
- const unsigned char* arg_types,
- const unsigned long long* arg_values);
- // Constructor used to convert legacy set of arguments, where the
- // convertable values are also provided by an array of CONVERTABLE_TYPE.
- template <typename CONVERTABLE_TYPE>
- TraceArguments(int num_args,
- const char* const* arg_names,
- const unsigned char* arg_types,
- const unsigned long long* arg_values,
- CONVERTABLE_TYPE* arg_convertables) {
- static int max_args = static_cast<int>(kMaxSize);
- if (num_args > max_args)
- num_args = max_args;
- size_ = static_cast<unsigned char>(num_args);
- for (size_t n = 0; n < size_; ++n) {
- types_[n] = arg_types[n];
- names_[n] = arg_names[n];
- if (arg_types[n] == TRACE_VALUE_TYPE_CONVERTABLE) {
- values_[n].Init(
- std::forward<CONVERTABLE_TYPE>(std::move(arg_convertables[n])));
- } else {
- values_[n].as_uint = arg_values[n];
- }
- }
- }
- // Destructor. NOTE: Intentionally inlined (see note above).
- ~TraceArguments() {
- for (size_t n = 0; n < size_; ++n) {
- if (types_[n] == TRACE_VALUE_TYPE_CONVERTABLE)
- delete values_[n].as_convertable;
- }
- }
- // Disallow copy operations.
- TraceArguments(const TraceArguments&) = delete;
- TraceArguments& operator=(const TraceArguments&) = delete;
- // Allow move operations.
- TraceArguments(TraceArguments&& other) noexcept {
- ::memcpy(this, &other, sizeof(*this));
- // All owning pointers were copied to |this|. Setting |other.size_| will
- // mask the pointer values still in |other|.
- other.size_ = 0;
- }
- TraceArguments& operator=(TraceArguments&&) noexcept;
- // Accessors
- size_t size() const { return size_; }
- const unsigned char* types() const { return types_; }
- const char* const* names() const { return names_; }
- const TraceValue* values() const { return values_; }
- // Reset to empty arguments list.
- void Reset();
- // Use |storage| to copy all copyable strings.
- // If |copy_all_strings| is false, then only the TRACE_VALUE_TYPE_COPY_STRING
- // values will be copied into storage. If it is true, then argument names are
- // also copied to storage, as well as the strings pointed to by
- // |*extra_string1| and |*extra_string2|.
- // NOTE: If there are no strings to copy, |*storage| is left untouched.
- void CopyStringsTo(StringStorage* storage,
- bool copy_all_strings,
- const char** extra_string1,
- const char** extra_string2);
- // Append debug string representation to |*out|.
- void AppendDebugString(std::string* out);
- private:
- unsigned char size_;
- unsigned char types_[kMaxSize];
- const char* names_[kMaxSize];
- TraceValue values_[kMaxSize];
- };
- } // namespace trace_event
- } // namespace base
- #endif // BASE_TRACE_EVENT_TRACE_ARGUMENTS_H_
|