xref: /aosp_15_r20/external/cronet/base/trace_event/trace_arguments.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1*6777b538SAndroid Build Coastguard Worker // Copyright 2018 The Chromium Authors
2*6777b538SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*6777b538SAndroid Build Coastguard Worker // found in the LICENSE file.
4*6777b538SAndroid Build Coastguard Worker 
5*6777b538SAndroid Build Coastguard Worker #include "base/trace_event/trace_arguments.h"
6*6777b538SAndroid Build Coastguard Worker 
7*6777b538SAndroid Build Coastguard Worker #include <inttypes.h>
8*6777b538SAndroid Build Coastguard Worker #include <stddef.h>
9*6777b538SAndroid Build Coastguard Worker #include <stdio.h>
10*6777b538SAndroid Build Coastguard Worker #include <string.h>
11*6777b538SAndroid Build Coastguard Worker 
12*6777b538SAndroid Build Coastguard Worker #include <cmath>
13*6777b538SAndroid Build Coastguard Worker #include <ostream>
14*6777b538SAndroid Build Coastguard Worker 
15*6777b538SAndroid Build Coastguard Worker #include "base/check_op.h"
16*6777b538SAndroid Build Coastguard Worker #include "base/json/string_escape.h"
17*6777b538SAndroid Build Coastguard Worker #include "base/memory/raw_ptr.h"
18*6777b538SAndroid Build Coastguard Worker #include "base/notreached.h"
19*6777b538SAndroid Build Coastguard Worker #include "base/strings/strcat.h"
20*6777b538SAndroid Build Coastguard Worker #include "base/strings/string_number_conversions.h"
21*6777b538SAndroid Build Coastguard Worker #include "base/strings/string_util.h"
22*6777b538SAndroid Build Coastguard Worker #include "base/strings/stringprintf.h"
23*6777b538SAndroid Build Coastguard Worker #include "base/strings/utf_string_conversions.h"
24*6777b538SAndroid Build Coastguard Worker 
25*6777b538SAndroid Build Coastguard Worker namespace base {
26*6777b538SAndroid Build Coastguard Worker namespace trace_event {
27*6777b538SAndroid Build Coastguard Worker 
28*6777b538SAndroid Build Coastguard Worker namespace {
29*6777b538SAndroid Build Coastguard Worker 
GetAllocLength(const char * str)30*6777b538SAndroid Build Coastguard Worker size_t GetAllocLength(const char* str) {
31*6777b538SAndroid Build Coastguard Worker   return str ? strlen(str) + 1 : 0;
32*6777b538SAndroid Build Coastguard Worker }
33*6777b538SAndroid Build Coastguard Worker 
34*6777b538SAndroid Build Coastguard Worker // Copies |*member| into |*buffer|, sets |*member| to point to this new
35*6777b538SAndroid Build Coastguard Worker // location, and then advances |*buffer| by the amount written.
CopyTraceEventParameter(char ** buffer,const char ** member,const char * end)36*6777b538SAndroid Build Coastguard Worker void CopyTraceEventParameter(char** buffer,
37*6777b538SAndroid Build Coastguard Worker                              const char** member,
38*6777b538SAndroid Build Coastguard Worker                              const char* end) {
39*6777b538SAndroid Build Coastguard Worker   if (*member) {
40*6777b538SAndroid Build Coastguard Worker     DCHECK_GE(end, *buffer);
41*6777b538SAndroid Build Coastguard Worker     size_t written =
42*6777b538SAndroid Build Coastguard Worker         strlcpy(*buffer, *member, static_cast<size_t>(end - *buffer)) + 1;
43*6777b538SAndroid Build Coastguard Worker     DCHECK_LE(static_cast<ptrdiff_t>(written), end - *buffer);
44*6777b538SAndroid Build Coastguard Worker     *member = *buffer;
45*6777b538SAndroid Build Coastguard Worker     *buffer += written;
46*6777b538SAndroid Build Coastguard Worker   }
47*6777b538SAndroid Build Coastguard Worker }
48*6777b538SAndroid Build Coastguard Worker 
49*6777b538SAndroid Build Coastguard Worker // Append |val| as a JSON output value to |*out|.
AppendDouble(double val,bool as_json,std::string * out)50*6777b538SAndroid Build Coastguard Worker void AppendDouble(double val, bool as_json, std::string* out) {
51*6777b538SAndroid Build Coastguard Worker   // FIXME: base/json/json_writer.cc is using the same code,
52*6777b538SAndroid Build Coastguard Worker   //        should be made into a common method.
53*6777b538SAndroid Build Coastguard Worker   std::string real;
54*6777b538SAndroid Build Coastguard Worker   if (std::isfinite(val)) {
55*6777b538SAndroid Build Coastguard Worker     real = NumberToString(val);
56*6777b538SAndroid Build Coastguard Worker     // Ensure that the number has a .0 if there's no decimal or 'e'.  This
57*6777b538SAndroid Build Coastguard Worker     // makes sure that when we read the JSON back, it's interpreted as a
58*6777b538SAndroid Build Coastguard Worker     // real rather than an int.
59*6777b538SAndroid Build Coastguard Worker     if (real.find('.') == std::string::npos &&
60*6777b538SAndroid Build Coastguard Worker         real.find('e') == std::string::npos &&
61*6777b538SAndroid Build Coastguard Worker         real.find('E') == std::string::npos) {
62*6777b538SAndroid Build Coastguard Worker       real.append(".0");
63*6777b538SAndroid Build Coastguard Worker     }
64*6777b538SAndroid Build Coastguard Worker     // The JSON spec requires that non-integer values in the range (-1,1)
65*6777b538SAndroid Build Coastguard Worker     // have a zero before the decimal point - ".52" is not valid, "0.52" is.
66*6777b538SAndroid Build Coastguard Worker     if (real[0] == '.') {
67*6777b538SAndroid Build Coastguard Worker       real.insert(0, "0");
68*6777b538SAndroid Build Coastguard Worker     } else if (real.length() > 1 && real[0] == '-' && real[1] == '.') {
69*6777b538SAndroid Build Coastguard Worker       // "-.1" bad "-0.1" good
70*6777b538SAndroid Build Coastguard Worker       real.insert(1, "0");
71*6777b538SAndroid Build Coastguard Worker     }
72*6777b538SAndroid Build Coastguard Worker   } else if (std::isnan(val)) {
73*6777b538SAndroid Build Coastguard Worker     // The JSON spec doesn't allow NaN and Infinity (since these are
74*6777b538SAndroid Build Coastguard Worker     // objects in EcmaScript).  Use strings instead.
75*6777b538SAndroid Build Coastguard Worker     real = as_json ? "\"NaN\"" : "NaN";
76*6777b538SAndroid Build Coastguard Worker   } else if (val < 0) {
77*6777b538SAndroid Build Coastguard Worker     real = as_json ? "\"-Infinity\"" : "-Infinity";
78*6777b538SAndroid Build Coastguard Worker   } else {
79*6777b538SAndroid Build Coastguard Worker     real = as_json ? "\"Infinity\"" : "Infinity";
80*6777b538SAndroid Build Coastguard Worker   }
81*6777b538SAndroid Build Coastguard Worker   StringAppendF(out, "%s", real.c_str());
82*6777b538SAndroid Build Coastguard Worker }
83*6777b538SAndroid Build Coastguard Worker 
TypeToString(unsigned char arg_type)84*6777b538SAndroid Build Coastguard Worker const char* TypeToString(unsigned char arg_type) {
85*6777b538SAndroid Build Coastguard Worker   switch (arg_type) {
86*6777b538SAndroid Build Coastguard Worker     case TRACE_VALUE_TYPE_INT:
87*6777b538SAndroid Build Coastguard Worker       return "int";
88*6777b538SAndroid Build Coastguard Worker     case TRACE_VALUE_TYPE_UINT:
89*6777b538SAndroid Build Coastguard Worker       return "uint";
90*6777b538SAndroid Build Coastguard Worker     case TRACE_VALUE_TYPE_DOUBLE:
91*6777b538SAndroid Build Coastguard Worker       return "double";
92*6777b538SAndroid Build Coastguard Worker     case TRACE_VALUE_TYPE_BOOL:
93*6777b538SAndroid Build Coastguard Worker       return "bool";
94*6777b538SAndroid Build Coastguard Worker     case TRACE_VALUE_TYPE_POINTER:
95*6777b538SAndroid Build Coastguard Worker       return "pointer";
96*6777b538SAndroid Build Coastguard Worker     case TRACE_VALUE_TYPE_STRING:
97*6777b538SAndroid Build Coastguard Worker       return "string";
98*6777b538SAndroid Build Coastguard Worker     case TRACE_VALUE_TYPE_COPY_STRING:
99*6777b538SAndroid Build Coastguard Worker       return "copy_string";
100*6777b538SAndroid Build Coastguard Worker     case TRACE_VALUE_TYPE_CONVERTABLE:
101*6777b538SAndroid Build Coastguard Worker       return "convertable";
102*6777b538SAndroid Build Coastguard Worker     default:
103*6777b538SAndroid Build Coastguard Worker       NOTREACHED();
104*6777b538SAndroid Build Coastguard Worker       return "UNKNOWN_TYPE";
105*6777b538SAndroid Build Coastguard Worker   }
106*6777b538SAndroid Build Coastguard Worker }
107*6777b538SAndroid Build Coastguard Worker 
AppendValueDebugString(const TraceArguments & args,size_t idx,std::string * out)108*6777b538SAndroid Build Coastguard Worker void AppendValueDebugString(const TraceArguments& args,
109*6777b538SAndroid Build Coastguard Worker                             size_t idx,
110*6777b538SAndroid Build Coastguard Worker                             std::string* out) {
111*6777b538SAndroid Build Coastguard Worker   *out += (args.names()[idx] ? args.names()[idx] : "NULL_NAME");
112*6777b538SAndroid Build Coastguard Worker   *out += "=";
113*6777b538SAndroid Build Coastguard Worker   *out += TypeToString(args.types()[idx]);
114*6777b538SAndroid Build Coastguard Worker   *out += "(";
115*6777b538SAndroid Build Coastguard Worker   args.values()[idx].AppendAsJSON(args.types()[idx], out);
116*6777b538SAndroid Build Coastguard Worker   *out += ")";
117*6777b538SAndroid Build Coastguard Worker }
118*6777b538SAndroid Build Coastguard Worker 
119*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(USE_PERFETTO_CLIENT_LIBRARY)
120*6777b538SAndroid Build Coastguard Worker class PerfettoProtoAppender : public ConvertableToTraceFormat::ProtoAppender {
121*6777b538SAndroid Build Coastguard Worker  public:
PerfettoProtoAppender(perfetto::protos::pbzero::DebugAnnotation * proto)122*6777b538SAndroid Build Coastguard Worker   explicit PerfettoProtoAppender(
123*6777b538SAndroid Build Coastguard Worker       perfetto::protos::pbzero::DebugAnnotation* proto)
124*6777b538SAndroid Build Coastguard Worker       : annotation_proto_(proto) {}
125*6777b538SAndroid Build Coastguard Worker   ~PerfettoProtoAppender() override = default;
126*6777b538SAndroid Build Coastguard Worker 
AddBuffer(uint8_t * begin,uint8_t * end)127*6777b538SAndroid Build Coastguard Worker   void AddBuffer(uint8_t* begin, uint8_t* end) override {
128*6777b538SAndroid Build Coastguard Worker     ranges_.emplace_back();
129*6777b538SAndroid Build Coastguard Worker     ranges_.back().begin = begin;
130*6777b538SAndroid Build Coastguard Worker     ranges_.back().end = end;
131*6777b538SAndroid Build Coastguard Worker   }
132*6777b538SAndroid Build Coastguard Worker 
Finalize(uint32_t field_id)133*6777b538SAndroid Build Coastguard Worker   size_t Finalize(uint32_t field_id) override {
134*6777b538SAndroid Build Coastguard Worker     return annotation_proto_->AppendScatteredBytes(field_id, ranges_.data(),
135*6777b538SAndroid Build Coastguard Worker                                                    ranges_.size());
136*6777b538SAndroid Build Coastguard Worker   }
137*6777b538SAndroid Build Coastguard Worker 
138*6777b538SAndroid Build Coastguard Worker  private:
139*6777b538SAndroid Build Coastguard Worker   std::vector<protozero::ContiguousMemoryRange> ranges_;
140*6777b538SAndroid Build Coastguard Worker   raw_ptr<perfetto::protos::pbzero::DebugAnnotation> annotation_proto_;
141*6777b538SAndroid Build Coastguard Worker };
142*6777b538SAndroid Build Coastguard Worker #endif  // BUILDFLAG(USE_PERFETTO_CLIENT_LIBRARY)
143*6777b538SAndroid Build Coastguard Worker 
144*6777b538SAndroid Build Coastguard Worker }  // namespace
145*6777b538SAndroid Build Coastguard Worker 
Reset(size_t alloc_size)146*6777b538SAndroid Build Coastguard Worker void StringStorage::Reset(size_t alloc_size) {
147*6777b538SAndroid Build Coastguard Worker   if (!alloc_size) {
148*6777b538SAndroid Build Coastguard Worker     if (data_)
149*6777b538SAndroid Build Coastguard Worker       ::free(data_);
150*6777b538SAndroid Build Coastguard Worker     data_ = nullptr;
151*6777b538SAndroid Build Coastguard Worker   } else if (!data_ || alloc_size != data_->size) {
152*6777b538SAndroid Build Coastguard Worker     data_ = static_cast<Data*>(::realloc(data_, sizeof(size_t) + alloc_size));
153*6777b538SAndroid Build Coastguard Worker     data_->size = alloc_size;
154*6777b538SAndroid Build Coastguard Worker   }
155*6777b538SAndroid Build Coastguard Worker }
156*6777b538SAndroid Build Coastguard Worker 
Contains(const TraceArguments & args) const157*6777b538SAndroid Build Coastguard Worker bool StringStorage::Contains(const TraceArguments& args) const {
158*6777b538SAndroid Build Coastguard Worker   for (size_t n = 0; n < args.size(); ++n) {
159*6777b538SAndroid Build Coastguard Worker     if (args.types()[n] == TRACE_VALUE_TYPE_COPY_STRING &&
160*6777b538SAndroid Build Coastguard Worker         !Contains(args.values()[n].as_string)) {
161*6777b538SAndroid Build Coastguard Worker       return false;
162*6777b538SAndroid Build Coastguard Worker     }
163*6777b538SAndroid Build Coastguard Worker   }
164*6777b538SAndroid Build Coastguard Worker   return true;
165*6777b538SAndroid Build Coastguard Worker }
166*6777b538SAndroid Build Coastguard Worker 
167*6777b538SAndroid Build Coastguard Worker static_assert(
168*6777b538SAndroid Build Coastguard Worker     std::is_trivial_v<TraceValue> && std::is_standard_layout_v<TraceValue>,
169*6777b538SAndroid Build Coastguard Worker     "TraceValue must be plain-old-data type for performance reasons!");
170*6777b538SAndroid Build Coastguard Worker 
AppendAsJSON(unsigned char type,std::string * out) const171*6777b538SAndroid Build Coastguard Worker void TraceValue::AppendAsJSON(unsigned char type, std::string* out) const {
172*6777b538SAndroid Build Coastguard Worker   Append(type, true, out);
173*6777b538SAndroid Build Coastguard Worker }
174*6777b538SAndroid Build Coastguard Worker 
AppendAsString(unsigned char type,std::string * out) const175*6777b538SAndroid Build Coastguard Worker void TraceValue::AppendAsString(unsigned char type, std::string* out) const {
176*6777b538SAndroid Build Coastguard Worker   Append(type, false, out);
177*6777b538SAndroid Build Coastguard Worker }
178*6777b538SAndroid Build Coastguard Worker 
Append(unsigned char type,bool as_json,std::string * out) const179*6777b538SAndroid Build Coastguard Worker void TraceValue::Append(unsigned char type,
180*6777b538SAndroid Build Coastguard Worker                         bool as_json,
181*6777b538SAndroid Build Coastguard Worker                         std::string* out) const {
182*6777b538SAndroid Build Coastguard Worker   switch (type) {
183*6777b538SAndroid Build Coastguard Worker     case TRACE_VALUE_TYPE_BOOL:
184*6777b538SAndroid Build Coastguard Worker       *out += this->as_bool ? "true" : "false";
185*6777b538SAndroid Build Coastguard Worker       break;
186*6777b538SAndroid Build Coastguard Worker     case TRACE_VALUE_TYPE_UINT:
187*6777b538SAndroid Build Coastguard Worker       StringAppendF(out, "%" PRIu64, static_cast<uint64_t>(this->as_uint));
188*6777b538SAndroid Build Coastguard Worker       break;
189*6777b538SAndroid Build Coastguard Worker     case TRACE_VALUE_TYPE_INT:
190*6777b538SAndroid Build Coastguard Worker       StringAppendF(out, "%" PRId64, static_cast<int64_t>(this->as_int));
191*6777b538SAndroid Build Coastguard Worker       break;
192*6777b538SAndroid Build Coastguard Worker     case TRACE_VALUE_TYPE_DOUBLE:
193*6777b538SAndroid Build Coastguard Worker       AppendDouble(this->as_double, as_json, out);
194*6777b538SAndroid Build Coastguard Worker       break;
195*6777b538SAndroid Build Coastguard Worker     case TRACE_VALUE_TYPE_POINTER: {
196*6777b538SAndroid Build Coastguard Worker       // JSON only supports double and int numbers.
197*6777b538SAndroid Build Coastguard Worker       // So as not to lose bits from a 64-bit pointer, output as a hex string.
198*6777b538SAndroid Build Coastguard Worker       // For consistency, do the same for non-JSON strings, but without the
199*6777b538SAndroid Build Coastguard Worker       // surrounding quotes.
200*6777b538SAndroid Build Coastguard Worker       const std::string value = StringPrintf(
201*6777b538SAndroid Build Coastguard Worker           "0x%" PRIx64,
202*6777b538SAndroid Build Coastguard Worker           static_cast<uint64_t>(reinterpret_cast<uintptr_t>(this->as_pointer)));
203*6777b538SAndroid Build Coastguard Worker       *out += as_json ? StrCat({"\"", value, "\""}) : value;
204*6777b538SAndroid Build Coastguard Worker     } break;
205*6777b538SAndroid Build Coastguard Worker     case TRACE_VALUE_TYPE_STRING:
206*6777b538SAndroid Build Coastguard Worker     case TRACE_VALUE_TYPE_COPY_STRING:
207*6777b538SAndroid Build Coastguard Worker       if (as_json)
208*6777b538SAndroid Build Coastguard Worker         EscapeJSONString(this->as_string ? this->as_string : "NULL", true, out);
209*6777b538SAndroid Build Coastguard Worker       else
210*6777b538SAndroid Build Coastguard Worker         *out += this->as_string ? this->as_string : "NULL";
211*6777b538SAndroid Build Coastguard Worker       break;
212*6777b538SAndroid Build Coastguard Worker     case TRACE_VALUE_TYPE_CONVERTABLE:
213*6777b538SAndroid Build Coastguard Worker       this->as_convertable->AppendAsTraceFormat(out);
214*6777b538SAndroid Build Coastguard Worker       break;
215*6777b538SAndroid Build Coastguard Worker     case TRACE_VALUE_TYPE_PROTO:
216*6777b538SAndroid Build Coastguard Worker       DCHECK(as_json);
217*6777b538SAndroid Build Coastguard Worker       // Typed protobuf arguments aren't representable in JSON.
218*6777b538SAndroid Build Coastguard Worker       *out += "\"Unsupported (crbug.com/1225176)\"";
219*6777b538SAndroid Build Coastguard Worker       break;
220*6777b538SAndroid Build Coastguard Worker     default:
221*6777b538SAndroid Build Coastguard Worker       NOTREACHED() << "Don't know how to print this value";
222*6777b538SAndroid Build Coastguard Worker       break;
223*6777b538SAndroid Build Coastguard Worker   }
224*6777b538SAndroid Build Coastguard Worker }
225*6777b538SAndroid Build Coastguard Worker 
operator =(TraceArguments && other)226*6777b538SAndroid Build Coastguard Worker TraceArguments& TraceArguments::operator=(TraceArguments&& other) noexcept {
227*6777b538SAndroid Build Coastguard Worker   if (this != &other) {
228*6777b538SAndroid Build Coastguard Worker     this->~TraceArguments();
229*6777b538SAndroid Build Coastguard Worker     new (this) TraceArguments(std::move(other));
230*6777b538SAndroid Build Coastguard Worker   }
231*6777b538SAndroid Build Coastguard Worker   return *this;
232*6777b538SAndroid Build Coastguard Worker }
233*6777b538SAndroid Build Coastguard Worker 
TraceArguments(int num_args,const char * const * arg_names,const unsigned char * arg_types,const unsigned long long * arg_values)234*6777b538SAndroid Build Coastguard Worker TraceArguments::TraceArguments(int num_args,
235*6777b538SAndroid Build Coastguard Worker                                const char* const* arg_names,
236*6777b538SAndroid Build Coastguard Worker                                const unsigned char* arg_types,
237*6777b538SAndroid Build Coastguard Worker                                const unsigned long long* arg_values) {
238*6777b538SAndroid Build Coastguard Worker   if (num_args > static_cast<int>(kMaxSize))
239*6777b538SAndroid Build Coastguard Worker     num_args = static_cast<int>(kMaxSize);
240*6777b538SAndroid Build Coastguard Worker 
241*6777b538SAndroid Build Coastguard Worker   size_ = static_cast<unsigned char>(num_args);
242*6777b538SAndroid Build Coastguard Worker   for (size_t n = 0; n < size_; ++n) {
243*6777b538SAndroid Build Coastguard Worker     types_[n] = arg_types[n];
244*6777b538SAndroid Build Coastguard Worker     names_[n] = arg_names[n];
245*6777b538SAndroid Build Coastguard Worker     values_[n].as_uint = arg_values[n];
246*6777b538SAndroid Build Coastguard Worker   }
247*6777b538SAndroid Build Coastguard Worker }
248*6777b538SAndroid Build Coastguard Worker 
Reset()249*6777b538SAndroid Build Coastguard Worker void TraceArguments::Reset() {
250*6777b538SAndroid Build Coastguard Worker   for (size_t n = 0; n < size_; ++n) {
251*6777b538SAndroid Build Coastguard Worker     if (types_[n] == TRACE_VALUE_TYPE_CONVERTABLE)
252*6777b538SAndroid Build Coastguard Worker       delete values_[n].as_convertable;
253*6777b538SAndroid Build Coastguard Worker   }
254*6777b538SAndroid Build Coastguard Worker   size_ = 0;
255*6777b538SAndroid Build Coastguard Worker }
256*6777b538SAndroid Build Coastguard Worker 
CopyStringsTo(StringStorage * storage,bool copy_all_strings,const char ** extra_string1,const char ** extra_string2)257*6777b538SAndroid Build Coastguard Worker void TraceArguments::CopyStringsTo(StringStorage* storage,
258*6777b538SAndroid Build Coastguard Worker                                    bool copy_all_strings,
259*6777b538SAndroid Build Coastguard Worker                                    const char** extra_string1,
260*6777b538SAndroid Build Coastguard Worker                                    const char** extra_string2) {
261*6777b538SAndroid Build Coastguard Worker   // First, compute total allocation size.
262*6777b538SAndroid Build Coastguard Worker   size_t alloc_size = 0;
263*6777b538SAndroid Build Coastguard Worker 
264*6777b538SAndroid Build Coastguard Worker   if (copy_all_strings) {
265*6777b538SAndroid Build Coastguard Worker     alloc_size +=
266*6777b538SAndroid Build Coastguard Worker         GetAllocLength(*extra_string1) + GetAllocLength(*extra_string2);
267*6777b538SAndroid Build Coastguard Worker     for (size_t n = 0; n < size_; ++n)
268*6777b538SAndroid Build Coastguard Worker       alloc_size += GetAllocLength(names_[n]);
269*6777b538SAndroid Build Coastguard Worker   }
270*6777b538SAndroid Build Coastguard Worker   for (size_t n = 0; n < size_; ++n) {
271*6777b538SAndroid Build Coastguard Worker     if (copy_all_strings && types_[n] == TRACE_VALUE_TYPE_STRING)
272*6777b538SAndroid Build Coastguard Worker       types_[n] = TRACE_VALUE_TYPE_COPY_STRING;
273*6777b538SAndroid Build Coastguard Worker     if (types_[n] == TRACE_VALUE_TYPE_COPY_STRING)
274*6777b538SAndroid Build Coastguard Worker       alloc_size += GetAllocLength(values_[n].as_string);
275*6777b538SAndroid Build Coastguard Worker   }
276*6777b538SAndroid Build Coastguard Worker 
277*6777b538SAndroid Build Coastguard Worker   if (alloc_size) {
278*6777b538SAndroid Build Coastguard Worker     storage->Reset(alloc_size);
279*6777b538SAndroid Build Coastguard Worker     char* ptr = storage->data();
280*6777b538SAndroid Build Coastguard Worker     const char* end = ptr + alloc_size;
281*6777b538SAndroid Build Coastguard Worker     if (copy_all_strings) {
282*6777b538SAndroid Build Coastguard Worker       CopyTraceEventParameter(&ptr, extra_string1, end);
283*6777b538SAndroid Build Coastguard Worker       CopyTraceEventParameter(&ptr, extra_string2, end);
284*6777b538SAndroid Build Coastguard Worker       for (size_t n = 0; n < size_; ++n)
285*6777b538SAndroid Build Coastguard Worker         CopyTraceEventParameter(&ptr, &names_[n], end);
286*6777b538SAndroid Build Coastguard Worker     }
287*6777b538SAndroid Build Coastguard Worker     for (size_t n = 0; n < size_; ++n) {
288*6777b538SAndroid Build Coastguard Worker       if (types_[n] == TRACE_VALUE_TYPE_COPY_STRING)
289*6777b538SAndroid Build Coastguard Worker         CopyTraceEventParameter(&ptr, &values_[n].as_string, end);
290*6777b538SAndroid Build Coastguard Worker     }
291*6777b538SAndroid Build Coastguard Worker #if DCHECK_IS_ON()
292*6777b538SAndroid Build Coastguard Worker     DCHECK_EQ(end, ptr) << "Overrun by " << ptr - end;
293*6777b538SAndroid Build Coastguard Worker     if (copy_all_strings) {
294*6777b538SAndroid Build Coastguard Worker       if (extra_string1 && *extra_string1)
295*6777b538SAndroid Build Coastguard Worker         DCHECK(storage->Contains(*extra_string1));
296*6777b538SAndroid Build Coastguard Worker       if (extra_string2 && *extra_string2)
297*6777b538SAndroid Build Coastguard Worker         DCHECK(storage->Contains(*extra_string2));
298*6777b538SAndroid Build Coastguard Worker       for (size_t n = 0; n < size_; ++n)
299*6777b538SAndroid Build Coastguard Worker         DCHECK(storage->Contains(names_[n]));
300*6777b538SAndroid Build Coastguard Worker     }
301*6777b538SAndroid Build Coastguard Worker     for (size_t n = 0; n < size_; ++n) {
302*6777b538SAndroid Build Coastguard Worker       if (types_[n] == TRACE_VALUE_TYPE_COPY_STRING)
303*6777b538SAndroid Build Coastguard Worker         DCHECK(storage->Contains(values_[n].as_string));
304*6777b538SAndroid Build Coastguard Worker     }
305*6777b538SAndroid Build Coastguard Worker #endif  // DCHECK_IS_ON()
306*6777b538SAndroid Build Coastguard Worker   } else {
307*6777b538SAndroid Build Coastguard Worker     storage->Reset();
308*6777b538SAndroid Build Coastguard Worker   }
309*6777b538SAndroid Build Coastguard Worker }
310*6777b538SAndroid Build Coastguard Worker 
AppendDebugString(std::string * out)311*6777b538SAndroid Build Coastguard Worker void TraceArguments::AppendDebugString(std::string* out) {
312*6777b538SAndroid Build Coastguard Worker   *out += "TraceArguments(";
313*6777b538SAndroid Build Coastguard Worker   for (size_t n = 0; n < size_; ++n) {
314*6777b538SAndroid Build Coastguard Worker     if (n > 0)
315*6777b538SAndroid Build Coastguard Worker       *out += ", ";
316*6777b538SAndroid Build Coastguard Worker     AppendValueDebugString(*this, n, out);
317*6777b538SAndroid Build Coastguard Worker   }
318*6777b538SAndroid Build Coastguard Worker   *out += ")";
319*6777b538SAndroid Build Coastguard Worker }
320*6777b538SAndroid Build Coastguard Worker 
321*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(USE_PERFETTO_CLIENT_LIBRARY)
Add(perfetto::protos::pbzero::DebugAnnotation * annotation) const322*6777b538SAndroid Build Coastguard Worker void ConvertableToTraceFormat::Add(
323*6777b538SAndroid Build Coastguard Worker     perfetto::protos::pbzero::DebugAnnotation* annotation) const {
324*6777b538SAndroid Build Coastguard Worker   PerfettoProtoAppender proto_appender(annotation);
325*6777b538SAndroid Build Coastguard Worker   if (AppendToProto(&proto_appender)) {
326*6777b538SAndroid Build Coastguard Worker     return;
327*6777b538SAndroid Build Coastguard Worker   }
328*6777b538SAndroid Build Coastguard Worker 
329*6777b538SAndroid Build Coastguard Worker   std::string json;
330*6777b538SAndroid Build Coastguard Worker   AppendAsTraceFormat(&json);
331*6777b538SAndroid Build Coastguard Worker   annotation->set_legacy_json_value(json);
332*6777b538SAndroid Build Coastguard Worker }
333*6777b538SAndroid Build Coastguard Worker #endif  // BUILDFLAG(USE_PERFETTO_CLIENT_LIBRARY)
334*6777b538SAndroid Build Coastguard Worker 
335*6777b538SAndroid Build Coastguard Worker }  // namespace trace_event
336*6777b538SAndroid Build Coastguard Worker }  // namespace base
337