summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@qt.io>2019-02-08 10:17:06 +0100
committerAllan Sandfeld Jensen <allan.jensen@qt.io>2019-02-22 09:00:46 +0000
commitbfb9a9d92676d425e2a57c052882458d991d19cc (patch)
tree3c4d7f528e5acc437f4a84acf319c1941147f954
parentee09936d80b3731c8658f3613269cee12be403cc (diff)
downloadqtwebengine-chromium-bfb9a9d92676d425e2a57c052882458d991d19cc.tar.gz
[Revert] Introduction of TraceArguments
Convoluted macro and template mess that doesn't compile on MSVC. Upstream commmits: eebbd7f63c58e92d8b7081b3287b28f07706b95f 3e390e1cf6a97441fcdc5c5bc34f813f0053f6e9 ff2599dc95f6cfd211c131b63d494f7114326c0a fd0d2d18ae70c83daa081fbc9ae5de0b0aad791e c1b9c28bfe1b5439f61e27148acd079e843d2129 Change-Id: I73f23b51fa8a3690d9e1f7658a26e969ae047570 Reviewed-by: Michael BrĂ¼ning <michael.bruning@qt.io>
-rw-r--r--chromium/base/BUILD.gn3
-rw-r--r--chromium/base/trace_event/blame_context.cc23
-rw-r--r--chromium/base/trace_event/event_name_filter_unittest.cc4
-rw-r--r--chromium/base/trace_event/process_memory_dump.cc1
-rw-r--r--chromium/base/trace_event/trace_arguments.cc271
-rw-r--r--chromium/base/trace_event/trace_arguments.h671
-rw-r--r--chromium/base/trace_event/trace_arguments_unittest.cc472
-rw-r--r--chromium/base/trace_event/trace_event.h461
-rw-r--r--chromium/base/trace_event/trace_event_android.cc55
-rw-r--r--chromium/base/trace_event/trace_event_etw_export_win.cc33
-rw-r--r--chromium/base/trace_event/trace_event_etw_export_win.h15
-rw-r--r--chromium/base/trace_event/trace_event_impl.cc310
-rw-r--r--chromium/base/trace_event/trace_event_impl.h102
-rw-r--r--chromium/base/trace_event/trace_event_unittest.cc12
-rw-r--r--chromium/base/trace_event/trace_log.cc201
-rw-r--r--chromium/base/trace_event/trace_log.h58
-rw-r--r--chromium/gin/v8_platform.cc41
-rw-r--r--chromium/ppapi/shared_impl/ppb_trace_event_impl.cc48
-rw-r--r--chromium/services/resource_coordinator/memory_instrumentation/coordinator_impl.cc14
-rw-r--r--chromium/services/resource_coordinator/public/cpp/memory_instrumentation/tracing_observer.cc11
-rw-r--r--chromium/services/tracing/public/cpp/perfetto/trace_event_data_source.cc15
-rw-r--r--chromium/skia/ext/event_tracer_impl.cc12
-rw-r--r--chromium/third_party/blink/renderer/platform/instrumentation/tracing/trace_event.h21
-rw-r--r--chromium/third_party/webrtc_overrides/init_webrtc.cc8
-rw-r--r--chromium/ui/gl/angle_platform_impl.cc5
25 files changed, 1084 insertions, 1783 deletions
diff --git a/chromium/base/BUILD.gn b/chromium/base/BUILD.gn
index 1cf6f176455..995f6c3ed68 100644
--- a/chromium/base/BUILD.gn
+++ b/chromium/base/BUILD.gn
@@ -937,8 +937,6 @@ jumbo_component("base") {
"trace_event/memory_usage_estimator.h",
"trace_event/process_memory_dump.cc",
"trace_event/process_memory_dump.h",
- "trace_event/trace_arguments.cc",
- "trace_event/trace_arguments.h",
"trace_event/trace_buffer.cc",
"trace_event/trace_buffer.h",
"trace_event/trace_category.h",
@@ -2568,7 +2566,6 @@ test("base_unittests") {
"trace_event/memory_infra_background_whitelist_unittest.cc",
"trace_event/memory_usage_estimator_unittest.cc",
"trace_event/process_memory_dump_unittest.cc",
- "trace_event/trace_arguments_unittest.cc",
"trace_event/trace_category_unittest.cc",
"trace_event/trace_config_unittest.cc",
"trace_event/trace_event_filter_test_utils.cc",
diff --git a/chromium/base/trace_event/blame_context.cc b/chromium/base/trace_event/blame_context.cc
index b46412c1db9..0ed9aa7ad05 100644
--- a/chromium/base/trace_event/blame_context.cc
+++ b/chromium/base/trace_event/blame_context.cc
@@ -33,9 +33,9 @@ BlameContext::BlameContext(const char* category,
BlameContext::~BlameContext() {
DCHECK(thread_checker_.CalledOnValidThread());
DCHECK(WasInitialized());
- TRACE_EVENT_API_ADD_TRACE_EVENT(TRACE_EVENT_PHASE_DELETE_OBJECT,
- category_group_enabled_, type_, scope_, id_,
- nullptr, TRACE_EVENT_FLAG_HAS_ID);
+ TRACE_EVENT_API_ADD_TRACE_EVENT(
+ TRACE_EVENT_PHASE_DELETE_OBJECT, category_group_enabled_, type_, scope_,
+ id_, 0, nullptr, nullptr, nullptr, nullptr, TRACE_EVENT_FLAG_HAS_ID);
trace_event::TraceLog::GetInstance()->RemoveAsyncEnabledStateObserver(this);
}
@@ -43,6 +43,7 @@ void BlameContext::Enter() {
DCHECK(WasInitialized());
TRACE_EVENT_API_ADD_TRACE_EVENT(TRACE_EVENT_PHASE_ENTER_CONTEXT,
category_group_enabled_, name_, scope_, id_,
+ 0 /* num_args */, nullptr, nullptr, nullptr,
nullptr, TRACE_EVENT_FLAG_HAS_ID);
}
@@ -50,6 +51,7 @@ void BlameContext::Leave() {
DCHECK(WasInitialized());
TRACE_EVENT_API_ADD_TRACE_EVENT(TRACE_EVENT_PHASE_LEAVE_CONTEXT,
category_group_enabled_, name_, scope_, id_,
+ 0 /* num_args */, nullptr, nullptr, nullptr,
nullptr, TRACE_EVENT_FLAG_HAS_ID);
}
@@ -61,10 +63,15 @@ void BlameContext::TakeSnapshot() {
std::unique_ptr<trace_event::TracedValue> snapshot(
new trace_event::TracedValue);
AsValueInto(snapshot.get());
- TraceArguments args("snapshot", std::move(snapshot));
+ static const char* const kArgName = "snapshot";
+ const int kNumArgs = 1;
+ unsigned char arg_types[1] = {TRACE_VALUE_TYPE_CONVERTABLE};
+ std::unique_ptr<trace_event::ConvertableToTraceFormat> arg_values[1] = {
+ std::move(snapshot)};
TRACE_EVENT_API_ADD_TRACE_EVENT(TRACE_EVENT_PHASE_SNAPSHOT_OBJECT,
category_group_enabled_, type_, scope_, id_,
- &args, TRACE_EVENT_FLAG_HAS_ID);
+ kNumArgs, &kArgName, arg_types, nullptr,
+ arg_values, TRACE_EVENT_FLAG_HAS_ID);
}
void BlameContext::OnTraceLogEnabled() {
@@ -88,9 +95,9 @@ void BlameContext::Initialize() {
DCHECK(thread_checker_.CalledOnValidThread());
category_group_enabled_ =
TRACE_EVENT_API_GET_CATEGORY_GROUP_ENABLED(category_);
- TRACE_EVENT_API_ADD_TRACE_EVENT(TRACE_EVENT_PHASE_CREATE_OBJECT,
- category_group_enabled_, type_, scope_, id_,
- nullptr, TRACE_EVENT_FLAG_HAS_ID);
+ TRACE_EVENT_API_ADD_TRACE_EVENT(
+ TRACE_EVENT_PHASE_CREATE_OBJECT, category_group_enabled_, type_, scope_,
+ id_, 0, nullptr, nullptr, nullptr, nullptr, TRACE_EVENT_FLAG_HAS_ID);
trace_event::TraceLog::GetInstance()->AddAsyncEnabledStateObserver(
weak_factory_.GetWeakPtr());
TakeSnapshot();
diff --git a/chromium/base/trace_event/event_name_filter_unittest.cc b/chromium/base/trace_event/event_name_filter_unittest.cc
index d0b32d11dae..e1d6f51d9f2 100644
--- a/chromium/base/trace_event/event_name_filter_unittest.cc
+++ b/chromium/base/trace_event/event_name_filter_unittest.cc
@@ -13,8 +13,8 @@ namespace trace_event {
const TraceEvent& MakeTraceEvent(const char* name) {
static TraceEvent event;
- event.Reset(0, TimeTicks(), ThreadTicks(), 'b', nullptr, name, "", 0, 0,
- nullptr, 0);
+ event.Reset(0, TimeTicks(), ThreadTicks(), 'b', nullptr, name, "", 0, 0, 0,
+ nullptr, nullptr, nullptr, nullptr, 0);
return event;
}
diff --git a/chromium/base/trace_event/process_memory_dump.cc b/chromium/base/trace_event/process_memory_dump.cc
index 5a049cc1d5c..8f851f4b0cb 100644
--- a/chromium/base/trace_event/process_memory_dump.cc
+++ b/chromium/base/trace_event/process_memory_dump.cc
@@ -13,7 +13,6 @@
#include "base/process/process_metrics.h"
#include "base/strings/stringprintf.h"
#include "base/trace_event/memory_infra_background_whitelist.h"
-#include "base/trace_event/trace_event_impl.h"
#include "base/trace_event/traced_value.h"
#include "base/unguessable_token.h"
#include "build/build_config.h"
diff --git a/chromium/base/trace_event/trace_arguments.cc b/chromium/base/trace_event/trace_arguments.cc
deleted file mode 100644
index 642ba2311d7..00000000000
--- a/chromium/base/trace_event/trace_arguments.cc
+++ /dev/null
@@ -1,271 +0,0 @@
-// 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.
-
-#include "base/trace_event/trace_arguments.h"
-
-#include <inttypes.h>
-#include <stddef.h>
-#include <stdio.h>
-#include <string.h>
-
-#include <cmath>
-
-#include "base/json/string_escape.h"
-#include "base/logging.h"
-#include "base/stl_util.h"
-#include "base/strings/string_number_conversions.h"
-#include "base/strings/string_util.h"
-#include "base/strings/stringprintf.h"
-#include "base/strings/utf_string_conversions.h"
-
-namespace base {
-namespace trace_event {
-
-namespace {
-
-size_t GetAllocLength(const char* str) {
- return str ? strlen(str) + 1 : 0;
-}
-
-// Copies |*member| into |*buffer|, sets |*member| to point to this new
-// location, and then advances |*buffer| by the amount written.
-void CopyTraceEventParameter(char** buffer,
- const char** member,
- const char* end) {
- if (*member) {
- size_t written = strlcpy(*buffer, *member, end - *buffer) + 1;
- DCHECK_LE(static_cast<int>(written), end - *buffer);
- *member = *buffer;
- *buffer += written;
- }
-}
-
-// Append |val| as a JSON output value to |*out|.
-void AppendDoubleAsJSON(double val, std::string* out) {
- // FIXME: base/json/json_writer.cc is using the same code,
- // should be made into a common method.
- std::string real;
- if (std::isfinite(val)) {
- real = NumberToString(val);
- // Ensure that the number has a .0 if there's no decimal or 'e'. This
- // makes sure that when we read the JSON back, it's interpreted as a
- // real rather than an int.
- if (real.find('.') == std::string::npos &&
- real.find('e') == std::string::npos &&
- real.find('E') == std::string::npos) {
- real.append(".0");
- }
- // The JSON spec requires that non-integer values in the range (-1,1)
- // have a zero before the decimal point - ".52" is not valid, "0.52" is.
- if (real[0] == '.') {
- real.insert(0, "0");
- } else if (real.length() > 1 && real[0] == '-' && real[1] == '.') {
- // "-.1" bad "-0.1" good
- real.insert(1, "0");
- }
- } else if (std::isnan(val)) {
- // The JSON spec doesn't allow NaN and Infinity (since these are
- // objects in EcmaScript). Use strings instead.
- real = "\"NaN\"";
- } else if (val < 0) {
- real = "\"-Infinity\"";
- } else {
- real = "\"Infinity\"";
- }
- StringAppendF(out, "%s", real.c_str());
-}
-
-const char* TypeToString(char arg_type) {
- switch (arg_type) {
- case TRACE_VALUE_TYPE_INT:
- return "int";
- case TRACE_VALUE_TYPE_UINT:
- return "uint";
- case TRACE_VALUE_TYPE_DOUBLE:
- return "double";
- case TRACE_VALUE_TYPE_BOOL:
- return "bool";
- case TRACE_VALUE_TYPE_POINTER:
- return "pointer";
- case TRACE_VALUE_TYPE_STRING:
- return "string";
- case TRACE_VALUE_TYPE_COPY_STRING:
- return "copy_string";
- case TRACE_VALUE_TYPE_CONVERTABLE:
- return "convertable";
- default:
- NOTREACHED();
- return "UNKNOWN_TYPE";
- }
-}
-
-void AppendValueDebugString(const TraceArguments& args,
- size_t idx,
- std::string* out) {
- *out += (args.names()[idx] ? args.names()[idx] : "NULL_NAME");
- *out += "=";
- *out += TypeToString(args.types()[idx]);
- *out += "(";
- args.values()[idx].AppendAsJSON(args.types()[idx], out);
- *out += ")";
-}
-
-} // namespace
-
-void StringStorage::Reset(size_t alloc_size) {
- if (!alloc_size) {
- if (data_)
- ::free(data_);
- data_ = nullptr;
- } else if (!data_ || alloc_size != data_->size) {
- data_ = static_cast<Data*>(::realloc(data_, sizeof(size_t) + alloc_size));
- data_->size = alloc_size;
- }
-}
-
-bool StringStorage::Contains(const TraceArguments& args) const {
- for (size_t n = 0; n < args.size(); ++n) {
- if (args.types()[n] == TRACE_VALUE_TYPE_COPY_STRING &&
- !Contains(args.values()[n].as_string)) {
- return false;
- }
- }
- return true;
-}
-
-static_assert(
- std::is_pod<TraceValue>::value,
- "TraceValue must be plain-old-data type for performance reasons!");
-
-void TraceValue::AppendAsJSON(unsigned char type, std::string* out) const {
- switch (type) {
- case TRACE_VALUE_TYPE_BOOL:
- *out += this->as_bool ? "true" : "false";
- break;
- case TRACE_VALUE_TYPE_UINT:
- StringAppendF(out, "%" PRIu64, static_cast<uint64_t>(this->as_uint));
- break;
- case TRACE_VALUE_TYPE_INT:
- StringAppendF(out, "%" PRId64, static_cast<int64_t>(this->as_int));
- break;
- case TRACE_VALUE_TYPE_DOUBLE:
- AppendDoubleAsJSON(this->as_double, out);
- break;
- case TRACE_VALUE_TYPE_POINTER:
- // JSON only supports double and int numbers.
- // So as not to lose bits from a 64-bit pointer, output as a hex string.
- StringAppendF(
- out, "\"0x%" PRIx64 "\"",
- static_cast<uint64_t>(reinterpret_cast<uintptr_t>(this->as_pointer)));
- break;
- case TRACE_VALUE_TYPE_STRING:
- case TRACE_VALUE_TYPE_COPY_STRING:
- EscapeJSONString(this->as_string ? this->as_string : "NULL", true, out);
- break;
- case TRACE_VALUE_TYPE_CONVERTABLE:
- this->as_convertable->AppendAsTraceFormat(out);
- break;
- default:
- NOTREACHED() << "Don't know how to print this value";
- break;
- }
-}
-
-TraceArguments& TraceArguments::operator=(TraceArguments&& other) noexcept {
- if (this != &other) {
- this->~TraceArguments();
- new (this) TraceArguments(std::move(other));
- }
- return *this;
-}
-
-TraceArguments::TraceArguments(int num_args,
- const char* const* arg_names,
- const unsigned char* arg_types,
- const unsigned long long* arg_values) {
- if (num_args > static_cast<int>(kMaxSize))
- num_args = static_cast<int>(kMaxSize);
-
- 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];
- values_[n].as_uint = arg_values[n];
- }
-}
-
-void TraceArguments::Reset() {
- for (size_t n = 0; n < size_; ++n) {
- if (types_[n] == TRACE_VALUE_TYPE_CONVERTABLE)
- delete values_[n].as_convertable;
- }
- size_ = 0;
-}
-
-void TraceArguments::CopyStringsTo(StringStorage* storage,
- bool copy_all_strings,
- const char** extra_string1,
- const char** extra_string2) {
- // First, compute total allocation size.
- size_t alloc_size = 0;
-
- if (copy_all_strings) {
- alloc_size +=
- GetAllocLength(*extra_string1) + GetAllocLength(*extra_string2);
- for (size_t n = 0; n < size_; ++n)
- alloc_size += GetAllocLength(names_[n]);
- }
- for (size_t n = 0; n < size_; ++n) {
- if (copy_all_strings && types_[n] == TRACE_VALUE_TYPE_STRING)
- types_[n] = TRACE_VALUE_TYPE_COPY_STRING;
- if (types_[n] == TRACE_VALUE_TYPE_COPY_STRING)
- alloc_size += GetAllocLength(values_[n].as_string);
- }
-
- if (alloc_size) {
- storage->Reset(alloc_size);
- char* ptr = storage->data();
- const char* end = ptr + alloc_size;
- if (copy_all_strings) {
- CopyTraceEventParameter(&ptr, extra_string1, end);
- CopyTraceEventParameter(&ptr, extra_string2, end);
- for (size_t n = 0; n < size_; ++n)
- CopyTraceEventParameter(&ptr, &names_[n], end);
- }
- for (size_t n = 0; n < size_; ++n) {
- if (types_[n] == TRACE_VALUE_TYPE_COPY_STRING)
- CopyTraceEventParameter(&ptr, &values_[n].as_string, end);
- }
-#if DCHECK_IS_ON()
- DCHECK_EQ(end, ptr) << "Overrun by " << ptr - end;
- if (copy_all_strings) {
- if (extra_string1 && *extra_string1)
- DCHECK(storage->Contains(*extra_string1));
- if (extra_string2 && *extra_string2)
- DCHECK(storage->Contains(*extra_string2));
- for (size_t n = 0; n < size_; ++n)
- DCHECK(storage->Contains(names_[n]));
- }
- for (size_t n = 0; n < size_; ++n) {
- if (types_[n] == TRACE_VALUE_TYPE_COPY_STRING)
- DCHECK(storage->Contains(values_[n].as_string));
- }
-#endif // DCHECK_IS_ON()
- } else {
- storage->Reset();
- }
-}
-
-void TraceArguments::AppendDebugString(std::string* out) {
- *out += "TraceArguments(";
- for (size_t n = 0; n < size_; ++n) {
- if (n > 0)
- *out += ", ";
- AppendValueDebugString(*this, n, out);
- }
- *out += ")";
-}
-
-} // namespace trace_event
-} // namespace base
diff --git a/chromium/base/trace_event/trace_arguments.h b/chromium/base/trace_event/trace_arguments.h
deleted file mode 100644
index 6a9af808e4c..00000000000
--- a/chromium/base/trace_event/trace_arguments.h
+++ /dev/null
@@ -1,671 +0,0 @@
-// 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);
-
- std::string ToString() const {
- std::string result;
- AppendAsTraceFormat(&result);
- return result;
- }
-
- 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;
-
- private:
- // 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_
diff --git a/chromium/base/trace_event/trace_arguments_unittest.cc b/chromium/base/trace_event/trace_arguments_unittest.cc
deleted file mode 100644
index a550cd616c4..00000000000
--- a/chromium/base/trace_event/trace_arguments_unittest.cc
+++ /dev/null
@@ -1,472 +0,0 @@
-// 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.
-
-#include "base/trace_event/trace_arguments.h"
-
-#include <gtest/gtest.h>
-#include <string>
-
-namespace base {
-namespace trace_event {
-
-namespace {
-
-// Simple convertable that holds a string to append to the trace,
-// and can also write to a boolean flag on destruction.
-class MyConvertable : public ConvertableToTraceFormat {
- public:
- MyConvertable(const char* text, bool* destroy_flag = nullptr)
- : text_(text), destroy_flag_(destroy_flag) {}
- ~MyConvertable() override {
- if (destroy_flag_)
- *destroy_flag_ = true;
- }
- void AppendAsTraceFormat(std::string* out) const override { *out += text_; }
- const char* text() const { return text_; }
-
- private:
- const char* text_;
- bool* destroy_flag_;
-};
-
-} // namespace
-
-TEST(TraceArguments, StringStorageDefaultConstruction) {
- StringStorage storage;
- EXPECT_TRUE(storage.empty());
- EXPECT_FALSE(storage.data());
- EXPECT_EQ(0U, storage.size());
-}
-
-TEST(TraceArguments, StringStorageConstructionWithSize) {
- const size_t kSize = 128;
- StringStorage storage(kSize);
- EXPECT_FALSE(storage.empty());
- EXPECT_TRUE(storage.data());
- EXPECT_EQ(kSize, storage.size());
- EXPECT_EQ(storage.data(), storage.begin());
- EXPECT_EQ(storage.data() + kSize, storage.end());
-}
-
-TEST(TraceArguments, StringStorageReset) {
- StringStorage storage(128);
- EXPECT_FALSE(storage.empty());
-
- storage.Reset();
- EXPECT_TRUE(storage.empty());
- EXPECT_FALSE(storage.data());
- EXPECT_EQ(0u, storage.size());
-}
-
-TEST(TraceArguments, StringStorageResetWithSize) {
- StringStorage storage;
- EXPECT_TRUE(storage.empty());
-
- const size_t kSize = 128;
- storage.Reset(kSize);
- EXPECT_FALSE(storage.empty());
- EXPECT_TRUE(storage.data());
- EXPECT_EQ(kSize, storage.size());
- EXPECT_EQ(storage.data(), storage.begin());
- EXPECT_EQ(storage.data() + kSize, storage.end());
-}
-
-TEST(TraceArguments, StringStorageEstimateTraceMemoryOverhead) {
- StringStorage storage;
- EXPECT_EQ(0u, storage.EstimateTraceMemoryOverhead());
-
- const size_t kSize = 128;
- storage.Reset(kSize);
- EXPECT_EQ(sizeof(size_t) + kSize, storage.EstimateTraceMemoryOverhead());
-}
-
-static void CheckJSONFor(TraceValue v, char type, const char* expected) {
- std::string out;
- v.AppendAsJSON(type, &out);
- EXPECT_STREQ(expected, out.c_str());
-}
-
-TEST(TraceArguments, TraceValueAppendAsJSON) {
- TraceValue v;
-
- v.Init(-1024);
- CheckJSONFor(v, TRACE_VALUE_TYPE_INT, "-1024");
- v.Init(1024ULL);
- CheckJSONFor(v, TRACE_VALUE_TYPE_UINT, "1024");
- v.Init(3.1415926535);
- CheckJSONFor(v, TRACE_VALUE_TYPE_DOUBLE, "3.1415926535");
- v.Init(true);
- CheckJSONFor(v, TRACE_VALUE_TYPE_BOOL, "true");
- v.Init(false);
- CheckJSONFor(v, TRACE_VALUE_TYPE_BOOL, "false");
- v.Init("Some \"nice\" String");
- CheckJSONFor(v, TRACE_VALUE_TYPE_STRING, "\"Some \\\"nice\\\" String\"");
- CheckJSONFor(v, TRACE_VALUE_TYPE_COPY_STRING, "\"Some \\\"nice\\\" String\"");
-}
-
-TEST(TraceArguments, DefaultConstruction) {
- TraceArguments args;
- EXPECT_EQ(0U, args.size());
-}
-
-TEST(TraceArguments, ConstructorSingleInteger) {
- TraceArguments args("foo_int", int(10));
- EXPECT_EQ(1U, args.size());
- EXPECT_EQ(TRACE_VALUE_TYPE_INT, args.types()[0]);
- EXPECT_STREQ("foo_int", args.names()[0]);
- EXPECT_EQ(10, args.values()[0].as_int);
-}
-
-TEST(TraceArguments, ConstructorSingleFloat) {
- TraceArguments args("foo_pi", float(3.1415));
- double expected = float(3.1415);
- EXPECT_EQ(1U, args.size());
- EXPECT_EQ(TRACE_VALUE_TYPE_DOUBLE, args.types()[0]);
- EXPECT_STREQ("foo_pi", args.names()[0]);
- EXPECT_EQ(expected, args.values()[0].as_double);
-}
-
-TEST(TraceArguments, ConstructorSingleNoCopyString) {
- const char kText[] = "Persistent string";
- TraceArguments args("foo_cstring", kText);
- EXPECT_EQ(1U, args.size());
- EXPECT_EQ(TRACE_VALUE_TYPE_STRING, args.types()[0]);
- EXPECT_STREQ("foo_cstring", args.names()[0]);
- EXPECT_EQ(kText, args.values()[0].as_string);
-}
-
-TEST(TraceArguments, ConstructorSingleStdString) {
- std::string text = "Non-persistent string";
- TraceArguments args("foo_stdstring", text);
- EXPECT_EQ(1U, args.size());
- EXPECT_EQ(TRACE_VALUE_TYPE_COPY_STRING, args.types()[0]);
- EXPECT_STREQ("foo_stdstring", args.names()[0]);
- EXPECT_EQ(text.c_str(), args.values()[0].as_string);
-}
-
-TEST(TraceArguments, ConstructorSingleTraceStringWithCopy) {
- const char kText[] = "Persistent string #2";
- TraceArguments args("foo_tracestring", TraceStringWithCopy(kText));
- EXPECT_EQ(1U, args.size());
- EXPECT_EQ(TRACE_VALUE_TYPE_COPY_STRING, args.types()[0]);
- EXPECT_STREQ("foo_tracestring", args.names()[0]);
- EXPECT_EQ(kText, args.values()[0].as_string);
-}
-
-TEST(TraceArguments, ConstructorSinglePointer) {
- bool destroy_flag = false;
- {
- // Simple class that can set a boolean flag on destruction.
- class Foo {
- public:
- Foo(bool* destroy_flag) : destroy_flag_(destroy_flag) {}
- ~Foo() {
- if (destroy_flag_)
- *destroy_flag_ = true;
- }
-
- private:
- bool* destroy_flag_;
- };
- auto foo = std::make_unique<Foo>(&destroy_flag);
- EXPECT_FALSE(destroy_flag);
- // This test also verifies that the object is not destroyed by the
- // TraceArguments destructor. This should only be possible for
- // TRACE_VALUE_TYPE_CONVERTABLE instances.
- {
- TraceArguments args("foo_pointer", foo.get());
- EXPECT_EQ(1U, args.size());
- EXPECT_EQ(TRACE_VALUE_TYPE_POINTER, args.types()[0]);
- EXPECT_STREQ("foo_pointer", args.names()[0]);
- EXPECT_EQ(foo.get(), args.values()[0].as_pointer);
- EXPECT_FALSE(destroy_flag);
- } // Calls TraceArguments destructor.
- EXPECT_FALSE(destroy_flag);
- } // Calls Foo destructor.
- EXPECT_TRUE(destroy_flag);
-}
-
-TEST(TraceArguments, ConstructorSingleConvertable) {
- bool destroy_flag = false;
- const char kText[] = "Text for MyConvertable instance";
- MyConvertable* ptr = new MyConvertable(kText, &destroy_flag);
-
- // This test also verifies that the MyConvertable instance is properly
- // destroyed when the TraceArguments destructor is called.
- EXPECT_FALSE(destroy_flag);
- {
- TraceArguments args("foo_convertable", std::unique_ptr<MyConvertable>(ptr));
- EXPECT_EQ(1U, args.size());
- EXPECT_EQ(TRACE_VALUE_TYPE_CONVERTABLE, args.types()[0]);
- EXPECT_STREQ("foo_convertable", args.names()[0]);
- EXPECT_EQ(ptr, args.values()[0].as_convertable);
- EXPECT_FALSE(destroy_flag);
- } // Calls TraceArguments destructor.
- EXPECT_TRUE(destroy_flag);
-}
-
-TEST(TraceArguments, ConstructorWithTwoArguments) {
- const char kText1[] = "First argument";
- const char kText2[] = "Second argument";
- bool destroy_flag = false;
-
- {
- MyConvertable* ptr = new MyConvertable(kText2, &destroy_flag);
- TraceArguments args1("foo_arg1_cstring", kText1, "foo_arg2_convertable",
- std::unique_ptr<MyConvertable>(ptr));
- EXPECT_EQ(2U, args1.size());
- EXPECT_STREQ("foo_arg1_cstring", args1.names()[0]);
- EXPECT_STREQ("foo_arg2_convertable", args1.names()[1]);
- EXPECT_EQ(TRACE_VALUE_TYPE_STRING, args1.types()[0]);
- EXPECT_EQ(TRACE_VALUE_TYPE_CONVERTABLE, args1.types()[1]);
- EXPECT_EQ(kText1, args1.values()[0].as_string);
- EXPECT_EQ(ptr, args1.values()[1].as_convertable);
- EXPECT_FALSE(destroy_flag);
- } // calls |args1| destructor. Should delete |ptr|.
- EXPECT_TRUE(destroy_flag);
-}
-
-TEST(TraceArguments, ConstructorLegacyNoConvertables) {
- const char* const kNames[3] = {"legacy_arg1", "legacy_arg2", "legacy_arg3"};
- const unsigned char kTypes[3] = {
- TRACE_VALUE_TYPE_INT,
- TRACE_VALUE_TYPE_STRING,
- TRACE_VALUE_TYPE_POINTER,
- };
- static const char kText[] = "Some text";
- const unsigned long long kValues[3] = {
- 1000042ULL,
- reinterpret_cast<unsigned long long>(kText),
- reinterpret_cast<unsigned long long>(kText + 2),
- };
- TraceArguments args(3, kNames, kTypes, kValues);
- // Check that only the first kMaxSize arguments are taken!
- EXPECT_EQ(2U, args.size());
- EXPECT_STREQ(kNames[0], args.names()[0]);
- EXPECT_STREQ(kNames[1], args.names()[1]);
- EXPECT_EQ(TRACE_VALUE_TYPE_INT, args.types()[0]);
- EXPECT_EQ(TRACE_VALUE_TYPE_STRING, args.types()[1]);
- EXPECT_EQ(kValues[0], args.values()[0].as_uint);
- EXPECT_EQ(kText, args.values()[1].as_string);
-};
-
-TEST(TraceArguments, ConstructorLegacyWithConvertables) {
- const char* const kNames[3] = {"legacy_arg1", "legacy_arg2", "legacy_arg3"};
- const unsigned char kTypes[3] = {
- TRACE_VALUE_TYPE_CONVERTABLE,
- TRACE_VALUE_TYPE_CONVERTABLE,
- TRACE_VALUE_TYPE_CONVERTABLE,
- };
- std::unique_ptr<MyConvertable> convertables[3] = {
- std::make_unique<MyConvertable>("First one"),
- std::make_unique<MyConvertable>("Second one"),
- std::make_unique<MyConvertable>("Third one"),
- };
- TraceArguments args(3, kNames, kTypes, nullptr, convertables);
- // Check that only the first kMaxSize arguments are taken!
- EXPECT_EQ(2U, args.size());
- EXPECT_STREQ(kNames[0], args.names()[0]);
- EXPECT_STREQ(kNames[1], args.names()[1]);
- EXPECT_EQ(TRACE_VALUE_TYPE_CONVERTABLE, args.types()[0]);
- EXPECT_EQ(TRACE_VALUE_TYPE_CONVERTABLE, args.types()[1]);
- // Check that only the first two items were moved to |args|.
- EXPECT_FALSE(convertables[0].get());
- EXPECT_FALSE(convertables[1].get());
- EXPECT_TRUE(convertables[2].get());
-}
-
-TEST(TraceArguments, MoveConstruction) {
- const char kText1[] = "First argument";
- const char kText2[] = "Second argument";
- bool destroy_flag = false;
-
- {
- MyConvertable* ptr = new MyConvertable(kText2, &destroy_flag);
- TraceArguments args1("foo_arg1_cstring", kText1, "foo_arg2_convertable",
- std::unique_ptr<MyConvertable>(ptr));
- EXPECT_EQ(2U, args1.size());
- EXPECT_STREQ("foo_arg1_cstring", args1.names()[0]);
- EXPECT_STREQ("foo_arg2_convertable", args1.names()[1]);
- EXPECT_EQ(TRACE_VALUE_TYPE_STRING, args1.types()[0]);
- EXPECT_EQ(TRACE_VALUE_TYPE_CONVERTABLE, args1.types()[1]);
- EXPECT_EQ(kText1, args1.values()[0].as_string);
- EXPECT_EQ(ptr, args1.values()[1].as_convertable);
-
- {
- TraceArguments args2(std::move(args1));
- EXPECT_FALSE(destroy_flag);
-
- // |args1| is now empty.
- EXPECT_EQ(0U, args1.size());
-
- // Check that everything was transferred to |args2|.
- EXPECT_EQ(2U, args2.size());
- EXPECT_STREQ("foo_arg1_cstring", args2.names()[0]);
- EXPECT_STREQ("foo_arg2_convertable", args2.names()[1]);
- EXPECT_EQ(TRACE_VALUE_TYPE_STRING, args2.types()[0]);
- EXPECT_EQ(TRACE_VALUE_TYPE_CONVERTABLE, args2.types()[1]);
- EXPECT_EQ(kText1, args2.values()[0].as_string);
- EXPECT_EQ(ptr, args2.values()[1].as_convertable);
- } // Calls |args2| destructor. Should delete |ptr|.
- EXPECT_TRUE(destroy_flag);
- destroy_flag = false;
- } // Calls |args1| destructor. Should not delete |ptr|.
- EXPECT_FALSE(destroy_flag);
-}
-
-TEST(TraceArguments, MoveAssignment) {
- const char kText1[] = "First argument";
- const char kText2[] = "Second argument";
- bool destroy_flag = false;
-
- {
- MyConvertable* ptr = new MyConvertable(kText2, &destroy_flag);
- TraceArguments args1("foo_arg1_cstring", kText1, "foo_arg2_convertable",
- std::unique_ptr<MyConvertable>(ptr));
- EXPECT_EQ(2U, args1.size());
- EXPECT_STREQ("foo_arg1_cstring", args1.names()[0]);
- EXPECT_STREQ("foo_arg2_convertable", args1.names()[1]);
- EXPECT_EQ(TRACE_VALUE_TYPE_STRING, args1.types()[0]);
- EXPECT_EQ(TRACE_VALUE_TYPE_CONVERTABLE, args1.types()[1]);
- EXPECT_EQ(kText1, args1.values()[0].as_string);
- EXPECT_EQ(ptr, args1.values()[1].as_convertable);
-
- {
- TraceArguments args2;
-
- args2 = std::move(args1);
- EXPECT_FALSE(destroy_flag);
-
- // |args1| is now empty.
- EXPECT_EQ(0U, args1.size());
-
- // Check that everything was transferred to |args2|.
- EXPECT_EQ(2U, args2.size());
- EXPECT_STREQ("foo_arg1_cstring", args2.names()[0]);
- EXPECT_STREQ("foo_arg2_convertable", args2.names()[1]);
- EXPECT_EQ(TRACE_VALUE_TYPE_STRING, args2.types()[0]);
- EXPECT_EQ(TRACE_VALUE_TYPE_CONVERTABLE, args2.types()[1]);
- EXPECT_EQ(kText1, args2.values()[0].as_string);
- EXPECT_EQ(ptr, args2.values()[1].as_convertable);
- } // Calls |args2| destructor. Should delete |ptr|.
- EXPECT_TRUE(destroy_flag);
- destroy_flag = false;
- } // Calls |args1| destructor. Should not delete |ptr|.
- EXPECT_FALSE(destroy_flag);
-}
-
-TEST(TraceArguments, Reset) {
- bool destroy_flag = false;
- {
- TraceArguments args(
- "foo_arg1", "Hello", "foo_arg2",
- std::make_unique<MyConvertable>("World", &destroy_flag));
-
- EXPECT_EQ(2U, args.size());
- EXPECT_FALSE(destroy_flag);
- args.Reset();
- EXPECT_EQ(0U, args.size());
- EXPECT_TRUE(destroy_flag);
- destroy_flag = false;
- } // Calls |args| destructor. Should not delete twice.
- EXPECT_FALSE(destroy_flag);
-}
-
-TEST(TraceArguments, CopyStringsTo_NoStrings) {
- StringStorage storage;
-
- TraceArguments args("arg1", 10, "arg2", 42);
- args.CopyStringsTo(&storage, false, nullptr, nullptr);
- EXPECT_TRUE(storage.empty());
- EXPECT_EQ(0U, storage.size());
-}
-
-TEST(TraceArguments, CopyStringsTo_OnlyArgs) {
- StringStorage storage;
-
- TraceArguments args("arg1", TraceStringWithCopy("Hello"), "arg2",
- TraceStringWithCopy("World"));
-
- const char kExtra1[] = "extra1";
- const char kExtra2[] = "extra2";
- const char* extra1 = kExtra1;
- const char* extra2 = kExtra2;
-
- // Types should be copyable strings.
- EXPECT_EQ(TRACE_VALUE_TYPE_COPY_STRING, args.types()[0]);
- EXPECT_EQ(TRACE_VALUE_TYPE_COPY_STRING, args.types()[1]);
-
- args.CopyStringsTo(&storage, false, &extra1, &extra2);
-
- // Storage should be allocated.
- EXPECT_TRUE(storage.data());
- EXPECT_NE(0U, storage.size());
-
- // Types should not be changed.
- EXPECT_EQ(TRACE_VALUE_TYPE_COPY_STRING, args.types()[0]);
- EXPECT_EQ(TRACE_VALUE_TYPE_COPY_STRING, args.types()[1]);
-
- // names should not be copied.
- EXPECT_FALSE(storage.Contains(args.names()[0]));
- EXPECT_FALSE(storage.Contains(args.names()[1]));
- EXPECT_STREQ("arg1", args.names()[0]);
- EXPECT_STREQ("arg2", args.names()[1]);
-
- // strings should be copied.
- EXPECT_TRUE(storage.Contains(args.values()[0].as_string));
- EXPECT_TRUE(storage.Contains(args.values()[1].as_string));
- EXPECT_STREQ("Hello", args.values()[0].as_string);
- EXPECT_STREQ("World", args.values()[1].as_string);
-
- // |extra1| and |extra2| should not be copied.
- EXPECT_EQ(kExtra1, extra1);
- EXPECT_EQ(kExtra2, extra2);
-}
-
-TEST(TraceArguments, CopyStringsTo_Everything) {
- StringStorage storage;
-
- TraceArguments args("arg1", "Hello", "arg2", "World");
- const char kExtra1[] = "extra1";
- const char kExtra2[] = "extra2";
- const char* extra1 = kExtra1;
- const char* extra2 = kExtra2;
-
- // Types should be normal strings.
- EXPECT_EQ(TRACE_VALUE_TYPE_STRING, args.types()[0]);
- EXPECT_EQ(TRACE_VALUE_TYPE_STRING, args.types()[1]);
-
- args.CopyStringsTo(&storage, true, &extra1, &extra2);
-
- // Storage should be allocated.
- EXPECT_TRUE(storage.data());
- EXPECT_NE(0U, storage.size());
-
- // Types should be changed to copyable strings.
- EXPECT_EQ(TRACE_VALUE_TYPE_COPY_STRING, args.types()[0]);
- EXPECT_EQ(TRACE_VALUE_TYPE_COPY_STRING, args.types()[1]);
-
- // names should be copied.
- EXPECT_TRUE(storage.Contains(args.names()[0]));
- EXPECT_TRUE(storage.Contains(args.names()[1]));
- EXPECT_STREQ("arg1", args.names()[0]);
- EXPECT_STREQ("arg2", args.names()[1]);
-
- // strings should be copied.
- EXPECT_TRUE(storage.Contains(args.values()[0].as_string));
- EXPECT_TRUE(storage.Contains(args.values()[1].as_string));
- EXPECT_STREQ("Hello", args.values()[0].as_string);
- EXPECT_STREQ("World", args.values()[1].as_string);
-
- // |extra1| and |extra2| should be copied.
- EXPECT_NE(kExtra1, extra1);
- EXPECT_NE(kExtra2, extra2);
- EXPECT_TRUE(storage.Contains(extra1));
- EXPECT_TRUE(storage.Contains(extra2));
- EXPECT_STREQ(kExtra1, extra1);
- EXPECT_STREQ(kExtra2, extra2);
-}
-
-} // namespace trace_event
-} // namespace base
diff --git a/chromium/base/trace_event/trace_event.h b/chromium/base/trace_event/trace_event.h
index 53d8ca24d06..9bac00617f8 100644
--- a/chromium/base/trace_event/trace_event.h
+++ b/chromium/base/trace_event/trace_event.h
@@ -22,7 +22,6 @@
#include "base/trace_event/builtin_categories.h"
#include "base/trace_event/common/trace_event_common.h"
#include "base/trace_event/heap_profiler.h"
-#include "base/trace_event/trace_arguments.h"
#include "base/trace_event/trace_category.h"
#include "base/trace_event/trace_event_system_stats_monitor.h"
#include "base/trace_event/trace_log.h"
@@ -30,7 +29,8 @@
// By default, const char* argument values are assumed to have long-lived scope
// and will not be copied. Use this macro to force a const char* to be copied.
-#define TRACE_STR_COPY(str) ::base::trace_event::TraceStringWithCopy(str)
+#define TRACE_STR_COPY(str) \
+ trace_event_internal::TraceStringWithCopy(str)
// DEPRECATED: do not use: Consider using the TRACE_ID_LOCAL macro instead. By
// default, uint64_t ID argument values are not mangled with the Process ID in
@@ -659,86 +659,113 @@ class BASE_EXPORT TraceID {
unsigned int id_flags_ = TRACE_EVENT_FLAG_HAS_ID;
};
-// These functions all internally call
-// base::trace_event::TraceLog::GetInstance() then call the method with the same
-// name on it. This is used to reduce the generated machine code at each
-// TRACE_EVENTXXX macro call.
-
-base::trace_event::TraceEventHandle BASE_EXPORT
-AddTraceEvent(char phase,
- const unsigned char* category_group_enabled,
- const char* name,
- const char* scope,
- unsigned long long id,
- base::trace_event::TraceArguments* args,
- unsigned int flags);
-
-base::trace_event::TraceEventHandle BASE_EXPORT
-AddTraceEventWithBindId(char phase,
- const unsigned char* category_group_enabled,
- const char* name,
- const char* scope,
- unsigned long long id,
- unsigned long long bind_id,
- base::trace_event::TraceArguments* args,
- unsigned int flags);
+// Simple union to store various types as unsigned long long.
+union TraceValueUnion {
+ bool as_bool;
+ unsigned long long as_uint;
+ long long as_int;
+ double as_double;
+ const void* as_pointer;
+ const char* as_string;
+};
-base::trace_event::TraceEventHandle BASE_EXPORT
-AddTraceEventWithProcessId(char phase,
- const unsigned char* category_group_enabled,
- const char* name,
- const char* scope,
- unsigned long long id,
- int process_id,
- base::trace_event::TraceArguments* args,
- unsigned int flags);
+// Simple container for const char* that should be copied instead of retained.
+class TraceStringWithCopy {
+ public:
+ explicit TraceStringWithCopy(const char* str) : str_(str) {}
+ const char* str() const { return str_; }
+ private:
+ const char* str_;
+};
-base::trace_event::TraceEventHandle BASE_EXPORT
-AddTraceEventWithThreadIdAndTimestamp(
- char phase,
- const unsigned char* category_group_enabled,
- const char* name,
- const char* scope,
- unsigned long long id,
- int thread_id,
- const base::TimeTicks& timestamp,
- base::trace_event::TraceArguments* args,
- unsigned int flags);
+// Define SetTraceValue for each allowed type. It stores the type and
+// value in the return arguments. This allows this API to avoid declaring any
+// structures so that it is portable to third_party libraries.
+#define INTERNAL_DECLARE_SET_TRACE_VALUE(actual_type, \
+ arg_expression, \
+ union_member, \
+ value_type_id) \
+ static inline void SetTraceValue( \
+ actual_type arg, \
+ unsigned char* type, \
+ unsigned long long* value) { \
+ TraceValueUnion type_value; \
+ type_value.union_member = arg_expression; \
+ *type = value_type_id; \
+ *value = type_value.as_uint; \
+ }
+// Simpler form for int types that can be safely casted.
+#define INTERNAL_DECLARE_SET_TRACE_VALUE_INT(actual_type, \
+ value_type_id) \
+ static inline void SetTraceValue( \
+ actual_type arg, \
+ unsigned char* type, \
+ unsigned long long* value) { \
+ *type = value_type_id; \
+ *value = static_cast<unsigned long long>(arg); \
+ }
-base::trace_event::TraceEventHandle BASE_EXPORT
-AddTraceEventWithThreadIdAndTimestamp(
- char phase,
- const unsigned char* category_group_enabled,
- const char* name,
- const char* scope,
- unsigned long long id,
- unsigned long long bind_id,
- int thread_id,
- const base::TimeTicks& timestamp,
- base::trace_event::TraceArguments* args,
- unsigned int flags);
+INTERNAL_DECLARE_SET_TRACE_VALUE_INT(unsigned long long, TRACE_VALUE_TYPE_UINT)
+INTERNAL_DECLARE_SET_TRACE_VALUE_INT(unsigned long, TRACE_VALUE_TYPE_UINT)
+INTERNAL_DECLARE_SET_TRACE_VALUE_INT(unsigned int, TRACE_VALUE_TYPE_UINT)
+INTERNAL_DECLARE_SET_TRACE_VALUE_INT(unsigned short, TRACE_VALUE_TYPE_UINT)
+INTERNAL_DECLARE_SET_TRACE_VALUE_INT(unsigned char, TRACE_VALUE_TYPE_UINT)
+INTERNAL_DECLARE_SET_TRACE_VALUE_INT(long long, TRACE_VALUE_TYPE_INT)
+INTERNAL_DECLARE_SET_TRACE_VALUE_INT(long, TRACE_VALUE_TYPE_INT)
+INTERNAL_DECLARE_SET_TRACE_VALUE_INT(int, TRACE_VALUE_TYPE_INT)
+INTERNAL_DECLARE_SET_TRACE_VALUE_INT(short, TRACE_VALUE_TYPE_INT)
+INTERNAL_DECLARE_SET_TRACE_VALUE_INT(signed char, TRACE_VALUE_TYPE_INT)
+INTERNAL_DECLARE_SET_TRACE_VALUE(bool, arg, as_bool, TRACE_VALUE_TYPE_BOOL)
+INTERNAL_DECLARE_SET_TRACE_VALUE(double, arg, as_double,
+ TRACE_VALUE_TYPE_DOUBLE)
+INTERNAL_DECLARE_SET_TRACE_VALUE(const void*, arg, as_pointer,
+ TRACE_VALUE_TYPE_POINTER)
+INTERNAL_DECLARE_SET_TRACE_VALUE(const char*, arg, as_string,
+ TRACE_VALUE_TYPE_STRING)
+INTERNAL_DECLARE_SET_TRACE_VALUE(const TraceStringWithCopy&, arg.str(),
+ as_string, TRACE_VALUE_TYPE_COPY_STRING)
+
+#undef INTERNAL_DECLARE_SET_TRACE_VALUE
+#undef INTERNAL_DECLARE_SET_TRACE_VALUE_INT
+
+// std::string version of SetTraceValue so that trace arguments can be strings.
+static inline void SetTraceValue(const std::string& arg,
+ unsigned char* type,
+ unsigned long long* value) {
+ TraceValueUnion type_value;
+ type_value.as_string = arg.c_str();
+ *type = TRACE_VALUE_TYPE_COPY_STRING;
+ *value = type_value.as_uint;
+}
-void BASE_EXPORT AddMetadataEvent(const unsigned char* category_group_enabled,
- const char* name,
- base::trace_event::TraceArguments* args,
- unsigned int flags);
+// base::Time, base::TimeTicks, etc. versions of SetTraceValue to make it easier
+// to trace these types.
+static inline void SetTraceValue(const base::Time arg,
+ unsigned char* type,
+ unsigned long long* value) {
+ *type = TRACE_VALUE_TYPE_INT;
+ *value = arg.ToInternalValue();
+}
-int BASE_EXPORT GetNumTracesRecorded();
+static inline void SetTraceValue(const base::TimeTicks arg,
+ unsigned char* type,
+ unsigned long long* value) {
+ *type = TRACE_VALUE_TYPE_INT;
+ *value = arg.ToInternalValue();
+}
-void BASE_EXPORT
-UpdateTraceEventDuration(const unsigned char* category_group_enabled,
- const char* name,
- base::trace_event::TraceEventHandle handle);
+static inline void SetTraceValue(const base::ThreadTicks arg,
+ unsigned char* type,
+ unsigned long long* value) {
+ *type = TRACE_VALUE_TYPE_INT;
+ *value = arg.ToInternalValue();
+}
-void BASE_EXPORT
-UpdateTraceEventDurationExplicit(const unsigned char* category_group_enabled,
- const char* name,
- base::trace_event::TraceEventHandle handle,
- const base::TimeTicks& now,
- const base::ThreadTicks& thread_now);
+// These functions all internally call
+// base::trace_event::TraceLog::GetInstance() then call the method with the same
+// name on it. This is used to reduce the generated machine code at each
+// TRACE_EVENTXXX macro call.
-// TODO(898794): Remove these functions once all callers have been updated
-// to use base::trace_event::Arguments instead.
base::trace_event::TraceEventHandle BASE_EXPORT
AddTraceEvent(char phase,
const unsigned char* category_group_enabled,
@@ -829,13 +856,51 @@ AddMetadataEvent(const unsigned char* category_group_enabled,
convertable_values,
unsigned int flags);
+int BASE_EXPORT GetNumTracesRecorded();
+
+void BASE_EXPORT
+UpdateTraceEventDuration(const unsigned char* category_group_enabled,
+ const char* name,
+ base::trace_event::TraceEventHandle handle);
+
+void BASE_EXPORT
+UpdateTraceEventDurationExplicit(const unsigned char* category_group_enabled,
+ const char* name,
+ base::trace_event::TraceEventHandle handle,
+ const base::TimeTicks& now,
+ const base::ThreadTicks& thread_now);
+
// These AddTraceEvent and AddTraceEventWithThreadIdAndTimestamp template
// functions are defined here instead of in the macro, because the arg_values
// could be temporary objects, such as std::string. In order to store
// pointers to the internal c_str and pass through to the tracing API,
// the arg_values must live throughout these procedures.
-template <class ARG1_TYPE>
+template <class ARG1_CONVERTABLE_TYPE>
+static inline base::trace_event::TraceEventHandle
+AddTraceEventWithThreadIdAndTimestamp(
+ char phase,
+ const unsigned char* category_group_enabled,
+ const char* name,
+ const char* scope,
+ unsigned long long id,
+ int thread_id,
+ const base::TimeTicks& timestamp,
+ unsigned int flags,
+ unsigned long long bind_id,
+ const char* arg1_name,
+ std::unique_ptr<ARG1_CONVERTABLE_TYPE> arg1_val) {
+ const int num_args = 1;
+ unsigned char arg_types[1] = { TRACE_VALUE_TYPE_CONVERTABLE };
+ std::unique_ptr<base::trace_event::ConvertableToTraceFormat>
+ convertable_values[1] = {std::move(arg1_val)};
+ return TRACE_EVENT_API_ADD_TRACE_EVENT_WITH_THREAD_ID_AND_TIMESTAMP(
+ phase, category_group_enabled, name, scope, id, bind_id, thread_id,
+ timestamp, num_args, &arg1_name, arg_types, NULL, convertable_values,
+ flags);
+}
+
+template <class ARG1_TYPE, class ARG2_CONVERTABLE_TYPE>
static inline base::trace_event::TraceEventHandle
AddTraceEventWithThreadIdAndTimestamp(
char phase,
@@ -848,15 +913,25 @@ AddTraceEventWithThreadIdAndTimestamp(
unsigned int flags,
unsigned long long bind_id,
const char* arg1_name,
- ARG1_TYPE&& arg1_val) {
- base::trace_event::TraceArguments args(arg1_name,
- std::forward<ARG1_TYPE>(arg1_val));
+ const ARG1_TYPE& arg1_val,
+ const char* arg2_name,
+ std::unique_ptr<ARG2_CONVERTABLE_TYPE> arg2_val) {
+ const int num_args = 2;
+ const char* arg_names[2] = { arg1_name, arg2_name };
+
+ unsigned char arg_types[2];
+ unsigned long long arg_values[2];
+ SetTraceValue(arg1_val, &arg_types[0], &arg_values[0]);
+ arg_types[1] = TRACE_VALUE_TYPE_CONVERTABLE;
+ std::unique_ptr<base::trace_event::ConvertableToTraceFormat>
+ convertable_values[2] = {nullptr, std::move(arg2_val)};
return TRACE_EVENT_API_ADD_TRACE_EVENT_WITH_THREAD_ID_AND_TIMESTAMP(
phase, category_group_enabled, name, scope, id, bind_id, thread_id,
- timestamp, &args, flags);
+ timestamp, num_args, arg_names, arg_types, arg_values, convertable_values,
+ flags);
}
-template <class ARG1_TYPE, class ARG2_TYPE>
+template <class ARG1_CONVERTABLE_TYPE, class ARG2_TYPE>
static inline base::trace_event::TraceEventHandle
AddTraceEventWithThreadIdAndTimestamp(
char phase,
@@ -869,15 +944,51 @@ AddTraceEventWithThreadIdAndTimestamp(
unsigned int flags,
unsigned long long bind_id,
const char* arg1_name,
- ARG1_TYPE&& arg1_val,
+ std::unique_ptr<ARG1_CONVERTABLE_TYPE> arg1_val,
const char* arg2_name,
- ARG2_TYPE&& arg2_val) {
- base::trace_event::TraceArguments args(
- arg1_name, std::forward<ARG1_TYPE>(arg1_val), arg2_name,
- std::forward<ARG2_TYPE>(arg2_val));
+ const ARG2_TYPE& arg2_val) {
+ const int num_args = 2;
+ const char* arg_names[2] = { arg1_name, arg2_name };
+
+ unsigned char arg_types[2];
+ unsigned long long arg_values[2];
+ arg_types[0] = TRACE_VALUE_TYPE_CONVERTABLE;
+ arg_values[0] = 0;
+ SetTraceValue(arg2_val, &arg_types[1], &arg_values[1]);
+ std::unique_ptr<base::trace_event::ConvertableToTraceFormat>
+ convertable_values[2] = {std::move(arg1_val), nullptr};
return TRACE_EVENT_API_ADD_TRACE_EVENT_WITH_THREAD_ID_AND_TIMESTAMP(
phase, category_group_enabled, name, scope, id, bind_id, thread_id,
- timestamp, &args, flags);
+ timestamp, num_args, arg_names, arg_types, arg_values, convertable_values,
+ flags);
+}
+
+template <class ARG1_CONVERTABLE_TYPE, class ARG2_CONVERTABLE_TYPE>
+static inline base::trace_event::TraceEventHandle
+AddTraceEventWithThreadIdAndTimestamp(
+ char phase,
+ const unsigned char* category_group_enabled,
+ const char* name,
+ const char* scope,
+ unsigned long long id,
+ int thread_id,
+ const base::TimeTicks& timestamp,
+ unsigned int flags,
+ unsigned long long bind_id,
+ const char* arg1_name,
+ std::unique_ptr<ARG1_CONVERTABLE_TYPE> arg1_val,
+ const char* arg2_name,
+ std::unique_ptr<ARG2_CONVERTABLE_TYPE> arg2_val) {
+ const int num_args = 2;
+ const char* arg_names[2] = { arg1_name, arg2_name };
+ unsigned char arg_types[2] =
+ { TRACE_VALUE_TYPE_CONVERTABLE, TRACE_VALUE_TYPE_CONVERTABLE };
+ std::unique_ptr<base::trace_event::ConvertableToTraceFormat>
+ convertable_values[2] = {std::move(arg1_val), std::move(arg2_val)};
+ return TRACE_EVENT_API_ADD_TRACE_EVENT_WITH_THREAD_ID_AND_TIMESTAMP(
+ phase, category_group_enabled, name, scope, id, bind_id, thread_id,
+ timestamp, num_args, arg_names, arg_types, NULL, convertable_values,
+ flags);
}
static inline base::trace_event::TraceEventHandle
@@ -893,7 +1004,7 @@ AddTraceEventWithThreadIdAndTimestamp(
unsigned long long bind_id) {
return TRACE_EVENT_API_ADD_TRACE_EVENT_WITH_THREAD_ID_AND_TIMESTAMP(
phase, category_group_enabled, name, scope, id, bind_id, thread_id,
- timestamp, nullptr, flags);
+ timestamp, kZeroNumArgs, NULL, NULL, NULL, NULL, flags);
}
static inline base::trace_event::TraceEventHandle AddTraceEvent(
@@ -911,7 +1022,113 @@ static inline base::trace_event::TraceEventHandle AddTraceEvent(
bind_id);
}
-template <class ARG1_TYPE>
+template<class ARG1_TYPE>
+static inline base::trace_event::TraceEventHandle
+AddTraceEventWithThreadIdAndTimestamp(
+ char phase,
+ const unsigned char* category_group_enabled,
+ const char* name,
+ const char* scope,
+ unsigned long long id,
+ int thread_id,
+ const base::TimeTicks& timestamp,
+ unsigned int flags,
+ unsigned long long bind_id,
+ const char* arg1_name,
+ const ARG1_TYPE& arg1_val) {
+ const int num_args = 1;
+ unsigned char arg_types[1];
+ unsigned long long arg_values[1];
+ SetTraceValue(arg1_val, &arg_types[0], &arg_values[0]);
+ return TRACE_EVENT_API_ADD_TRACE_EVENT_WITH_THREAD_ID_AND_TIMESTAMP(
+ phase, category_group_enabled, name, scope, id, bind_id, thread_id,
+ timestamp, num_args, &arg1_name, arg_types, arg_values, NULL, flags);
+}
+
+template<class ARG1_TYPE>
+static inline base::trace_event::TraceEventHandle AddTraceEvent(
+ char phase,
+ const unsigned char* category_group_enabled,
+ const char* name,
+ const char* scope,
+ unsigned long long id,
+ unsigned int flags,
+ unsigned long long bind_id,
+ const char* arg1_name,
+ const ARG1_TYPE& arg1_val) {
+ int thread_id = static_cast<int>(base::PlatformThread::CurrentId());
+ base::TimeTicks now = TRACE_TIME_TICKS_NOW();
+ return AddTraceEventWithThreadIdAndTimestamp(
+ phase, category_group_enabled, name, scope, id, thread_id, now, flags,
+ bind_id, arg1_name, arg1_val);
+}
+
+template <class ARG1_CONVERTABLE_TYPE>
+static inline base::trace_event::TraceEventHandle AddTraceEvent(
+ char phase,
+ const unsigned char* category_group_enabled,
+ const char* name,
+ const char* scope,
+ unsigned long long id,
+ unsigned int flags,
+ unsigned long long bind_id,
+ const char* arg1_name,
+ std::unique_ptr<ARG1_CONVERTABLE_TYPE> arg1_val) {
+ int thread_id = static_cast<int>(base::PlatformThread::CurrentId());
+ base::TimeTicks now = TRACE_TIME_TICKS_NOW();
+ return AddTraceEventWithThreadIdAndTimestamp(
+ phase, category_group_enabled, name, scope, id, thread_id, now, flags,
+ bind_id, arg1_name, std::move(arg1_val));
+}
+
+template<class ARG1_TYPE, class ARG2_TYPE>
+static inline base::trace_event::TraceEventHandle
+AddTraceEventWithThreadIdAndTimestamp(
+ char phase,
+ const unsigned char* category_group_enabled,
+ const char* name,
+ const char* scope,
+ unsigned long long id,
+ int thread_id,
+ const base::TimeTicks& timestamp,
+ unsigned int flags,
+ unsigned long long bind_id,
+ const char* arg1_name,
+ const ARG1_TYPE& arg1_val,
+ const char* arg2_name,
+ const ARG2_TYPE& arg2_val) {
+ const int num_args = 2;
+ const char* arg_names[2] = { arg1_name, arg2_name };
+ unsigned char arg_types[2];
+ unsigned long long arg_values[2];
+ SetTraceValue(arg1_val, &arg_types[0], &arg_values[0]);
+ SetTraceValue(arg2_val, &arg_types[1], &arg_values[1]);
+ return TRACE_EVENT_API_ADD_TRACE_EVENT_WITH_THREAD_ID_AND_TIMESTAMP(
+ phase, category_group_enabled, name, scope, id, bind_id, thread_id,
+ timestamp, num_args, arg_names, arg_types, arg_values, NULL, flags);
+}
+
+template <class ARG1_CONVERTABLE_TYPE, class ARG2_TYPE>
+static inline base::trace_event::TraceEventHandle AddTraceEvent(
+ char phase,
+ const unsigned char* category_group_enabled,
+ const char* name,
+ const char* scope,
+ unsigned long long id,
+ unsigned int flags,
+ unsigned long long bind_id,
+ const char* arg1_name,
+ std::unique_ptr<ARG1_CONVERTABLE_TYPE> arg1_val,
+ const char* arg2_name,
+ const ARG2_TYPE& arg2_val) {
+ int thread_id = static_cast<int>(base::PlatformThread::CurrentId());
+ base::TimeTicks now = TRACE_TIME_TICKS_NOW();
+ return AddTraceEventWithThreadIdAndTimestamp(
+ phase, category_group_enabled, name, scope, id, thread_id, now, flags,
+ bind_id, arg1_name, std::move(arg1_val), arg2_name, arg2_val);
+}
+
+template <class ARG1_TYPE, class ARG2_CONVERTABLE_TYPE>
static inline base::trace_event::TraceEventHandle AddTraceEvent(
char phase,
const unsigned char* category_group_enabled,
@@ -921,15 +1138,17 @@ static inline base::trace_event::TraceEventHandle AddTraceEvent(
unsigned int flags,
unsigned long long bind_id,
const char* arg1_name,
- ARG1_TYPE&& arg1_val) {
+ const ARG1_TYPE& arg1_val,
+ const char* arg2_name,
+ std::unique_ptr<ARG2_CONVERTABLE_TYPE> arg2_val) {
int thread_id = static_cast<int>(base::PlatformThread::CurrentId());
base::TimeTicks now = TRACE_TIME_TICKS_NOW();
return AddTraceEventWithThreadIdAndTimestamp(
phase, category_group_enabled, name, scope, id, thread_id, now, flags,
- bind_id, arg1_name, std::forward<ARG1_TYPE>(arg1_val));
+ bind_id, arg1_name, arg1_val, arg2_name, std::move(arg2_val));
}
-template <class ARG1_TYPE, class ARG2_TYPE>
+template <class ARG1_CONVERTABLE_TYPE, class ARG2_CONVERTABLE_TYPE>
static inline base::trace_event::TraceEventHandle AddTraceEvent(
char phase,
const unsigned char* category_group_enabled,
@@ -939,26 +1158,68 @@ static inline base::trace_event::TraceEventHandle AddTraceEvent(
unsigned int flags,
unsigned long long bind_id,
const char* arg1_name,
- ARG1_TYPE&& arg1_val,
+ std::unique_ptr<ARG1_CONVERTABLE_TYPE> arg1_val,
const char* arg2_name,
- ARG2_TYPE&& arg2_val) {
+ std::unique_ptr<ARG2_CONVERTABLE_TYPE> arg2_val) {
int thread_id = static_cast<int>(base::PlatformThread::CurrentId());
base::TimeTicks now = TRACE_TIME_TICKS_NOW();
return AddTraceEventWithThreadIdAndTimestamp(
phase, category_group_enabled, name, scope, id, thread_id, now, flags,
- bind_id, arg1_name, std::forward<ARG1_TYPE>(arg1_val), arg2_name,
- std::forward<ARG2_TYPE>(arg2_val));
+ bind_id, arg1_name, std::move(arg1_val), arg2_name, std::move(arg2_val));
+}
+
+template<class ARG1_TYPE, class ARG2_TYPE>
+static inline base::trace_event::TraceEventHandle AddTraceEvent(
+ char phase,
+ const unsigned char* category_group_enabled,
+ const char* name,
+ const char* scope,
+ unsigned long long id,
+ unsigned int flags,
+ unsigned long long bind_id,
+ const char* arg1_name,
+ const ARG1_TYPE& arg1_val,
+ const char* arg2_name,
+ const ARG2_TYPE& arg2_val) {
+ int thread_id = static_cast<int>(base::PlatformThread::CurrentId());
+ base::TimeTicks now = TRACE_TIME_TICKS_NOW();
+ return AddTraceEventWithThreadIdAndTimestamp(
+ phase, category_group_enabled, name, scope, id, thread_id, now, flags,
+ bind_id, arg1_name, arg1_val, arg2_name, arg2_val);
+}
+
+template <class ARG1_CONVERTABLE_TYPE>
+static inline void AddMetadataEvent(
+ const unsigned char* category_group_enabled,
+ const char* event_name,
+ const char* arg_name,
+ std::unique_ptr<ARG1_CONVERTABLE_TYPE> arg_value) {
+ const char* arg_names[1] = {arg_name};
+ unsigned char arg_types[1] = {TRACE_VALUE_TYPE_CONVERTABLE};
+ std::unique_ptr<base::trace_event::ConvertableToTraceFormat>
+ convertable_values[1] = {std::move(arg_value)};
+ trace_event_internal::AddMetadataEvent(category_group_enabled, event_name,
+ 1, // num_args
+ arg_names, arg_types,
+ nullptr, // arg_values
+ convertable_values,
+ TRACE_EVENT_FLAG_NONE);
}
template <class ARG1_TYPE>
static void AddMetadataEvent(const unsigned char* category_group_enabled,
const char* event_name,
const char* arg_name,
- ARG1_TYPE&& arg_val) {
- base::trace_event::TraceArguments args(arg_name,
- std::forward<ARG1_TYPE>(arg_val));
- trace_event_internal::AddMetadataEvent(category_group_enabled, event_name,
- &args, TRACE_EVENT_FLAG_NONE);
+ const ARG1_TYPE& arg_val) {
+ const int num_args = 1;
+ const char* arg_names[1] = {arg_name};
+ unsigned char arg_types[1];
+ unsigned long long arg_values[1];
+ SetTraceValue(arg_val, &arg_types[0], &arg_values[0]);
+
+ trace_event_internal::AddMetadataEvent(
+ category_group_enabled, event_name, num_args, arg_names, arg_types,
+ arg_values, nullptr, TRACE_EVENT_FLAG_NONE);
}
// Used by TRACE_EVENTx macros. Do not use directly.
diff --git a/chromium/base/trace_event/trace_event_android.cc b/chromium/base/trace_event/trace_event_android.cc
index a1e51e8f21d..30d9c74a6d7 100644
--- a/chromium/base/trace_event/trace_event_android.cc
+++ b/chromium/base/trace_event/trace_event_android.cc
@@ -39,25 +39,32 @@ void WriteToATrace(int fd, const char* buffer, size_t size) {
}
}
-void WriteEvent(char phase,
- const char* category_group,
- const char* name,
- unsigned long long id,
- const TraceArguments& args,
- unsigned int flags) {
+void WriteEvent(
+ char phase,
+ const char* category_group,
+ const char* name,
+ unsigned long long id,
+ const char** arg_names,
+ const unsigned char* arg_types,
+ const TraceEvent::TraceValue* arg_values,
+ const std::unique_ptr<ConvertableToTraceFormat>* convertable_values,
+ unsigned int flags) {
std::string out = StringPrintf("%c|%d|%s", phase, getpid(), name);
if (flags & TRACE_EVENT_FLAG_HAS_ID)
StringAppendF(&out, "-%" PRIx64, static_cast<uint64_t>(id));
out += '|';
- const char* const* arg_names = args.names();
- for (size_t i = 0; i < args.size() && arg_names[i]; ++i) {
+ for (int i = 0; i < kTraceMaxNumArgs && arg_names[i];
+ ++i) {
if (i)
out += ';';
out += arg_names[i];
out += '=';
std::string::size_type value_start = out.length();
- args.values()[i].AppendAsJSON(args.types()[i], &out);
+ if (arg_types[i] == TRACE_VALUE_TYPE_CONVERTABLE)
+ convertable_values[i]->AppendAsTraceFormat(&out);
+ else
+ TraceEvent::AppendValueAsJSON(arg_types[i], arg_values[i], &out);
// Remove the quotes which may confuse the atrace script.
ReplaceSubstringsAfterOffset(&out, value_start, "\\\"", "'");
@@ -140,35 +147,43 @@ void TraceEvent::SendToATrace() {
switch (phase_) {
case TRACE_EVENT_PHASE_BEGIN:
- WriteEvent('B', category_group, name_, id_, args_, flags_);
+ WriteEvent('B', category_group, name_, id_,
+ arg_names_, arg_types_, arg_values_, convertable_values_,
+ flags_);
break;
case TRACE_EVENT_PHASE_COMPLETE:
- WriteEvent(duration_.ToInternalValue() == -1 ? 'B' : 'E', category_group,
- name_, id_, args_, flags_);
+ WriteEvent(duration_.ToInternalValue() == -1 ? 'B' : 'E',
+ category_group, name_, id_,
+ arg_names_, arg_types_, arg_values_, convertable_values_,
+ flags_);
break;
case TRACE_EVENT_PHASE_END:
// Though a single 'E' is enough, here append pid, name and
// category_group etc. So that unpaired events can be found easily.
- WriteEvent('E', category_group, name_, id_, args_, flags_);
+ WriteEvent('E', category_group, name_, id_,
+ arg_names_, arg_types_, arg_values_, convertable_values_,
+ flags_);
break;
case TRACE_EVENT_PHASE_INSTANT:
// Simulate an instance event with a pair of begin/end events.
- WriteEvent('B', category_group, name_, id_, args_, flags_);
+ WriteEvent('B', category_group, name_, id_,
+ arg_names_, arg_types_, arg_values_, convertable_values_,
+ flags_);
WriteToATrace(g_atrace_fd, "E", 1);
break;
case TRACE_EVENT_PHASE_COUNTER:
- for (size_t i = 0; i < arg_size() && arg_name(i); ++i) {
- DCHECK(arg_type(i) == TRACE_VALUE_TYPE_INT);
- std::string out =
- base::StringPrintf("C|%d|%s-%s", getpid(), name_, arg_name(i));
+ for (int i = 0; i < kTraceMaxNumArgs && arg_names_[i]; ++i) {
+ DCHECK(arg_types_[i] == TRACE_VALUE_TYPE_INT);
+ std::string out = base::StringPrintf(
+ "C|%d|%s-%s", getpid(), name_, arg_names_[i]);
if (flags_ & TRACE_EVENT_FLAG_HAS_ID)
StringAppendF(&out, "-%" PRIx64, static_cast<uint64_t>(id_));
- StringAppendF(&out, "|%d|%s", static_cast<int>(arg_value(i).as_int),
- category_group);
+ StringAppendF(&out, "|%d|%s",
+ static_cast<int>(arg_values_[i].as_int), category_group);
WriteToATrace(g_atrace_fd, out.c_str(), out.size());
}
break;
diff --git a/chromium/base/trace_event/trace_event_etw_export_win.cc b/chromium/base/trace_event/trace_event_etw_export_win.cc
index e2c4f80dc16..89059da3556 100644
--- a/chromium/base/trace_event/trace_event_etw_export_win.cc
+++ b/chromium/base/trace_event/trace_event_etw_export_win.cc
@@ -168,11 +168,16 @@ bool TraceEventETWExport::IsETWExportEnabled() {
}
// static
-void TraceEventETWExport::AddEvent(char phase,
- const unsigned char* category_group_enabled,
- const char* name,
- unsigned long long id,
- const TraceArguments* args) {
+void TraceEventETWExport::AddEvent(
+ char phase,
+ const unsigned char* category_group_enabled,
+ const char* name,
+ unsigned long long id,
+ int num_args,
+ const char* const* arg_names,
+ const unsigned char* arg_types,
+ const unsigned long long* arg_values,
+ const std::unique_ptr<ConvertableToTraceFormat>* convertable_values) {
// We bail early in case exporting is disabled or no consumer is listening.
auto* instance = GetInstance();
if (!instance || !instance->etw_export_enabled_ || !EventEnabledChromeEvent())
@@ -250,22 +255,26 @@ void TraceEventETWExport::AddEvent(char phase,
}
std::string arg_values_string[3];
- size_t num_args = args ? args->size() : 0;
- for (size_t i = 0; i < num_args; i++) {
- if (args->types()[i] == TRACE_VALUE_TYPE_CONVERTABLE) {
+ for (int i = 0; i < num_args; i++) {
+ if (arg_types[i] == TRACE_VALUE_TYPE_CONVERTABLE) {
// Temporarily do nothing here. This function consumes 1/3 to 1/2 of
// *total* process CPU time when ETW tracing, and many of the strings
// created exceed WPA's 4094 byte limit and are shown as:
// "Unable to parse data". See crbug.com/488257
+ // convertable_values[i]->AppendAsTraceFormat(arg_values_string + i);
} else {
- args->values()[i].AppendAsJSON(args->types()[i], arg_values_string + i);
+ TraceEvent::TraceValue trace_event;
+ trace_event.as_uint = arg_values[i];
+ TraceEvent::AppendValueAsJSON(arg_types[i], trace_event,
+ arg_values_string + i);
}
}
EventWriteChromeEvent(
- name, phase_string, num_args > 0 ? args->names()[0] : "",
- arg_values_string[0].c_str(), num_args > 1 ? args->names()[1] : "",
- arg_values_string[1].c_str(), "", "");
+ name, phase_string, num_args > 0 ? arg_names[0] : "",
+ arg_values_string[0].c_str(), num_args > 1 ? arg_names[1] : "",
+ arg_values_string[1].c_str(), num_args > 2 ? arg_names[2] : "",
+ arg_values_string[2].c_str());
}
// static
diff --git a/chromium/base/trace_event/trace_event_etw_export_win.h b/chromium/base/trace_event/trace_event_etw_export_win.h
index ac19553a527..345e87b9ae9 100644
--- a/chromium/base/trace_event/trace_event_etw_export_win.h
+++ b/chromium/base/trace_event/trace_event_etw_export_win.h
@@ -47,11 +47,16 @@ class BASE_EXPORT TraceEventETWExport {
// Exports an event to ETW. This is mainly used in
// TraceLog::AddTraceEventWithThreadIdAndTimestamp to export internal events.
- static void AddEvent(char phase,
- const unsigned char* category_group_enabled,
- const char* name,
- unsigned long long id,
- const TraceArguments* args);
+ static void AddEvent(
+ char phase,
+ const unsigned char* category_group_enabled,
+ const char* name,
+ unsigned long long id,
+ int num_args,
+ const char* const* arg_names,
+ const unsigned char* arg_types,
+ const unsigned long long* arg_values,
+ const std::unique_ptr<ConvertableToTraceFormat>* convertable_values);
// Exports an ETW event that marks the end of a complete event.
static void AddCompleteEndEvent(const char* name);
diff --git a/chromium/base/trace_event/trace_event_impl.cc b/chromium/base/trace_event/trace_event_impl.cc
index ee3e21d4483..66b69c3d87f 100644
--- a/chromium/base/trace_event/trace_event_impl.cc
+++ b/chromium/base/trace_event/trace_event_impl.cc
@@ -22,6 +22,25 @@
namespace base {
namespace trace_event {
+namespace {
+
+size_t GetAllocLength(const char* str) { return str ? strlen(str) + 1 : 0; }
+
+// Copies |*member| into |*buffer|, sets |*member| to point to this new
+// location, and then advances |*buffer| by the amount written.
+void CopyTraceEventParameter(char** buffer,
+ const char** member,
+ const char* end) {
+ if (*member) {
+ size_t written = strlcpy(*buffer, *member, end - *buffer) + 1;
+ DCHECK_LE(static_cast<int>(written), end - *buffer);
+ *member = *buffer;
+ *buffer += written;
+ }
+}
+
+} // namespace
+
bool ConvertableToTraceFormat::AppendToProto(ProtoAppender* appender) {
return false;
}
@@ -30,19 +49,48 @@ bool ConvertableToTraceFormat::AppendToProto(ProtoAppender* appender) {
static_assert(trace_event_internal::kGlobalScope == nullptr,
"Invalid TraceEvent::scope default initializer value");
-TraceEvent::TraceEvent() = default;
-
-TraceEvent::TraceEvent(int thread_id,
- TimeTicks timestamp,
- ThreadTicks thread_timestamp,
- char phase,
- const unsigned char* category_group_enabled,
- const char* name,
- const char* scope,
- unsigned long long id,
- unsigned long long bind_id,
- TraceArguments* args,
- unsigned int flags)
+TraceEvent::TraceEvent() {
+ for (int i = 0; i < kTraceMaxNumArgs; ++i) {
+ arg_values_[i].as_uint = 0u;
+ arg_names_[i] = nullptr;
+ arg_types_[i] = TRACE_VALUE_TYPE_UINT;
+ }
+}
+
+TraceEvent::~TraceEvent() = default;
+
+TraceEvent::TraceEvent(TraceEvent&& other) noexcept = default;
+
+#if !defined(__clang__)
+// Clang will crash at runtime when trying to compile the line below
+// with coverage instrumentation enabled (https://crbug.com/908937)
+TraceEvent& TraceEvent::operator=(TraceEvent&& other) noexcept = default;
+#else // defined(__clang__)
+TraceEvent& TraceEvent::operator=(TraceEvent&& other) noexcept {
+ if (this != &other) {
+ this->~TraceEvent();
+ new (this) TraceEvent(std::move(other));
+ }
+ return *this;
+}
+#endif // defined(__clang__)
+
+TraceEvent::TraceEvent(
+ int thread_id,
+ TimeTicks timestamp,
+ ThreadTicks thread_timestamp,
+ char phase,
+ const unsigned char* category_group_enabled,
+ const char* name,
+ const char* scope,
+ unsigned long long id,
+ unsigned long long bind_id,
+ int num_args,
+ const char* const* arg_names,
+ const unsigned char* arg_types,
+ const unsigned long long* arg_values,
+ std::unique_ptr<ConvertableToTraceFormat>* convertable_values,
+ unsigned int flags)
: timestamp_(timestamp),
thread_timestamp_(thread_timestamp),
scope_(scope),
@@ -53,33 +101,121 @@ TraceEvent::TraceEvent(int thread_id,
flags_(flags),
bind_id_(bind_id),
phase_(phase) {
- InitArgs(args);
+ InitArgs(num_args, arg_names, arg_types, arg_values, convertable_values,
+ flags);
}
-TraceEvent::~TraceEvent() = default;
+void TraceEvent::InitArgs(
+ int num_args,
+ const char* const* arg_names,
+ const unsigned char* arg_types,
+ const unsigned long long* arg_values,
+ std::unique_ptr<ConvertableToTraceFormat>* convertable_values,
+ unsigned int flags) {
+ // Clamp num_args since it may have been set by a third_party library.
+ num_args = (num_args > kTraceMaxNumArgs) ? kTraceMaxNumArgs : num_args;
+ int i = 0;
+ for (; i < num_args; ++i) {
+ arg_names_[i] = arg_names[i];
+ arg_types_[i] = arg_types[i];
+
+ if (arg_types[i] == TRACE_VALUE_TYPE_CONVERTABLE) {
+ convertable_values_[i] = std::move(convertable_values[i]);
+ } else {
+ arg_values_[i].as_uint = arg_values[i];
+ convertable_values_[i].reset();
+ }
+ }
+ for (; i < kTraceMaxNumArgs; ++i) {
+ arg_names_[i] = nullptr;
+ arg_values_[i].as_uint = 0u;
+ convertable_values_[i].reset();
+ arg_types_[i] = TRACE_VALUE_TYPE_UINT;
+ }
-TraceEvent::TraceEvent(TraceEvent&& other) noexcept = default;
-TraceEvent& TraceEvent::operator=(TraceEvent&& other) noexcept = default;
+ bool copy = !!(flags & TRACE_EVENT_FLAG_COPY);
+ size_t alloc_size = 0;
+ if (copy) {
+ alloc_size += GetAllocLength(name_) + GetAllocLength(scope_);
+ for (i = 0; i < num_args; ++i) {
+ alloc_size += GetAllocLength(arg_names_[i]);
+ if (arg_types_[i] == TRACE_VALUE_TYPE_STRING)
+ arg_types_[i] = TRACE_VALUE_TYPE_COPY_STRING;
+ }
+ }
+
+ bool arg_is_copy[kTraceMaxNumArgs];
+ for (i = 0; i < num_args; ++i) {
+ // No copying of convertable types, we retain ownership.
+ if (arg_types_[i] == TRACE_VALUE_TYPE_CONVERTABLE)
+ continue;
+
+ // We only take a copy of arg_vals if they are of type COPY_STRING.
+ arg_is_copy[i] = (arg_types_[i] == TRACE_VALUE_TYPE_COPY_STRING);
+ if (arg_is_copy[i])
+ alloc_size += GetAllocLength(arg_values_[i].as_string);
+ }
+
+ if (alloc_size) {
+ parameter_copy_storage_.reset(new std::string);
+ parameter_copy_storage_->resize(alloc_size);
+ char* ptr = base::data(*parameter_copy_storage_);
+ const char* end = ptr + alloc_size;
+ if (copy) {
+ CopyTraceEventParameter(&ptr, &name_, end);
+ CopyTraceEventParameter(&ptr, &scope_, end);
+ for (i = 0; i < num_args; ++i) {
+ CopyTraceEventParameter(&ptr, &arg_names_[i], end);
+ }
+ }
+ for (i = 0; i < num_args; ++i) {
+ if (arg_types_[i] == TRACE_VALUE_TYPE_CONVERTABLE)
+ continue;
+ if (arg_is_copy[i])
+ CopyTraceEventParameter(&ptr, &arg_values_[i].as_string, end);
+ }
+ DCHECK_EQ(end, ptr) << "Overrun by " << ptr - end;
+ }
+}
void TraceEvent::Reset() {
// Only reset fields that won't be initialized in Reset(int, ...), or that may
// hold references to other objects.
duration_ = TimeDelta::FromInternalValue(-1);
- args_.Reset();
- parameter_copy_storage_.Reset();
+
+ // The following pointers might point into parameter_copy_storage_ so
+ // must be reset to nullptr first.
+ for (int i = 0; i < kTraceMaxNumArgs; ++i) {
+ arg_names_[i] = nullptr;
+ arg_values_[i].as_uint = 0u;
+ arg_types_[i] = TRACE_VALUE_TYPE_UINT;
+ }
+ scope_ = nullptr;
+ name_ = nullptr;
+
+ // It is now safe to reset the storage area.
+ parameter_copy_storage_.reset();
+
+ for (int i = 0; i < kTraceMaxNumArgs; ++i)
+ convertable_values_[i].reset();
}
-void TraceEvent::Reset(int thread_id,
- TimeTicks timestamp,
- ThreadTicks thread_timestamp,
- char phase,
- const unsigned char* category_group_enabled,
- const char* name,
- const char* scope,
- unsigned long long id,
- unsigned long long bind_id,
- TraceArguments* args,
- unsigned int flags) {
+void TraceEvent::Reset(
+ int thread_id,
+ TimeTicks timestamp,
+ ThreadTicks thread_timestamp,
+ char phase,
+ const unsigned char* category_group_enabled,
+ const char* name,
+ const char* scope,
+ unsigned long long id,
+ unsigned long long bind_id,
+ int num_args,
+ const char* const* arg_names,
+ const unsigned char* arg_types,
+ const unsigned long long* arg_values,
+ std::unique_ptr<ConvertableToTraceFormat>* convertable_values,
+ unsigned int flags) {
Reset();
timestamp_ = timestamp;
thread_timestamp_ = thread_timestamp;
@@ -92,14 +228,8 @@ void TraceEvent::Reset(int thread_id,
bind_id_ = bind_id;
phase_ = phase;
- InitArgs(args);
-}
-
-void TraceEvent::InitArgs(TraceArguments* args) {
- if (args)
- args_ = std::move(*args);
- args_.CopyStringsTo(&parameter_copy_storage_,
- !!(flags_ & TRACE_EVENT_FLAG_COPY), &name_, &scope_);
+ InitArgs(num_args, arg_names, arg_types, arg_values, convertable_values,
+ flags);
}
void TraceEvent::UpdateDuration(const TimeTicks& now,
@@ -115,12 +245,80 @@ void TraceEvent::UpdateDuration(const TimeTicks& now,
void TraceEvent::EstimateTraceMemoryOverhead(
TraceEventMemoryOverhead* overhead) {
- overhead->Add(TraceEventMemoryOverhead::kTraceEvent,
- parameter_copy_storage_.EstimateTraceMemoryOverhead());
+ overhead->Add(TraceEventMemoryOverhead::kTraceEvent, sizeof(*this));
+
+ if (parameter_copy_storage_)
+ overhead->AddString(*parameter_copy_storage_);
- for (size_t i = 0; i < arg_size(); ++i) {
- if (arg_type(i) == TRACE_VALUE_TYPE_CONVERTABLE)
- arg_value(i).as_convertable->EstimateTraceMemoryOverhead(overhead);
+ for (size_t i = 0; i < kTraceMaxNumArgs; ++i) {
+ if (arg_types_[i] == TRACE_VALUE_TYPE_CONVERTABLE)
+ convertable_values_[i]->EstimateTraceMemoryOverhead(overhead);
+ }
+}
+
+// static
+void TraceEvent::AppendValueAsJSON(unsigned char type,
+ TraceEvent::TraceValue value,
+ std::string* out) {
+ switch (type) {
+ case TRACE_VALUE_TYPE_BOOL:
+ *out += value.as_bool ? "true" : "false";
+ break;
+ case TRACE_VALUE_TYPE_UINT:
+ StringAppendF(out, "%" PRIu64, static_cast<uint64_t>(value.as_uint));
+ break;
+ case TRACE_VALUE_TYPE_INT:
+ StringAppendF(out, "%" PRId64, static_cast<int64_t>(value.as_int));
+ break;
+ case TRACE_VALUE_TYPE_DOUBLE: {
+ // FIXME: base/json/json_writer.cc is using the same code,
+ // should be made into a common method.
+ std::string real;
+ double val = value.as_double;
+ if (std::isfinite(val)) {
+ real = NumberToString(val);
+ // Ensure that the number has a .0 if there's no decimal or 'e'. This
+ // makes sure that when we read the JSON back, it's interpreted as a
+ // real rather than an int.
+ if (real.find('.') == std::string::npos &&
+ real.find('e') == std::string::npos &&
+ real.find('E') == std::string::npos) {
+ real.append(".0");
+ }
+ // The JSON spec requires that non-integer values in the range (-1,1)
+ // have a zero before the decimal point - ".52" is not valid, "0.52" is.
+ if (real[0] == '.') {
+ real.insert(0, "0");
+ } else if (real.length() > 1 && real[0] == '-' && real[1] == '.') {
+ // "-.1" bad "-0.1" good
+ real.insert(1, "0");
+ }
+ } else if (std::isnan(val)){
+ // The JSON spec doesn't allow NaN and Infinity (since these are
+ // objects in EcmaScript). Use strings instead.
+ real = "\"NaN\"";
+ } else if (val < 0) {
+ real = "\"-Infinity\"";
+ } else {
+ real = "\"Infinity\"";
+ }
+ StringAppendF(out, "%s", real.c_str());
+ break;
+ }
+ case TRACE_VALUE_TYPE_POINTER:
+ // JSON only supports double and int numbers.
+ // So as not to lose bits from a 64-bit pointer, output as a hex string.
+ StringAppendF(
+ out, "\"0x%" PRIx64 "\"",
+ static_cast<uint64_t>(reinterpret_cast<uintptr_t>(value.as_pointer)));
+ break;
+ case TRACE_VALUE_TYPE_STRING:
+ case TRACE_VALUE_TYPE_COPY_STRING:
+ EscapeJSONString(value.as_string ? value.as_string : "NULL", true, out);
+ break;
+ default:
+ NOTREACHED() << "Don't know how to print this value";
+ break;
}
}
@@ -155,7 +353,7 @@ void TraceEvent::AppendAsJSON(
// approach
ArgumentNameFilterPredicate argument_name_filter_predicate;
bool strip_args =
- arg_size() > 0 && arg_name(0) && !argument_filter_predicate.is_null() &&
+ arg_names_[0] && !argument_filter_predicate.is_null() &&
!argument_filter_predicate.Run(category_group_name, name_,
&argument_name_filter_predicate);
@@ -164,16 +362,19 @@ void TraceEvent::AppendAsJSON(
} else {
*out += "{";
- for (size_t i = 0; i < arg_size() && arg_name(i); ++i) {
+ for (int i = 0; i < kTraceMaxNumArgs && arg_names_[i]; ++i) {
if (i > 0)
*out += ",";
*out += "\"";
- *out += arg_name(i);
+ *out += arg_names_[i];
*out += "\":";
if (argument_name_filter_predicate.is_null() ||
- argument_name_filter_predicate.Run(arg_name(i))) {
- arg_value(i).AppendAsJSON(arg_type(i), out);
+ argument_name_filter_predicate.Run(arg_names_[i])) {
+ if (arg_types_[i] == TRACE_VALUE_TYPE_CONVERTABLE)
+ convertable_values_[i]->AppendAsTraceFormat(out);
+ else
+ AppendValueAsJSON(arg_types_[i], arg_values_[i], out);
} else {
*out += "\"__stripped__\"";
}
@@ -274,14 +475,19 @@ void TraceEvent::AppendPrettyPrinted(std::ostringstream* out) const {
*out << name_ << "[";
*out << TraceLog::GetCategoryGroupName(category_group_enabled_);
*out << "]";
- if (arg_size() > 0 && arg_name(0)) {
+ if (arg_names_[0]) {
*out << ", {";
- for (size_t i = 0; i < arg_size() && arg_name(i); ++i) {
+ for (int i = 0; i < kTraceMaxNumArgs && arg_names_[i]; ++i) {
if (i > 0)
*out << ", ";
- *out << arg_name(i) << ":";
+ *out << arg_names_[i] << ":";
std::string value_as_text;
- arg_value(i).AppendAsJSON(arg_type(i), &value_as_text);
+
+ if (arg_types_[i] == TRACE_VALUE_TYPE_CONVERTABLE)
+ convertable_values_[i]->AppendAsTraceFormat(&value_as_text);
+ else
+ AppendValueAsJSON(arg_types_[i], arg_values_[i], &value_as_text);
+
*out << value_as_text;
}
*out << "}";
diff --git a/chromium/base/trace_event/trace_event_impl.h b/chromium/base/trace_event/trace_event_impl.h
index 93eed6225b9..3c459530c52 100644
--- a/chromium/base/trace_event/trace_event_impl.h
+++ b/chromium/base/trace_event/trace_event_impl.h
@@ -23,7 +23,6 @@
#include "base/synchronization/lock.h"
#include "base/threading/thread_local.h"
#include "base/trace_event/common/trace_event_common.h"
-#include "base/trace_event/trace_arguments.h"
#include "base/trace_event/trace_event_memory_overhead.h"
#include "build/build_config.h"
@@ -37,6 +36,48 @@ typedef base::Callback<bool(const char* category_group_name,
ArgumentNameFilterPredicate*)>
ArgumentFilterPredicate;
+// For any argument of type TRACE_VALUE_TYPE_CONVERTABLE the provided
+// class must implement this interface.
+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);
+
+ std::string ToString() const {
+ std::string result;
+ AppendAsTraceFormat(&result);
+ return result;
+ }
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(ConvertableToTraceFormat);
+};
+
+const int kTraceMaxNumArgs = 2;
+
struct TraceEventHandle {
uint32_t chunk_seq;
// These numbers of bits must be kept consistent with
@@ -48,8 +89,14 @@ struct TraceEventHandle {
class BASE_EXPORT TraceEvent {
public:
- // TODO(898794): Remove once all users have been updated.
- using TraceValue = base::trace_event::TraceValue;
+ union TraceValue {
+ bool as_bool;
+ unsigned long long as_uint;
+ long long as_int;
+ double as_double;
+ const void* as_pointer;
+ const char* as_string;
+ };
TraceEvent();
@@ -62,7 +109,11 @@ class BASE_EXPORT TraceEvent {
const char* scope,
unsigned long long id,
unsigned long long bind_id,
- TraceArguments* args,
+ int num_args,
+ const char* const* arg_names,
+ const unsigned char* arg_types,
+ const unsigned long long* arg_values,
+ std::unique_ptr<ConvertableToTraceFormat>* convertable_values,
unsigned int flags);
~TraceEvent();
@@ -90,7 +141,11 @@ class BASE_EXPORT TraceEvent {
const char* scope,
unsigned long long id,
unsigned long long bind_id,
- TraceArguments* args,
+ int num_args,
+ const char* const* arg_names,
+ const unsigned char* arg_types,
+ const unsigned long long* arg_values,
+ std::unique_ptr<ConvertableToTraceFormat>* convertable_values,
unsigned int flags);
void UpdateDuration(const TimeTicks& now, const ThreadTicks& thread_now);
@@ -103,12 +158,9 @@ class BASE_EXPORT TraceEvent {
const ArgumentFilterPredicate& argument_filter_predicate) const;
void AppendPrettyPrinted(std::ostringstream* out) const;
- // TODO(898794): Remove once caller has been updated.
static void AppendValueAsJSON(unsigned char type,
TraceValue value,
- std::string* out) {
- value.AppendAsJSON(type, out);
- }
+ std::string* out);
TimeTicks timestamp() const { return timestamp_; }
ThreadTicks thread_timestamp() const { return thread_timestamp_; }
@@ -123,8 +175,8 @@ class BASE_EXPORT TraceEvent {
unsigned long long bind_id() const { return bind_id_; }
// Exposed for unittesting:
- const StringStorage& parameter_copy_storage() const {
- return parameter_copy_storage_;
+ const std::string* parameter_copy_storage() const {
+ return parameter_copy_storage_.get();
}
const unsigned char* category_group_enabled() const {
@@ -133,17 +185,12 @@ class BASE_EXPORT TraceEvent {
const char* name() const { return name_; }
- size_t arg_size() const { return args_.size(); }
- unsigned char arg_type(size_t index) const { return args_.types()[index]; }
- const char* arg_name(size_t index) const { return args_.names()[index]; }
- const TraceValue& arg_value(size_t index) const {
- return args_.values()[index];
- }
+ unsigned char arg_type(size_t index) const { return arg_types_[index]; }
+ const char* arg_name(size_t index) const { return arg_names_[index]; }
+ const TraceValue& arg_value(size_t index) const { return arg_values_[index]; }
ConvertableToTraceFormat* arg_convertible_value(size_t index) {
- return (arg_type(index) == TRACE_VALUE_TYPE_CONVERTABLE)
- ? arg_value(index).as_convertable
- : nullptr;
+ return convertable_values_[index].get();
}
#if defined(OS_ANDROID)
@@ -151,7 +198,12 @@ class BASE_EXPORT TraceEvent {
#endif
private:
- void InitArgs(TraceArguments* args);
+ void InitArgs(int num_args,
+ const char* const* arg_names,
+ const unsigned char* arg_types,
+ const unsigned long long* arg_values,
+ std::unique_ptr<ConvertableToTraceFormat>* convertable_values,
+ unsigned int flags);
// Note: these are ordered by size (largest first) for optimal packing.
TimeTicks timestamp_ = TimeTicks();
@@ -165,10 +217,13 @@ class BASE_EXPORT TraceEvent {
// The equivalence is checked with a static_assert() in trace_event_impl.cc.
const char* scope_ = nullptr;
unsigned long long id_ = 0u;
+ TraceValue arg_values_[kTraceMaxNumArgs];
+ const char* arg_names_[kTraceMaxNumArgs];
+ std::unique_ptr<ConvertableToTraceFormat>
+ convertable_values_[kTraceMaxNumArgs];
const unsigned char* category_group_enabled_ = nullptr;
const char* name_ = nullptr;
- StringStorage parameter_copy_storage_;
- TraceArguments args_;
+ std::unique_ptr<std::string> parameter_copy_storage_;
// Depending on TRACE_EVENT_FLAG_HAS_PROCESS_ID the event will have either:
// tid: thread_id_, pid: current_process_id (default case).
// tid: -1, pid: process_id_ (when flags_ & TRACE_EVENT_FLAG_HAS_PROCESS_ID).
@@ -178,6 +233,7 @@ class BASE_EXPORT TraceEvent {
};
unsigned int flags_ = 0;
unsigned long long bind_id_ = 0;
+ unsigned char arg_types_[kTraceMaxNumArgs];
char phase_ = TRACE_EVENT_PHASE_BEGIN;
DISALLOW_COPY_AND_ASSIGN(TraceEvent);
diff --git a/chromium/base/trace_event/trace_event_unittest.cc b/chromium/base/trace_event/trace_event_unittest.cc
index 47272e195c4..a0d46822e2f 100644
--- a/chromium/base/trace_event/trace_event_unittest.cc
+++ b/chromium/base/trace_event/trace_event_unittest.cc
@@ -1672,10 +1672,10 @@ TEST_F(TraceEventTestFixture, StaticStringVsString) {
ASSERT_TRUE(event2);
EXPECT_STREQ("name1", event1->name());
EXPECT_STREQ("name2", event2->name());
- EXPECT_FALSE(event1->parameter_copy_storage().empty());
- EXPECT_FALSE(event2->parameter_copy_storage().empty());
- EXPECT_GT(event1->parameter_copy_storage().size(), 0u);
- EXPECT_GT(event2->parameter_copy_storage().size(), 0u);
+ EXPECT_TRUE(event1->parameter_copy_storage() != nullptr);
+ EXPECT_TRUE(event2->parameter_copy_storage() != nullptr);
+ EXPECT_GT(event1->parameter_copy_storage()->size(), 0u);
+ EXPECT_GT(event2->parameter_copy_storage()->size(), 0u);
EndTraceAndFlush();
}
@@ -1705,8 +1705,8 @@ TEST_F(TraceEventTestFixture, StaticStringVsString) {
ASSERT_TRUE(event2);
EXPECT_STREQ("name1", event1->name());
EXPECT_STREQ("name2", event2->name());
- EXPECT_TRUE(event1->parameter_copy_storage().empty());
- EXPECT_TRUE(event2->parameter_copy_storage().empty());
+ EXPECT_TRUE(event1->parameter_copy_storage() == nullptr);
+ EXPECT_TRUE(event2->parameter_copy_storage() == nullptr);
EndTraceAndFlush();
}
}
diff --git a/chromium/base/trace_event/trace_log.cc b/chromium/base/trace_event/trace_log.cc
index 2f704e59bb5..1ab7161fc16 100644
--- a/chromium/base/trace_event/trace_log.cc
+++ b/chromium/base/trace_event/trace_log.cc
@@ -107,14 +107,19 @@ void InitializeMetadataEvent(TraceEvent* trace_event,
if (!trace_event)
return;
- TraceArguments args(arg_name, value);
+ int num_args = 1;
+ unsigned char arg_type;
+ unsigned long long arg_value;
+ ::trace_event_internal::SetTraceValue(value, &arg_type, &arg_value);
+
trace_event->Reset(
thread_id, TimeTicks(), ThreadTicks(), TRACE_EVENT_PHASE_METADATA,
CategoryRegistry::kCategoryMetadata->state_ptr(), metadata_name,
trace_event_internal::kGlobalScope, // scope
trace_event_internal::kNoId, // id
trace_event_internal::kNoId, // bind_id
- &args, TRACE_EVENT_FLAG_NONE);
+ num_args, &arg_name, &arg_type, &arg_value, nullptr,
+ TRACE_EVENT_FLAG_NONE);
}
class AutoThreadLocalBoolean {
@@ -1065,14 +1070,29 @@ TraceEventHandle TraceLog::AddTraceEvent(
const char* name,
const char* scope,
unsigned long long id,
- TraceArguments* args,
+ int num_args,
+ const char* const* arg_names,
+ const unsigned char* arg_types,
+ const unsigned long long* arg_values,
+ std::unique_ptr<ConvertableToTraceFormat>* convertable_values,
unsigned int flags) {
int thread_id = static_cast<int>(base::PlatformThread::CurrentId());
base::TimeTicks now = TRACE_TIME_TICKS_NOW();
return AddTraceEventWithThreadIdAndTimestamp(
- phase, category_group_enabled, name, scope, id,
+ phase,
+ category_group_enabled,
+ name,
+ scope,
+ id,
trace_event_internal::kNoId, // bind_id
- thread_id, now, args, flags);
+ thread_id,
+ now,
+ num_args,
+ arg_names,
+ arg_types,
+ arg_values,
+ convertable_values,
+ flags);
}
TraceEventHandle TraceLog::AddTraceEventWithBindId(
@@ -1082,13 +1102,29 @@ TraceEventHandle TraceLog::AddTraceEventWithBindId(
const char* scope,
unsigned long long id,
unsigned long long bind_id,
- TraceArguments* args,
+ int num_args,
+ const char* const* arg_names,
+ const unsigned char* arg_types,
+ const unsigned long long* arg_values,
+ std::unique_ptr<ConvertableToTraceFormat>* convertable_values,
unsigned int flags) {
int thread_id = static_cast<int>(base::PlatformThread::CurrentId());
base::TimeTicks now = TRACE_TIME_TICKS_NOW();
return AddTraceEventWithThreadIdAndTimestamp(
- phase, category_group_enabled, name, scope, id, bind_id, thread_id, now,
- args, flags | TRACE_EVENT_FLAG_HAS_CONTEXT_ID);
+ phase,
+ category_group_enabled,
+ name,
+ scope,
+ id,
+ bind_id,
+ thread_id,
+ now,
+ num_args,
+ arg_names,
+ arg_types,
+ arg_values,
+ convertable_values,
+ flags | TRACE_EVENT_FLAG_HAS_CONTEXT_ID);
}
TraceEventHandle TraceLog::AddTraceEventWithProcessId(
@@ -1098,13 +1134,28 @@ TraceEventHandle TraceLog::AddTraceEventWithProcessId(
const char* scope,
unsigned long long id,
int process_id,
- TraceArguments* args,
+ int num_args,
+ const char* const* arg_names,
+ const unsigned char* arg_types,
+ const unsigned long long* arg_values,
+ std::unique_ptr<ConvertableToTraceFormat>* convertable_values,
unsigned int flags) {
base::TimeTicks now = TRACE_TIME_TICKS_NOW();
return AddTraceEventWithThreadIdAndTimestamp(
- phase, category_group_enabled, name, scope, id,
+ phase,
+ category_group_enabled,
+ name,
+ scope,
+ id,
trace_event_internal::kNoId, // bind_id
- process_id, now, args, flags | TRACE_EVENT_FLAG_HAS_PROCESS_ID);
+ process_id,
+ now,
+ num_args,
+ arg_names,
+ arg_types,
+ arg_values,
+ convertable_values,
+ flags | TRACE_EVENT_FLAG_HAS_PROCESS_ID);
}
// Handle legacy calls to AddTraceEventWithThreadIdAndTimestamp
@@ -1117,12 +1168,27 @@ TraceEventHandle TraceLog::AddTraceEventWithThreadIdAndTimestamp(
unsigned long long id,
int thread_id,
const TimeTicks& timestamp,
- TraceArguments* args,
+ int num_args,
+ const char* const* arg_names,
+ const unsigned char* arg_types,
+ const unsigned long long* arg_values,
+ std::unique_ptr<ConvertableToTraceFormat>* convertable_values,
unsigned int flags) {
return AddTraceEventWithThreadIdAndTimestamp(
- phase, category_group_enabled, name, scope, id,
+ phase,
+ category_group_enabled,
+ name,
+ scope,
+ id,
trace_event_internal::kNoId, // bind_id
- thread_id, timestamp, args, flags);
+ thread_id,
+ timestamp,
+ num_args,
+ arg_names,
+ arg_types,
+ arg_values,
+ convertable_values,
+ flags);
}
TraceEventHandle TraceLog::AddTraceEventWithThreadIdAndTimestamp(
@@ -1134,7 +1200,11 @@ TraceEventHandle TraceLog::AddTraceEventWithThreadIdAndTimestamp(
unsigned long long bind_id,
int thread_id,
const TimeTicks& timestamp,
- TraceArguments* args,
+ int num_args,
+ const char* const* arg_names,
+ const unsigned char* arg_types,
+ const unsigned long long* arg_values,
+ std::unique_ptr<ConvertableToTraceFormat>* convertable_values,
unsigned int flags) {
TraceEventHandle handle = {0, 0, 0};
if (!*category_group_enabled)
@@ -1208,7 +1278,8 @@ TraceEventHandle TraceLog::AddTraceEventWithThreadIdAndTimestamp(
// acquiring the lock, which is not needed for ETW as it's already threadsafe.
if (*category_group_enabled & TraceCategory::ENABLED_FOR_ETW_EXPORT)
TraceEventETWExport::AddEvent(phase, category_group_enabled, name, id,
- args);
+ num_args, arg_names, arg_types, arg_values,
+ convertable_values);
#endif // OS_WIN
auto trace_event_override =
@@ -1216,7 +1287,8 @@ TraceEventHandle TraceLog::AddTraceEventWithThreadIdAndTimestamp(
if (trace_event_override) {
TraceEvent new_trace_event(thread_id, offset_event_timestamp, thread_now,
phase, category_group_enabled, name, scope, id,
- bind_id, args, flags);
+ bind_id, num_args, arg_names, arg_types,
+ arg_values, convertable_values, flags);
trace_event_override(
&new_trace_event,
@@ -1230,7 +1302,8 @@ TraceEventHandle TraceLog::AddTraceEventWithThreadIdAndTimestamp(
if (*category_group_enabled & TraceCategory::ENABLED_FOR_FILTERING) {
auto new_trace_event = std::make_unique<TraceEvent>(
thread_id, offset_event_timestamp, thread_now, phase,
- category_group_enabled, name, scope, id, bind_id, args, flags);
+ category_group_enabled, name, scope, id, bind_id, num_args, arg_names,
+ arg_types, arg_values, convertable_values, flags);
disabled_by_filters = true;
ForEachCategoryFilter(
@@ -1263,7 +1336,8 @@ TraceEventHandle TraceLog::AddTraceEventWithThreadIdAndTimestamp(
} else {
trace_event->Reset(thread_id, offset_event_timestamp, thread_now, phase,
category_group_enabled, name, scope, id, bind_id,
- args, flags);
+ num_args, arg_names, arg_types, arg_values,
+ convertable_values, flags);
}
#if defined(OS_ANDROID)
@@ -1284,10 +1358,15 @@ TraceEventHandle TraceLog::AddTraceEventWithThreadIdAndTimestamp(
return handle;
}
-void TraceLog::AddMetadataEvent(const unsigned char* category_group_enabled,
- const char* name,
- TraceArguments* args,
- unsigned int flags) {
+void TraceLog::AddMetadataEvent(
+ const unsigned char* category_group_enabled,
+ const char* name,
+ int num_args,
+ const char* const* arg_names,
+ const unsigned char* arg_types,
+ const unsigned long long* arg_values,
+ std::unique_ptr<ConvertableToTraceFormat>* convertable_values,
+ unsigned int flags) {
HEAP_PROFILER_SCOPED_IGNORE;
int thread_id = static_cast<int>(base::PlatformThread::CurrentId());
ThreadTicks thread_now = ThreadNow();
@@ -1299,7 +1378,7 @@ void TraceLog::AddMetadataEvent(const unsigned char* category_group_enabled,
trace_event_internal::kGlobalScope, // scope
trace_event_internal::kNoId, // id
trace_event_internal::kNoId, // bind_id
- args, flags);
+ num_args, arg_names, arg_types, arg_values, convertable_values, flags);
metadata_events_.push_back(std::move(trace_event));
}
@@ -1691,10 +1770,16 @@ base::trace_event::TraceEventHandle AddTraceEvent(
const char* name,
const char* scope,
unsigned long long id,
- base::trace_event::TraceArguments* args,
+ int num_args,
+ const char* const* arg_names,
+ const unsigned char* arg_types,
+ const unsigned long long* arg_values,
+ std::unique_ptr<base::trace_event::ConvertableToTraceFormat>*
+ convertable_values,
unsigned int flags) {
return base::trace_event::TraceLog::GetInstance()->AddTraceEvent(
- phase, category_group_enabled, name, scope, id, args, flags);
+ phase, category_group_enabled, name, scope, id, num_args, arg_names,
+ arg_types, arg_values, convertable_values, flags);
}
base::trace_event::TraceEventHandle AddTraceEventWithBindId(
@@ -1704,10 +1789,16 @@ base::trace_event::TraceEventHandle AddTraceEventWithBindId(
const char* scope,
unsigned long long id,
unsigned long long bind_id,
- base::trace_event::TraceArguments* args,
+ int num_args,
+ const char* const* arg_names,
+ const unsigned char* arg_types,
+ const unsigned long long* arg_values,
+ std::unique_ptr<base::trace_event::ConvertableToTraceFormat>*
+ convertable_values,
unsigned int flags) {
return base::trace_event::TraceLog::GetInstance()->AddTraceEventWithBindId(
- phase, category_group_enabled, name, scope, id, bind_id, args, flags);
+ phase, category_group_enabled, name, scope, id, bind_id, num_args,
+ arg_names, arg_types, arg_values, convertable_values, flags);
}
base::trace_event::TraceEventHandle AddTraceEventWithProcessId(
@@ -1717,10 +1808,16 @@ base::trace_event::TraceEventHandle AddTraceEventWithProcessId(
const char* scope,
unsigned long long id,
int process_id,
- base::trace_event::TraceArguments* args,
+ int num_args,
+ const char* const* arg_names,
+ const unsigned char* arg_types,
+ const unsigned long long* arg_values,
+ std::unique_ptr<base::trace_event::ConvertableToTraceFormat>*
+ convertable_values,
unsigned int flags) {
return base::trace_event::TraceLog::GetInstance()->AddTraceEventWithProcessId(
- phase, category_group_enabled, name, scope, id, process_id, args, flags);
+ phase, category_group_enabled, name, scope, id, process_id, num_args,
+ arg_names, arg_types, arg_values, convertable_values, flags);
}
base::trace_event::TraceEventHandle AddTraceEventWithThreadIdAndTimestamp(
@@ -1731,12 +1828,18 @@ base::trace_event::TraceEventHandle AddTraceEventWithThreadIdAndTimestamp(
unsigned long long id,
int thread_id,
const base::TimeTicks& timestamp,
- base::trace_event::TraceArguments* args,
+ int num_args,
+ const char* const* arg_names,
+ const unsigned char* arg_types,
+ const unsigned long long* arg_values,
+ std::unique_ptr<base::trace_event::ConvertableToTraceFormat>*
+ convertable_values,
unsigned int flags) {
return base::trace_event::TraceLog::GetInstance()
- ->AddTraceEventWithThreadIdAndTimestamp(phase, category_group_enabled,
- name, scope, id, thread_id,
- timestamp, args, flags);
+ ->AddTraceEventWithThreadIdAndTimestamp(
+ phase, category_group_enabled, name, scope, id, thread_id, timestamp,
+ num_args, arg_names, arg_types, arg_values, convertable_values,
+ flags);
}
base::trace_event::TraceEventHandle AddTraceEventWithThreadIdAndTimestamp(
@@ -1748,20 +1851,33 @@ base::trace_event::TraceEventHandle AddTraceEventWithThreadIdAndTimestamp(
unsigned long long bind_id,
int thread_id,
const base::TimeTicks& timestamp,
- base::trace_event::TraceArguments* args,
+ int num_args,
+ const char* const* arg_names,
+ const unsigned char* arg_types,
+ const unsigned long long* arg_values,
+ std::unique_ptr<base::trace_event::ConvertableToTraceFormat>*
+ convertable_values,
unsigned int flags) {
return base::trace_event::TraceLog::GetInstance()
->AddTraceEventWithThreadIdAndTimestamp(
phase, category_group_enabled, name, scope, id, bind_id, thread_id,
- timestamp, args, flags);
+ timestamp, num_args, arg_names, arg_types, arg_values,
+ convertable_values, flags);
}
-void AddMetadataEvent(const unsigned char* category_group_enabled,
- const char* name,
- base::trace_event::TraceArguments* args,
- unsigned int flags) {
+void AddMetadataEvent(
+ const unsigned char* category_group_enabled,
+ const char* name,
+ int num_args,
+ const char* const* arg_names,
+ const unsigned char* arg_types,
+ const unsigned long long* arg_values,
+ std::unique_ptr<base::trace_event::ConvertableToTraceFormat>*
+ convertable_values,
+ unsigned int flags) {
return base::trace_event::TraceLog::GetInstance()->AddMetadataEvent(
- category_group_enabled, name, args, flags);
+ category_group_enabled, name, num_args, arg_names, arg_types, arg_values,
+ convertable_values, flags);
}
int GetNumTracesRecorded() {
@@ -1802,7 +1918,8 @@ ScopedTraceBinaryEfficient::ScopedTraceBinaryEfficient(
trace_event_internal::kGlobalScope, // scope
trace_event_internal::kNoId, // id
static_cast<int>(base::PlatformThread::CurrentId()), // thread_id
- TRACE_TIME_TICKS_NOW(), nullptr, TRACE_EVENT_FLAG_NONE);
+ TRACE_TIME_TICKS_NOW(), 0, nullptr, nullptr, nullptr, nullptr,
+ TRACE_EVENT_FLAG_NONE);
}
}
diff --git a/chromium/base/trace_event/trace_log.h b/chromium/base/trace_event/trace_log.h
index debdf7d835a..be5a483ba73 100644
--- a/chromium/base/trace_event/trace_log.h
+++ b/chromium/base/trace_event/trace_log.h
@@ -216,13 +216,20 @@ class BASE_EXPORT TraceLog : public MemoryDumpProvider {
// Called by TRACE_EVENT* macros, don't call this directly.
// If |copy| is set, |name|, |arg_name1| and |arg_name2| will be deep copied
// into the event; see "Memory scoping note" and TRACE_EVENT_COPY_XXX above.
- TraceEventHandle AddTraceEvent(char phase,
- const unsigned char* category_group_enabled,
- const char* name,
- const char* scope,
- unsigned long long id,
- TraceArguments* args,
- unsigned int flags);
+
+ // TODO(898794): Remove methods below when all callers have been updated.
+ TraceEventHandle AddTraceEvent(
+ char phase,
+ const unsigned char* category_group_enabled,
+ const char* name,
+ const char* scope,
+ unsigned long long id,
+ int num_args,
+ const char* const* arg_names,
+ const unsigned char* arg_types,
+ const unsigned long long* arg_values,
+ std::unique_ptr<ConvertableToTraceFormat>* convertable_values,
+ unsigned int flags);
TraceEventHandle AddTraceEventWithBindId(
char phase,
const unsigned char* category_group_enabled,
@@ -230,7 +237,11 @@ class BASE_EXPORT TraceLog : public MemoryDumpProvider {
const char* scope,
unsigned long long id,
unsigned long long bind_id,
- TraceArguments* args,
+ int num_args,
+ const char* const* arg_names,
+ const unsigned char* arg_types,
+ const unsigned long long* arg_values,
+ std::unique_ptr<ConvertableToTraceFormat>* convertable_values,
unsigned int flags);
TraceEventHandle AddTraceEventWithProcessId(
char phase,
@@ -239,7 +250,11 @@ class BASE_EXPORT TraceLog : public MemoryDumpProvider {
const char* scope,
unsigned long long id,
int process_id,
- TraceArguments* args,
+ int num_args,
+ const char* const* arg_names,
+ const unsigned char* arg_types,
+ const unsigned long long* arg_values,
+ std::unique_ptr<ConvertableToTraceFormat>* convertable_values,
unsigned int flags);
TraceEventHandle AddTraceEventWithThreadIdAndTimestamp(
char phase,
@@ -249,7 +264,11 @@ class BASE_EXPORT TraceLog : public MemoryDumpProvider {
unsigned long long id,
int thread_id,
const TimeTicks& timestamp,
- TraceArguments* args,
+ int num_args,
+ const char* const* arg_names,
+ const unsigned char* arg_types,
+ const unsigned long long* arg_values,
+ std::unique_ptr<ConvertableToTraceFormat>* convertable_values,
unsigned int flags);
TraceEventHandle AddTraceEventWithThreadIdAndTimestamp(
char phase,
@@ -260,14 +279,23 @@ class BASE_EXPORT TraceLog : public MemoryDumpProvider {
unsigned long long bind_id,
int thread_id,
const TimeTicks& timestamp,
- TraceArguments* args,
+ int num_args,
+ const char* const* arg_names,
+ const unsigned char* arg_types,
+ const unsigned long long* arg_values,
+ std::unique_ptr<ConvertableToTraceFormat>* convertable_values,
unsigned int flags);
// Adds a metadata event that will be written when the trace log is flushed.
- void AddMetadataEvent(const unsigned char* category_group_enabled,
- const char* name,
- TraceArguments* args,
- unsigned int flags);
+ void AddMetadataEvent(
+ const unsigned char* category_group_enabled,
+ const char* name,
+ int num_args,
+ const char* const* arg_names,
+ const unsigned char* arg_types,
+ const unsigned long long* arg_values,
+ std::unique_ptr<ConvertableToTraceFormat>* convertable_values,
+ unsigned int flags);
void UpdateTraceEventDuration(const unsigned char* category_group_enabled,
const char* name,
diff --git a/chromium/gin/v8_platform.cc b/chromium/gin/v8_platform.cc
index cdf89444b43..310b5b2be54 100644
--- a/chromium/gin/v8_platform.cc
+++ b/chromium/gin/v8_platform.cc
@@ -47,7 +47,7 @@ class ConvertableToTraceFormatWrapper final
: public base::trace_event::ConvertableToTraceFormat {
public:
explicit ConvertableToTraceFormatWrapper(
- std::unique_ptr<v8::ConvertableToTraceFormat> inner)
+ std::unique_ptr<v8::ConvertableToTraceFormat>& inner)
: inner_(std::move(inner)) {}
~ConvertableToTraceFormatWrapper() override = default;
void AppendAsTraceFormat(std::string* out) const final {
@@ -266,26 +266,6 @@ base::LazyInstance<PageAllocator>::Leaky g_page_allocator =
} // namespace
-} // namespace gin
-
-// Allow std::unique_ptr<v8::ConvertableToTraceFormat> to be a valid
-// initialization value for trace macros.
-template <>
-struct base::trace_event::TraceValue::Helper<
- std::unique_ptr<v8::ConvertableToTraceFormat>> {
- static constexpr unsigned char kType = TRACE_VALUE_TYPE_CONVERTABLE;
- static inline void SetValue(
- TraceValue* v,
- std::unique_ptr<v8::ConvertableToTraceFormat> value) {
- // NOTE: |as_convertable| is an owning pointer, so using new here
- // is acceptable.
- v->as_convertable =
- new gin::ConvertableToTraceFormatWrapper(std::move(value));
- }
-};
-
-namespace gin {
-
class V8Platform::TracingControllerImpl : public v8::TracingController {
public:
TracingControllerImpl() = default;
@@ -308,15 +288,22 @@ class V8Platform::TracingControllerImpl : public v8::TracingController {
const uint64_t* arg_values,
std::unique_ptr<v8::ConvertableToTraceFormat>* arg_convertables,
unsigned int flags) override {
- base::trace_event::TraceArguments args(
- num_args, arg_names, arg_types,
- reinterpret_cast<const unsigned long long*>(arg_values),
- arg_convertables);
+ std::unique_ptr<base::trace_event::ConvertableToTraceFormat>
+ convertables[2];
+ if (num_args > 0 && arg_types[0] == TRACE_VALUE_TYPE_CONVERTABLE) {
+ convertables[0].reset(
+ new ConvertableToTraceFormatWrapper(arg_convertables[0]));
+ }
+ if (num_args > 1 && arg_types[1] == TRACE_VALUE_TYPE_CONVERTABLE) {
+ convertables[1].reset(
+ new ConvertableToTraceFormatWrapper(arg_convertables[1]));
+ }
DCHECK_LE(num_args, 2);
base::trace_event::TraceEventHandle handle =
TRACE_EVENT_API_ADD_TRACE_EVENT_WITH_BIND_ID(
- phase, category_enabled_flag, name, scope, id, bind_id, &args,
- flags);
+ phase, category_enabled_flag, name, scope, id, bind_id, num_args,
+ arg_names, arg_types, (const long long unsigned int*)arg_values,
+ convertables, flags);
uint64_t result;
memcpy(&result, &handle, sizeof(result));
return result;
diff --git a/chromium/ppapi/shared_impl/ppb_trace_event_impl.cc b/chromium/ppapi/shared_impl/ppb_trace_event_impl.cc
index 2f26fb8c4e7..08bf7d07f48 100644
--- a/chromium/ppapi/shared_impl/ppb_trace_event_impl.cc
+++ b/chromium/ppapi/shared_impl/ppb_trace_event_impl.cc
@@ -40,15 +40,22 @@ void TraceEventImpl::AddTraceEvent(int8_t phase,
static_assert(sizeof(unsigned long long) == sizeof(uint64_t),
"unexpected data type sizes");
- // NOTE: The |arg_values| cast is required to avoid a compiler warning,
- // since uint64_t and unsigned long long are not the same type, even
- // though they have the same size, on all platforms we care about.
- base::trace_event::TraceArguments args(
- num_args, arg_names, arg_types,
- reinterpret_cast<const unsigned long long*>(arg_values));
+
base::trace_event::TraceLog::GetInstance()->AddTraceEvent(
- phase, static_cast<const unsigned char*>(category_enabled), name,
- trace_event_internal::kGlobalScope, id, &args, flags);
+ phase,
+ static_cast<const unsigned char*>(category_enabled),
+ name,
+ trace_event_internal::kGlobalScope, id,
+ num_args,
+ arg_names,
+ arg_types,
+ // This cast is necessary for LP64 systems, where uint64_t is defined as
+ // an unsigned long int, but trace_event internals are hermetic and
+ // accepts an |unsigned long long*|. The pointer types are compatible but
+ // the compiler throws an error without an explicit cast.
+ reinterpret_cast<const unsigned long long*>(arg_values),
+ NULL,
+ flags);
}
// static
@@ -64,16 +71,25 @@ void TraceEventImpl::AddTraceEventWithThreadIdAndTimestamp(
const uint8_t arg_types[],
const uint64_t arg_values[],
uint8_t flags) {
- // See above comment about the cast to |const unsigned long long*|.
- base::trace_event::TraceArguments args(
- num_args, arg_names, arg_types,
- reinterpret_cast<const unsigned long long*>(arg_values));
base::trace_event::TraceLog::GetInstance()
->AddTraceEventWithThreadIdAndTimestamp(
- phase, static_cast<const unsigned char*>(category_enabled), name,
- trace_event_internal::kGlobalScope, id, trace_event_internal::kNoId,
- thread_id, base::TimeTicks::FromInternalValue(timestamp), &args,
- flags);
+ phase,
+ static_cast<const unsigned char*>(category_enabled),
+ name,
+ trace_event_internal::kGlobalScope, id,
+ trace_event_internal::kNoId,
+ thread_id,
+ base::TimeTicks::FromInternalValue(timestamp),
+ num_args,
+ arg_names,
+ arg_types,
+ // This cast is necessary for LP64 systems, where uint64_t is defined as
+ // an unsigned long int, but trace_event internals are hermetic and
+ // accepts an |unsigned long long*|. The pointer types are compatible but
+ // the compiler throws an error without an explicit cast.
+ reinterpret_cast<const unsigned long long*>(arg_values),
+ NULL,
+ flags);
}
// static
diff --git a/chromium/services/resource_coordinator/memory_instrumentation/coordinator_impl.cc b/chromium/services/resource_coordinator/memory_instrumentation/coordinator_impl.cc
index 54c2b43f075..d539bfa7ae5 100644
--- a/chromium/services/resource_coordinator/memory_instrumentation/coordinator_impl.cc
+++ b/chromium/services/resource_coordinator/memory_instrumentation/coordinator_impl.cc
@@ -48,7 +48,7 @@ constexpr base::TimeDelta kHeapDumpTimeout = base::TimeDelta::FromSeconds(60);
// event.
class StringWrapper : public base::trace_event::ConvertableToTraceFormat {
public:
- explicit StringWrapper(std::string&& json) : json_(std::move(json)) {}
+ explicit StringWrapper(std::string json) : json_(std::move(json)) {}
void AppendAsTraceFormat(std::string* out) const override {
out->append(json_);
@@ -552,8 +552,12 @@ void CoordinatorImpl::OnDumpProcessesForTracing(
const char* char_buffer = static_cast<const char*>(mapping.get());
std::string json(char_buffer, char_buffer + size);
- base::trace_event::TraceArguments args(
- "dumps", std::make_unique<StringWrapper>(std::move(json)));
+
+ const int kTraceEventNumArgs = 1;
+ const char* const kTraceEventArgNames[] = {"dumps"};
+ const unsigned char kTraceEventArgTypes[] = {TRACE_VALUE_TYPE_CONVERTABLE};
+ std::unique_ptr<base::trace_event::ConvertableToTraceFormat> wrapper(
+ new StringWrapper(std::move(json)));
// Using the same id merges all of the heap dumps into a single detailed
// dump node in the UI.
@@ -562,7 +566,9 @@ void CoordinatorImpl::OnDumpProcessesForTracing(
base::trace_event::TraceLog::GetCategoryGroupEnabled(
base::trace_event::MemoryDumpManager::kTraceCategory),
"periodic_interval", trace_event_internal::kGlobalScope, dump_guid,
- buffer_ptr->pid, &args, TRACE_EVENT_FLAG_HAS_ID);
+ buffer_ptr->pid, kTraceEventNumArgs, kTraceEventArgNames,
+ kTraceEventArgTypes, nullptr /* arg_values */, &wrapper,
+ TRACE_EVENT_FLAG_HAS_ID);
}
FinalizeGlobalMemoryDumpIfAllManagersReplied();
diff --git a/chromium/services/resource_coordinator/public/cpp/memory_instrumentation/tracing_observer.cc b/chromium/services/resource_coordinator/public/cpp/memory_instrumentation/tracing_observer.cc
index 0fc8548bb60..b8708ffa401 100644
--- a/chromium/services/resource_coordinator/public/cpp/memory_instrumentation/tracing_observer.cc
+++ b/chromium/services/resource_coordinator/public/cpp/memory_instrumentation/tracing_observer.cc
@@ -18,6 +18,10 @@ using base::trace_event::ProcessMemoryDump;
namespace {
+const int kTraceEventNumArgs = 1;
+const char* const kTraceEventArgNames[] = {"dumps"};
+const unsigned char kTraceEventArgTypes[] = {TRACE_VALUE_TYPE_CONVERTABLE};
+
bool IsMemoryInfraTracingEnabled() {
bool enabled;
TRACE_EVENT_CATEGORY_GROUP_ENABLED(
@@ -116,14 +120,15 @@ void TracingObserver::AddToTrace(
const uint64_t dump_guid = args.dump_guid;
const char* const event_name =
base::trace_event::MemoryDumpTypeToString(args.dump_type);
- base::trace_event::TraceArguments trace_args("dumps",
- std::move(traced_value));
+ std::unique_ptr<base::trace_event::ConvertableToTraceFormat> event_value(
+ std::move(traced_value));
TRACE_EVENT_API_ADD_TRACE_EVENT_WITH_PROCESS_ID(
TRACE_EVENT_PHASE_MEMORY_DUMP,
base::trace_event::TraceLog::GetCategoryGroupEnabled(
base::trace_event::MemoryDumpManager::kTraceCategory),
event_name, trace_event_internal::kGlobalScope, dump_guid, pid,
- &trace_args, TRACE_EVENT_FLAG_HAS_ID);
+ kTraceEventNumArgs, kTraceEventArgNames, kTraceEventArgTypes,
+ nullptr /* arg_values */, &event_value, TRACE_EVENT_FLAG_HAS_ID);
}
bool TracingObserver::AddChromeDumpToTraceIfEnabled(
diff --git a/chromium/services/tracing/public/cpp/perfetto/trace_event_data_source.cc b/chromium/services/tracing/public/cpp/perfetto/trace_event_data_source.cc
index cb782c47a2c..629f8cc7dec 100644
--- a/chromium/services/tracing/public/cpp/perfetto/trace_event_data_source.cc
+++ b/chromium/services/tracing/public/cpp/perfetto/trace_event_data_source.cc
@@ -236,10 +236,9 @@ class TraceEventDataSource::ThreadLocalEventSink {
EnsureValidHandles();
- uint32_t name_index = 0;
- uint32_t category_name_index = 0;
- const size_t kMaxSize = base::trace_event::TraceArguments::kMaxSize;
- uint32_t arg_name_indices[kMaxSize] = {0};
+ int name_index = 0;
+ int category_name_index = 0;
+ int arg_name_indices[base::trace_event::kTraceMaxNumArgs] = {0};
// Populate any new string table parts first; has to be done before
// the add_trace_events() call (as the string table is part of the outer
@@ -255,8 +254,9 @@ class TraceEventDataSource::ThreadLocalEventSink {
GetStringTableIndexForString(TraceLog::GetCategoryGroupName(
trace_event->category_group_enabled()));
- for (size_t i = 0;
- i < trace_event->arg_size() && trace_event->arg_name(i); ++i) {
+ for (int i = 0;
+ i < base::trace_event::kTraceMaxNumArgs && trace_event->arg_name(i);
+ ++i) {
arg_name_indices[i] =
GetStringTableIndexForString(trace_event->arg_name(i));
}
@@ -300,7 +300,8 @@ class TraceEventDataSource::ThreadLocalEventSink {
char phase = trace_event->phase();
new_trace_event->set_phase(phase);
- for (size_t i = 0; i < trace_event->arg_size() && trace_event->arg_name(i);
+ for (int i = 0;
+ i < base::trace_event::kTraceMaxNumArgs && trace_event->arg_name(i);
++i) {
auto type = trace_event->arg_type(i);
auto* new_arg = new_trace_event->add_args();
diff --git a/chromium/skia/ext/event_tracer_impl.cc b/chromium/skia/ext/event_tracer_impl.cc
index 71ed2d11d41..82d35a61e06 100644
--- a/chromium/skia/ext/event_tracer_impl.cc
+++ b/chromium/skia/ext/event_tracer_impl.cc
@@ -47,15 +47,13 @@ SkEventTracer::Handle
const uint8_t* argTypes,
const uint64_t* argValues,
uint8_t flags) {
- base::trace_event::TraceArguments args(
- numArgs, argNames, argTypes,
- reinterpret_cast<const unsigned long long*>(argValues));
base::trace_event::TraceEventHandle handle = TRACE_EVENT_API_ADD_TRACE_EVENT(
phase, categoryEnabledFlag, name, trace_event_internal::kGlobalScope, id,
- &args, flags);
- SkEventTracer::Handle result;
- memcpy(&result, &handle, sizeof(result));
- return result;
+ numArgs, argNames, argTypes, (const long long unsigned int*)argValues,
+ NULL, flags);
+ SkEventTracer::Handle result;
+ memcpy(&result, &handle, sizeof(result));
+ return result;
}
void
diff --git a/chromium/third_party/blink/renderer/platform/instrumentation/tracing/trace_event.h b/chromium/third_party/blink/renderer/platform/instrumentation/tracing/trace_event.h
index 5d8d61d3cd9..97e1475fa58 100644
--- a/chromium/third_party/blink/renderer/platform/instrumentation/tracing/trace_event.h
+++ b/chromium/third_party/blink/renderer/platform/instrumentation/tracing/trace_event.h
@@ -11,14 +11,19 @@
#include "third_party/blink/renderer/platform/wtf/text/cstring.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
-// Conversion from CString to TraceValue so that trace arguments can be strings.
-template <>
-struct base::trace_event::TraceValue::Helper<WTF::CString> {
- static constexpr unsigned char kType = TRACE_VALUE_TYPE_COPY_STRING;
- static inline void SetValue(TraceValue* v, const WTF::CString& value) {
- v->as_string = value.data();
- }
-};
+namespace WTF {
+
+// CString version of SetTraceValue so that trace arguments can be strings.
+static inline void SetTraceValue(const CString& arg,
+ unsigned char* type,
+ unsigned long long* value) {
+ trace_event_internal::TraceValueUnion type_value;
+ type_value.as_string = arg.data();
+ *type = TRACE_VALUE_TYPE_COPY_STRING;
+ *value = type_value.as_uint;
+}
+
+} // namespace WTF
namespace blink {
namespace trace_event {
diff --git a/chromium/third_party/webrtc_overrides/init_webrtc.cc b/chromium/third_party/webrtc_overrides/init_webrtc.cc
index db086b6f758..10df8b47eb1 100644
--- a/chromium/third_party/webrtc_overrides/init_webrtc.cc
+++ b/chromium/third_party/webrtc_overrides/init_webrtc.cc
@@ -28,11 +28,9 @@ void AddTraceEvent(char phase,
const unsigned char* arg_types,
const unsigned long long* arg_values,
unsigned char flags) {
- base::trace_event::TraceArguments args(num_args, arg_names, arg_types,
- arg_values);
- TRACE_EVENT_API_ADD_TRACE_EVENT(phase, category_group_enabled, name,
- trace_event_internal::kGlobalScope, id, &args,
- flags);
+ TRACE_EVENT_API_ADD_TRACE_EVENT(
+ phase, category_group_enabled, name, trace_event_internal::kGlobalScope,
+ id, num_args, arg_names, arg_types, arg_values, NULL, flags);
}
bool InitializeWebRtcModule() {
diff --git a/chromium/ui/gl/angle_platform_impl.cc b/chromium/ui/gl/angle_platform_impl.cc
index 4e144067721..4a0bc9aef25 100644
--- a/chromium/ui/gl/angle_platform_impl.cc
+++ b/chromium/ui/gl/angle_platform_impl.cc
@@ -66,13 +66,12 @@ TraceEventHandle ANGLEPlatformImpl_addTraceEvent(
unsigned char flags) {
base::TimeTicks timestamp_tt =
base::TimeTicks() + base::TimeDelta::FromSecondsD(timestamp);
- base::trace_event::TraceArguments args(num_args, arg_names, arg_types,
- arg_values);
base::trace_event::TraceEventHandle handle =
TRACE_EVENT_API_ADD_TRACE_EVENT_WITH_THREAD_ID_AND_TIMESTAMP(
phase, category_group_enabled, name,
trace_event_internal::kGlobalScope, id, trace_event_internal::kNoId,
- base::PlatformThread::CurrentId(), timestamp_tt, &args, flags);
+ base::PlatformThread::CurrentId(), timestamp_tt, num_args, arg_names,
+ arg_types, arg_values, nullptr, flags);
TraceEventHandle result;
memcpy(&result, &handle, sizeof(result));
return result;