Remove base/trace_event/
Change-Id: If14b91e0adfcebd178728abf55677802fc758e8f
Reviewed-on: https://gn-review.googlesource.com/1405
Reviewed-by: Brett Wilson <brettw@chromium.org>
Commit-Queue: Scott Graham <scottmg@chromium.org>
diff --git a/base/debug/task_annotator.cc b/base/debug/task_annotator.cc
index 2197b85..def2d7a 100644
--- a/base/debug/task_annotator.cc
+++ b/base/debug/task_annotator.cc
@@ -11,7 +11,6 @@
#include "base/no_destructor.h"
#include "base/pending_task.h"
#include "base/threading/thread_local.h"
-#include "base/trace_event/trace_event.h"
namespace base {
namespace debug {
@@ -37,13 +36,6 @@
void TaskAnnotator::DidQueueTask(const char* queue_function,
const PendingTask& pending_task) {
- if (queue_function) {
- TRACE_EVENT_WITH_FLOW0(TRACE_DISABLED_BY_DEFAULT("toplevel.flow"),
- queue_function,
- TRACE_ID_MANGLE(GetTaskTraceID(pending_task)),
- TRACE_EVENT_FLAG_FLOW_OUT);
- }
-
// TODO(https://crbug.com/826902): Fix callers that invoke DidQueueTask()
// twice for the same PendingTask.
// DCHECK(!pending_task.task_backtrace[0])
@@ -64,13 +56,6 @@
PendingTask* pending_task) {
ScopedTaskRunActivity task_activity(*pending_task);
- if (queue_function) {
- TRACE_EVENT_WITH_FLOW0(TRACE_DISABLED_BY_DEFAULT("toplevel.flow"),
- queue_function,
- TRACE_ID_MANGLE(GetTaskTraceID(*pending_task)),
- TRACE_EVENT_FLAG_FLOW_IN);
- }
-
// Before running the task, store the task backtrace with the chain of
// PostTasks that resulted in this call and deliberately alias it to ensure
// it is on the stack if the task crashes. Be careful not to assume that the
diff --git a/base/files/file_path_watcher_linux.cc b/base/files/file_path_watcher_linux.cc
index c58d686..75677d4 100644
--- a/base/files/file_path_watcher_linux.cc
+++ b/base/files/file_path_watcher_linux.cc
@@ -36,7 +36,6 @@
#include "base/synchronization/lock.h"
#include "base/threading/platform_thread.h"
#include "base/threading/sequenced_task_runner_handle.h"
-#include "base/trace_event/trace_event.h"
namespace base {
diff --git a/base/memory/memory_pressure_listener.cc b/base/memory/memory_pressure_listener.cc
index 669fb17..3768283 100644
--- a/base/memory/memory_pressure_listener.cc
+++ b/base/memory/memory_pressure_listener.cc
@@ -5,7 +5,6 @@
#include "base/memory/memory_pressure_listener.h"
#include "base/observer_list_threadsafe.h"
-#include "base/trace_event/trace_event.h"
namespace base {
diff --git a/base/memory/shared_memory_posix.cc b/base/memory/shared_memory_posix.cc
index 6b53551..f868eb2 100644
--- a/base/memory/shared_memory_posix.cc
+++ b/base/memory/shared_memory_posix.cc
@@ -23,7 +23,6 @@
#include "base/scoped_generic.h"
#include "base/strings/utf_string_conversions.h"
#include "base/threading/thread_restrictions.h"
-#include "base/trace_event/trace_event.h"
#include "base/unguessable_token.h"
#include "build_config.h"
diff --git a/base/memory/shared_memory_tracker.cc b/base/memory/shared_memory_tracker.cc
index 5ca7c84..ee2b490 100644
--- a/base/memory/shared_memory_tracker.cc
+++ b/base/memory/shared_memory_tracker.cc
@@ -6,9 +6,6 @@
#include "base/memory/shared_memory.h"
#include "base/strings/string_number_conversions.h"
-#include "base/trace_event/memory_allocator_dump_guid.h"
-#include "base/trace_event/memory_dump_manager.h"
-#include "base/trace_event/process_memory_dump.h"
namespace base {
@@ -27,32 +24,6 @@
return std::string(kDumpRootName) + "/" + id.ToString();
}
-// static
-trace_event::MemoryAllocatorDumpGuid
-SharedMemoryTracker::GetGlobalDumpIdForTracing(const UnguessableToken& id) {
- std::string dump_name = GetDumpNameForTracing(id);
- return trace_event::MemoryAllocatorDumpGuid(dump_name);
-}
-
-// static
-const trace_event::MemoryAllocatorDump*
-SharedMemoryTracker::GetOrCreateSharedMemoryDump(
- const SharedMemory* shared_memory,
- trace_event::ProcessMemoryDump* pmd) {
- return GetOrCreateSharedMemoryDumpInternal(shared_memory->memory(),
- shared_memory->mapped_size(),
- shared_memory->mapped_id(), pmd);
-}
-
-const trace_event::MemoryAllocatorDump*
-SharedMemoryTracker::GetOrCreateSharedMemoryDump(
- const SharedMemoryMapping& shared_memory,
- trace_event::ProcessMemoryDump* pmd) {
- return GetOrCreateSharedMemoryDumpInternal(shared_memory.raw_memory_ptr(),
- shared_memory.mapped_size(),
- shared_memory.guid(), pmd);
-}
-
void SharedMemoryTracker::IncrementMemoryUsage(
const SharedMemory& shared_memory) {
AutoLock hold(usages_lock_);
@@ -84,64 +55,8 @@
}
SharedMemoryTracker::SharedMemoryTracker() {
- trace_event::MemoryDumpManager::GetInstance()->RegisterDumpProvider(
- this, "SharedMemoryTracker", nullptr);
}
SharedMemoryTracker::~SharedMemoryTracker() = default;
-bool SharedMemoryTracker::OnMemoryDump(const trace_event::MemoryDumpArgs& args,
- trace_event::ProcessMemoryDump* pmd) {
- AutoLock hold(usages_lock_);
- for (const auto& usage : usages_) {
- const trace_event::MemoryAllocatorDump* dump =
- GetOrCreateSharedMemoryDumpInternal(
- usage.first, usage.second.mapped_size, usage.second.mapped_id, pmd);
- DCHECK(dump);
- }
- return true;
-}
-
-// static
-const trace_event::MemoryAllocatorDump*
-SharedMemoryTracker::GetOrCreateSharedMemoryDumpInternal(
- void* mapped_memory,
- size_t mapped_size,
- const UnguessableToken& mapped_id,
- trace_event::ProcessMemoryDump* pmd) {
- const std::string dump_name = GetDumpNameForTracing(mapped_id);
- trace_event::MemoryAllocatorDump* local_dump =
- pmd->GetAllocatorDump(dump_name);
- if (local_dump)
- return local_dump;
-
- size_t virtual_size = mapped_size;
- // If resident size is not available, a virtual size is used as fallback.
- size_t size = virtual_size;
-#if defined(COUNT_RESIDENT_BYTES_SUPPORTED)
- base::Optional<size_t> resident_size =
- trace_event::ProcessMemoryDump::CountResidentBytesInSharedMemory(
- mapped_memory, mapped_size);
- if (resident_size.has_value())
- size = resident_size.value();
-#endif
-
- local_dump = pmd->CreateAllocatorDump(dump_name);
- local_dump->AddScalar(trace_event::MemoryAllocatorDump::kNameSize,
- trace_event::MemoryAllocatorDump::kUnitsBytes, size);
- local_dump->AddScalar("virtual_size",
- trace_event::MemoryAllocatorDump::kUnitsBytes,
- virtual_size);
- auto global_dump_guid = GetGlobalDumpIdForTracing(mapped_id);
- trace_event::MemoryAllocatorDump* global_dump =
- pmd->CreateSharedGlobalAllocatorDump(global_dump_guid);
- global_dump->AddScalar(trace_event::MemoryAllocatorDump::kNameSize,
- trace_event::MemoryAllocatorDump::kUnitsBytes, size);
-
- // The edges will be overriden by the clients with correct importance.
- pmd->AddOverridableOwnershipEdge(local_dump->guid(), global_dump->guid(),
- 0 /* importance */);
- return local_dump;
-}
-
} // namespace
diff --git a/base/memory/shared_memory_tracker.h b/base/memory/shared_memory_tracker.h
index 499b172..72c7b7a 100644
--- a/base/memory/shared_memory_tracker.h
+++ b/base/memory/shared_memory_tracker.h
@@ -11,39 +11,17 @@
#include "base/memory/shared_memory.h"
#include "base/memory/shared_memory_mapping.h"
#include "base/synchronization/lock.h"
-#include "base/trace_event/memory_dump_provider.h"
namespace base {
-namespace trace_event {
-class MemoryAllocatorDump;
-class MemoryAllocatorDumpGuid;
-class ProcessMemoryDump;
-}
-
// SharedMemoryTracker tracks shared memory usage.
-class BASE_EXPORT SharedMemoryTracker : public trace_event::MemoryDumpProvider {
+class BASE_EXPORT SharedMemoryTracker {
public:
// Returns a singleton instance.
static SharedMemoryTracker* GetInstance();
static std::string GetDumpNameForTracing(const UnguessableToken& id);
- static trace_event::MemoryAllocatorDumpGuid GetGlobalDumpIdForTracing(
- const UnguessableToken& id);
-
- // Gets or creates if non-existant, a memory dump for the |shared_memory|
- // inside the given |pmd|. Also adds the necessary edges for the dump when
- // creating the dump.
- static const trace_event::MemoryAllocatorDump* GetOrCreateSharedMemoryDump(
- const SharedMemory* shared_memory,
- trace_event::ProcessMemoryDump* pmd);
- // We're in the middle of a refactor https://crbug.com/795291. Eventually, the
- // first call will go away.
- static const trace_event::MemoryAllocatorDump* GetOrCreateSharedMemoryDump(
- const SharedMemoryMapping& shared_memory,
- trace_event::ProcessMemoryDump* pmd);
-
// Records shared memory usage on valid mapping.
void IncrementMemoryUsage(const SharedMemory& shared_memory);
void IncrementMemoryUsage(const SharedMemoryMapping& mapping);
@@ -57,17 +35,7 @@
private:
SharedMemoryTracker();
- ~SharedMemoryTracker() override;
-
- // trace_event::MemoryDumpProvider implementation.
- bool OnMemoryDump(const trace_event::MemoryDumpArgs& args,
- trace_event::ProcessMemoryDump* pmd) override;
-
- static const trace_event::MemoryAllocatorDump*
- GetOrCreateSharedMemoryDumpInternal(void* mapped_memory,
- size_t mapped_size,
- const UnguessableToken& mapped_id,
- trace_event::ProcessMemoryDump* pmd);
+ ~SharedMemoryTracker();
// Information associated with each mapped address.
struct UsageInfo {
diff --git a/base/message_loop/message_loop.cc b/base/message_loop/message_loop.cc
index a7c3f25..0953aaf 100644
--- a/base/message_loop/message_loop.cc
+++ b/base/message_loop/message_loop.cc
@@ -18,7 +18,6 @@
#include "base/third_party/dynamic_annotations/dynamic_annotations.h"
#include "base/threading/thread_id_name_manager.h"
#include "base/threading/thread_task_runner_handle.h"
-#include "base/trace_event/trace_event.h"
#if defined(OS_MACOSX)
#include "base/message_loop/message_pump_mac.h"
@@ -312,8 +311,6 @@
// Execute the task and assume the worst: It is probably not reentrant.
task_execution_allowed_ = false;
- TRACE_TASK_EXECUTION("MessageLoop::RunTask", *pending_task);
-
for (auto& observer : task_observers_)
observer.WillProcessTask(*pending_task);
incoming_task_queue_->RunTask(pending_task);
diff --git a/base/message_loop/message_pump_libevent.cc b/base/message_loop/message_pump_libevent.cc
index a8efd27..2b47681 100644
--- a/base/message_loop/message_pump_libevent.cc
+++ b/base/message_loop/message_pump_libevent.cc
@@ -16,7 +16,6 @@
#include "base/posix/eintr_wrapper.h"
#include "base/third_party/libevent/event.h"
#include "base/time/time.h"
-#include "base/trace_event/trace_event.h"
#include "build_config.h"
#if defined(OS_MACOSX)
@@ -306,11 +305,6 @@
void* context) {
FdWatchController* controller = static_cast<FdWatchController*>(context);
DCHECK(controller);
- TRACE_EVENT2("toplevel", "MessagePumpLibevent::OnLibeventNotification",
- "src_file", controller->created_from_location().file_name(),
- "src_func", controller->created_from_location().function_name());
- TRACE_HEAP_PROFILER_API_SCOPED_TASK_EXECUTION heap_profiler_scope(
- controller->created_from_location().file_name());
MessagePumpLibevent* pump = controller->pump();
pump->processed_io_events_ = true;
diff --git a/base/message_loop/message_pump_win.cc b/base/message_loop/message_pump_win.cc
index 8e6f1f4..47cf477 100644
--- a/base/message_loop/message_pump_win.cc
+++ b/base/message_loop/message_pump_win.cc
@@ -13,7 +13,6 @@
#include "base/memory/ptr_util.h"
#include "base/metrics/histogram_macros.h"
#include "base/strings/stringprintf.h"
-#include "base/trace_event/trace_event.h"
#include "base/win/current_module.h"
#include "base/win/wrapped_window_proc.h"
@@ -347,8 +346,6 @@
}
bool MessagePumpForUI::ProcessMessageHelper(const MSG& msg) {
- TRACE_EVENT1("base", "MessagePumpForUI::ProcessMessageHelper",
- "message", msg.message);
if (WM_QUIT == msg.message) {
// WM_QUIT is the standard way to exit a GetMessage() loop. Our MessageLoop
// has its own quit mechanism, so WM_QUIT is unexpected and should be
diff --git a/base/process/launch_posix.cc b/base/process/launch_posix.cc
index d1690bc..1004012 100644
--- a/base/process/launch_posix.cc
+++ b/base/process/launch_posix.cc
@@ -42,7 +42,6 @@
#include "base/threading/platform_thread.h"
#include "base/threading/thread_restrictions.h"
#include "base/time/time.h"
-#include "base/trace_event/trace_event.h"
#include "build_config.h"
#if defined(OS_LINUX) || defined(OS_AIX)
diff --git a/base/task_scheduler/scheduler_worker.cc b/base/task_scheduler/scheduler_worker.cc
index d3b8c0c..33b400a 100644
--- a/base/task_scheduler/scheduler_worker.cc
+++ b/base/task_scheduler/scheduler_worker.cc
@@ -13,7 +13,6 @@
#include "base/logging.h"
#include "base/task_scheduler/scheduler_worker_observer.h"
#include "base/task_scheduler/task_tracker.h"
-#include "base/trace_event/trace_event.h"
#if defined(OS_MACOSX)
#include "base/mac/scoped_nsautorelease_pool.h"
@@ -274,7 +273,6 @@
void SchedulerWorker::RunWorker() {
DCHECK_EQ(self_, this);
- TRACE_EVENT_BEGIN0("task_scheduler", "SchedulerWorkerThread active");
if (scheduler_worker_observer_)
scheduler_worker_observer_->OnSchedulerWorkerMainEntry();
@@ -283,9 +281,7 @@
// A SchedulerWorker starts out waiting for work.
{
- TRACE_EVENT_END0("task_scheduler", "SchedulerWorkerThread active");
delegate_->WaitForWork(&wake_up_event_);
- TRACE_EVENT_BEGIN0("task_scheduler", "SchedulerWorkerThread active");
}
// When defined(COM_INIT_CHECK_HOOK_ENABLED), ignore
@@ -311,9 +307,7 @@
if (ShouldExit())
break;
- TRACE_EVENT_END0("task_scheduler", "SchedulerWorkerThread active");
delegate_->WaitForWork(&wake_up_event_);
- TRACE_EVENT_BEGIN0("task_scheduler", "SchedulerWorkerThread active");
continue;
}
@@ -345,8 +339,6 @@
// Release the self-reference to |this|. This can result in deleting |this|
// and as such no more member accesses should be made after this point.
self_ = nullptr;
-
- TRACE_EVENT_END0("task_scheduler", "SchedulerWorkerThread active");
}
} // namespace internal
diff --git a/base/task_scheduler/task_tracker.cc b/base/task_scheduler/task_tracker.cc
index 5c98b5c..4fd2356 100644
--- a/base/task_scheduler/task_tracker.cc
+++ b/base/task_scheduler/task_tracker.cc
@@ -15,6 +15,7 @@
#include "base/memory/ptr_util.h"
#include "base/metrics/histogram_macros.h"
#include "base/sequence_token.h"
+#include "base/strings/string_util.h"
#include "base/synchronization/condition_variable.h"
#include "base/task_scheduler/scoped_set_task_priority_for_current_thread.h"
#include "base/threading/sequence_local_storage_map.h"
@@ -22,7 +23,6 @@
#include "base/threading/thread_restrictions.h"
#include "base/threading/thread_task_runner_handle.h"
#include "base/time/time.h"
-#include "base/trace_event/trace_event.h"
#include "base/values.h"
namespace base {
@@ -35,7 +35,7 @@
constexpr char kSingleThreadExecutionMode[] = "single thread";
// An immutable copy of a scheduler task's info required by tracing.
-class TaskTracingInfo : public trace_event::ConvertableToTraceFormat {
+class TaskTracingInfo {
public:
TaskTracingInfo(const TaskTraits& task_traits,
const char* execution_mode,
@@ -44,9 +44,6 @@
execution_mode_(execution_mode),
sequence_token_(sequence_token) {}
- // trace_event::ConvertableToTraceFormat implementation.
- void AppendAsTraceFormat(std::string* out) const override;
-
private:
const TaskTraits task_traits_;
const char* const execution_mode_;
@@ -55,28 +52,11 @@
DISALLOW_COPY_AND_ASSIGN(TaskTracingInfo);
};
-void TaskTracingInfo::AppendAsTraceFormat(std::string* out) const {
- DictionaryValue dict;
-
- dict.SetString("task_priority",
- base::TaskPriorityToString(task_traits_.priority()));
- dict.SetString("execution_mode", execution_mode_);
- if (execution_mode_ != kParallelExecutionMode)
- dict.SetInteger("sequence_token", sequence_token_.ToInternalValue());
-
- std::string tmp;
- JSONWriter::Write(dict, &tmp);
- out->append(tmp);
-}
-
// These name conveys that a Task is posted to/run by the task scheduler without
// revealing its implementation details.
constexpr char kQueueFunctionName[] = "TaskScheduler PostTask";
constexpr char kRunFunctionName[] = "TaskScheduler RunTask";
-constexpr char kTaskSchedulerFlowTracingCategory[] =
- TRACE_DISABLED_BY_DEFAULT("task_scheduler.flow");
-
// Constructs a histogram to track latency which is logging to
// "TaskScheduler.{histogram_name}.{histogram_label}.{task_type_suffix}".
HistogramBase* GetLatencyHistogram(StringPiece histogram_name,
@@ -347,13 +327,6 @@
if (task.delayed_run_time.is_null())
subtle::NoBarrier_AtomicIncrement(&num_incomplete_undelayed_tasks_, 1);
- {
- TRACE_EVENT_WITH_FLOW0(
- kTaskSchedulerFlowTracingCategory, kQueueFunctionName,
- TRACE_ID_MANGLE(task_annotator_.GetTaskTraceID(task)),
- TRACE_EVENT_FLAG_FLOW_OUT);
- }
-
task_annotator_.DidQueueTask(nullptr, task);
return true;
@@ -496,29 +469,6 @@
}
if (can_run_task) {
- TRACE_TASK_EXECUTION(kRunFunctionName, task);
-
- const char* const execution_mode =
- task.single_thread_task_runner_ref
- ? kSingleThreadExecutionMode
- : (task.sequenced_task_runner_ref ? kSequencedExecutionMode
- : kParallelExecutionMode);
- // TODO(gab): In a better world this would be tacked on as an extra arg
- // to the trace event generated above. This is not possible however until
- // http://crbug.com/652692 is resolved.
- TRACE_EVENT1("task_scheduler", "TaskTracker::RunTask", "task_info",
- std::make_unique<TaskTracingInfo>(
- task.traits, execution_mode, sequence_token));
-
- {
- // Put this in its own scope so it preceeds rather than overlaps with
- // RunTask() in the trace view.
- TRACE_EVENT_WITH_FLOW0(
- kTaskSchedulerFlowTracingCategory, kQueueFunctionName,
- TRACE_ID_MANGLE(task_annotator_.GetTaskTraceID(task)),
- TRACE_EVENT_FLAG_FLOW_IN);
- }
-
task_annotator_.RunTask(nullptr, &task);
}
diff --git a/base/test/test_mock_time_task_runner.h b/base/test/test_mock_time_task_runner.h
index 23dbb2f..993db05 100644
--- a/base/test/test_mock_time_task_runner.h
+++ b/base/test/test_mock_time_task_runner.h
@@ -17,6 +17,7 @@
#include "base/macros.h"
#include "base/run_loop.h"
#include "base/single_thread_task_runner.h"
+#include "base/synchronization/condition_variable.h"
#include "base/synchronization/lock.h"
#include "base/test/test_pending_task.h"
#include "base/threading/thread_checker_impl.h"
diff --git a/base/test/test_pending_task.cc b/base/test/test_pending_task.cc
index f9cfa8e..bb81eaa 100644
--- a/base/test/test_pending_task.cc
+++ b/base/test/test_pending_task.cc
@@ -38,44 +38,4 @@
TestPendingTask::~TestPendingTask() = default;
-void TestPendingTask::AsValueInto(base::trace_event::TracedValue* state) const {
- state->SetInteger("run_at", GetTimeToRun().ToInternalValue());
- state->SetString("posting_function", location.ToString());
- state->SetInteger("post_time", post_time.ToInternalValue());
- state->SetInteger("delay", delay.ToInternalValue());
- switch (nestability) {
- case NESTABLE:
- state->SetString("nestability", "NESTABLE");
- break;
- case NON_NESTABLE:
- state->SetString("nestability", "NON_NESTABLE");
- break;
- }
- state->SetInteger("delay", delay.ToInternalValue());
-}
-
-std::unique_ptr<base::trace_event::ConvertableToTraceFormat>
-TestPendingTask::AsValue() const {
- std::unique_ptr<base::trace_event::TracedValue> state(
- new base::trace_event::TracedValue());
- AsValueInto(state.get());
- return std::move(state);
-}
-
-std::string TestPendingTask::ToString() const {
- std::string output("TestPendingTask(");
- AsValue()->AppendAsTraceFormat(&output);
- output += ")";
- return output;
-}
-
-std::ostream& operator<<(std::ostream& os, const TestPendingTask& task) {
- PrintTo(task, &os);
- return os;
-}
-
-void PrintTo(const TestPendingTask& task, std::ostream* os) {
- *os << task.ToString();
-}
-
} // namespace base
diff --git a/base/test/test_pending_task.h b/base/test/test_pending_task.h
index 460de0e..5e607ac 100644
--- a/base/test/test_pending_task.h
+++ b/base/test/test_pending_task.h
@@ -10,7 +10,6 @@
#include "base/callback.h"
#include "base/location.h"
#include "base/time/time.h"
-#include "base/trace_event/trace_event_argument.h"
namespace base {
@@ -58,21 +57,10 @@
TimeDelta delay;
TestNestability nestability;
- // Functions for using test pending task with tracing, useful in unit
- // testing.
- void AsValueInto(base::trace_event::TracedValue* state) const;
- std::unique_ptr<base::trace_event::ConvertableToTraceFormat> AsValue() const;
- std::string ToString() const;
-
private:
DISALLOW_COPY_AND_ASSIGN(TestPendingTask);
};
-// gtest helpers which allow pretty printing of the tasks, very useful in unit
-// testing.
-std::ostream& operator<<(std::ostream& os, const TestPendingTask& task);
-void PrintTo(const TestPendingTask& task, std::ostream* os);
-
} // namespace base
#endif // BASE_TEST_TEST_PENDING_TASK_H_
diff --git a/base/test/trace_event_analyzer.cc b/base/test/trace_event_analyzer.cc
deleted file mode 100644
index cab2899..0000000
--- a/base/test/trace_event_analyzer.cc
+++ /dev/null
@@ -1,1069 +0,0 @@
-// Copyright (c) 2012 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/test/trace_event_analyzer.h"
-
-#include <math.h>
-
-#include <algorithm>
-#include <set>
-
-#include "base/json/json_reader.h"
-#include "base/memory/ptr_util.h"
-#include "base/memory/ref_counted_memory.h"
-#include "base/run_loop.h"
-#include "base/strings/pattern.h"
-#include "base/trace_event/trace_buffer.h"
-#include "base/trace_event/trace_config.h"
-#include "base/trace_event/trace_log.h"
-#include "base/values.h"
-
-namespace {
-void OnTraceDataCollected(base::OnceClosure quit_closure,
- base::trace_event::TraceResultBuffer* buffer,
- const scoped_refptr<base::RefCountedString>& json,
- bool has_more_events) {
- buffer->AddFragment(json->data());
- if (!has_more_events)
- std::move(quit_closure).Run();
-}
-} // namespace
-
-namespace trace_analyzer {
-
-// TraceEvent
-
-TraceEvent::TraceEvent()
- : thread(0, 0),
- timestamp(0),
- duration(0),
- phase(TRACE_EVENT_PHASE_BEGIN),
- other_event(nullptr) {}
-
-TraceEvent::TraceEvent(TraceEvent&& other) = default;
-
-TraceEvent::~TraceEvent() = default;
-
-TraceEvent& TraceEvent::operator=(TraceEvent&& rhs) = default;
-
-bool TraceEvent::SetFromJSON(const base::Value* event_value) {
- if (event_value->type() != base::Value::Type::DICTIONARY) {
- LOG(ERROR) << "Value must be Type::DICTIONARY";
- return false;
- }
- const base::DictionaryValue* dictionary =
- static_cast<const base::DictionaryValue*>(event_value);
-
- std::string phase_str;
- const base::DictionaryValue* args = nullptr;
-
- if (!dictionary->GetString("ph", &phase_str)) {
- LOG(ERROR) << "ph is missing from TraceEvent JSON";
- return false;
- }
-
- phase = *phase_str.data();
-
- bool may_have_duration = (phase == TRACE_EVENT_PHASE_COMPLETE);
- bool require_origin = (phase != TRACE_EVENT_PHASE_METADATA);
- bool require_id = (phase == TRACE_EVENT_PHASE_ASYNC_BEGIN ||
- phase == TRACE_EVENT_PHASE_ASYNC_STEP_INTO ||
- phase == TRACE_EVENT_PHASE_ASYNC_STEP_PAST ||
- phase == TRACE_EVENT_PHASE_MEMORY_DUMP ||
- phase == TRACE_EVENT_PHASE_ENTER_CONTEXT ||
- phase == TRACE_EVENT_PHASE_LEAVE_CONTEXT ||
- phase == TRACE_EVENT_PHASE_CREATE_OBJECT ||
- phase == TRACE_EVENT_PHASE_DELETE_OBJECT ||
- phase == TRACE_EVENT_PHASE_SNAPSHOT_OBJECT ||
- phase == TRACE_EVENT_PHASE_ASYNC_END);
-
- if (require_origin && !dictionary->GetInteger("pid", &thread.process_id)) {
- LOG(ERROR) << "pid is missing from TraceEvent JSON";
- return false;
- }
- if (require_origin && !dictionary->GetInteger("tid", &thread.thread_id)) {
- LOG(ERROR) << "tid is missing from TraceEvent JSON";
- return false;
- }
- if (require_origin && !dictionary->GetDouble("ts", ×tamp)) {
- LOG(ERROR) << "ts is missing from TraceEvent JSON";
- return false;
- }
- if (may_have_duration) {
- dictionary->GetDouble("dur", &duration);
- }
- if (!dictionary->GetString("cat", &category)) {
- LOG(ERROR) << "cat is missing from TraceEvent JSON";
- return false;
- }
- if (!dictionary->GetString("name", &name)) {
- LOG(ERROR) << "name is missing from TraceEvent JSON";
- return false;
- }
- if (!dictionary->GetDictionary("args", &args)) {
- LOG(ERROR) << "args is missing from TraceEvent JSON";
- return false;
- }
- if (require_id && !dictionary->GetString("id", &id)) {
- LOG(ERROR) << "id is missing from ASYNC_BEGIN/ASYNC_END TraceEvent JSON";
- return false;
- }
-
- dictionary->GetDouble("tdur", &thread_duration);
- dictionary->GetDouble("tts", &thread_timestamp);
- dictionary->GetString("scope", &scope);
- dictionary->GetString("bind_id", &bind_id);
- dictionary->GetBoolean("flow_out", &flow_out);
- dictionary->GetBoolean("flow_in", &flow_in);
-
- const base::DictionaryValue* id2;
- if (dictionary->GetDictionary("id2", &id2)) {
- id2->GetString("global", &global_id2);
- id2->GetString("local", &local_id2);
- }
-
- // For each argument, copy the type and create a trace_analyzer::TraceValue.
- for (base::DictionaryValue::Iterator it(*args); !it.IsAtEnd();
- it.Advance()) {
- std::string str;
- bool boolean = false;
- int int_num = 0;
- double double_num = 0.0;
- if (it.value().GetAsString(&str)) {
- arg_strings[it.key()] = str;
- } else if (it.value().GetAsInteger(&int_num)) {
- arg_numbers[it.key()] = static_cast<double>(int_num);
- } else if (it.value().GetAsBoolean(&boolean)) {
- arg_numbers[it.key()] = static_cast<double>(boolean ? 1 : 0);
- } else if (it.value().GetAsDouble(&double_num)) {
- arg_numbers[it.key()] = double_num;
- }
- // Record all arguments as values.
- arg_values[it.key()] = it.value().CreateDeepCopy();
- }
-
- return true;
-}
-
-double TraceEvent::GetAbsTimeToOtherEvent() const {
- return fabs(other_event->timestamp - timestamp);
-}
-
-bool TraceEvent::GetArgAsString(const std::string& name,
- std::string* arg) const {
- const auto it = arg_strings.find(name);
- if (it != arg_strings.end()) {
- *arg = it->second;
- return true;
- }
- return false;
-}
-
-bool TraceEvent::GetArgAsNumber(const std::string& name,
- double* arg) const {
- const auto it = arg_numbers.find(name);
- if (it != arg_numbers.end()) {
- *arg = it->second;
- return true;
- }
- return false;
-}
-
-bool TraceEvent::GetArgAsValue(const std::string& name,
- std::unique_ptr<base::Value>* arg) const {
- const auto it = arg_values.find(name);
- if (it != arg_values.end()) {
- *arg = it->second->CreateDeepCopy();
- return true;
- }
- return false;
-}
-
-bool TraceEvent::HasStringArg(const std::string& name) const {
- return (arg_strings.find(name) != arg_strings.end());
-}
-
-bool TraceEvent::HasNumberArg(const std::string& name) const {
- return (arg_numbers.find(name) != arg_numbers.end());
-}
-
-bool TraceEvent::HasArg(const std::string& name) const {
- return (arg_values.find(name) != arg_values.end());
-}
-
-std::string TraceEvent::GetKnownArgAsString(const std::string& name) const {
- std::string arg_string;
- bool result = GetArgAsString(name, &arg_string);
- DCHECK(result);
- return arg_string;
-}
-
-double TraceEvent::GetKnownArgAsDouble(const std::string& name) const {
- double arg_double = 0;
- bool result = GetArgAsNumber(name, &arg_double);
- DCHECK(result);
- return arg_double;
-}
-
-int TraceEvent::GetKnownArgAsInt(const std::string& name) const {
- double arg_double = 0;
- bool result = GetArgAsNumber(name, &arg_double);
- DCHECK(result);
- return static_cast<int>(arg_double);
-}
-
-bool TraceEvent::GetKnownArgAsBool(const std::string& name) const {
- double arg_double = 0;
- bool result = GetArgAsNumber(name, &arg_double);
- DCHECK(result);
- return (arg_double != 0.0);
-}
-
-std::unique_ptr<base::Value> TraceEvent::GetKnownArgAsValue(
- const std::string& name) const {
- std::unique_ptr<base::Value> arg_value;
- bool result = GetArgAsValue(name, &arg_value);
- DCHECK(result);
- return arg_value;
-}
-
-// QueryNode
-
-QueryNode::QueryNode(const Query& query) : query_(query) {
-}
-
-QueryNode::~QueryNode() = default;
-
-// Query
-
-Query::Query(TraceEventMember member)
- : type_(QUERY_EVENT_MEMBER),
- operator_(OP_INVALID),
- member_(member),
- number_(0),
- is_pattern_(false) {
-}
-
-Query::Query(TraceEventMember member, const std::string& arg_name)
- : type_(QUERY_EVENT_MEMBER),
- operator_(OP_INVALID),
- member_(member),
- number_(0),
- string_(arg_name),
- is_pattern_(false) {
-}
-
-Query::Query(const Query& query) = default;
-
-Query::~Query() = default;
-
-Query Query::String(const std::string& str) {
- return Query(str);
-}
-
-Query Query::Double(double num) {
- return Query(num);
-}
-
-Query Query::Int(int32_t num) {
- return Query(static_cast<double>(num));
-}
-
-Query Query::Uint(uint32_t num) {
- return Query(static_cast<double>(num));
-}
-
-Query Query::Bool(bool boolean) {
- return Query(boolean ? 1.0 : 0.0);
-}
-
-Query Query::Phase(char phase) {
- return Query(static_cast<double>(phase));
-}
-
-Query Query::Pattern(const std::string& pattern) {
- Query query(pattern);
- query.is_pattern_ = true;
- return query;
-}
-
-bool Query::Evaluate(const TraceEvent& event) const {
- // First check for values that can convert to bool.
-
- // double is true if != 0:
- double bool_value = 0.0;
- bool is_bool = GetAsDouble(event, &bool_value);
- if (is_bool)
- return (bool_value != 0.0);
-
- // string is true if it is non-empty:
- std::string str_value;
- bool is_str = GetAsString(event, &str_value);
- if (is_str)
- return !str_value.empty();
-
- DCHECK_EQ(QUERY_BOOLEAN_OPERATOR, type_)
- << "Invalid query: missing boolean expression";
- DCHECK(left_.get());
- DCHECK(right_.get() || is_unary_operator());
-
- if (is_comparison_operator()) {
- DCHECK(left().is_value() && right().is_value())
- << "Invalid query: comparison operator used between event member and "
- "value.";
- bool compare_result = false;
- if (CompareAsDouble(event, &compare_result))
- return compare_result;
- if (CompareAsString(event, &compare_result))
- return compare_result;
- return false;
- }
- // It's a logical operator.
- switch (operator_) {
- case OP_AND:
- return left().Evaluate(event) && right().Evaluate(event);
- case OP_OR:
- return left().Evaluate(event) || right().Evaluate(event);
- case OP_NOT:
- return !left().Evaluate(event);
- default:
- NOTREACHED();
- return false;
- }
-}
-
-bool Query::CompareAsDouble(const TraceEvent& event, bool* result) const {
- double lhs, rhs;
- if (!left().GetAsDouble(event, &lhs) || !right().GetAsDouble(event, &rhs))
- return false;
- switch (operator_) {
- case OP_EQ:
- *result = (lhs == rhs);
- return true;
- case OP_NE:
- *result = (lhs != rhs);
- return true;
- case OP_LT:
- *result = (lhs < rhs);
- return true;
- case OP_LE:
- *result = (lhs <= rhs);
- return true;
- case OP_GT:
- *result = (lhs > rhs);
- return true;
- case OP_GE:
- *result = (lhs >= rhs);
- return true;
- default:
- NOTREACHED();
- return false;
- }
-}
-
-bool Query::CompareAsString(const TraceEvent& event, bool* result) const {
- std::string lhs, rhs;
- if (!left().GetAsString(event, &lhs) || !right().GetAsString(event, &rhs))
- return false;
- switch (operator_) {
- case OP_EQ:
- if (right().is_pattern_)
- *result = base::MatchPattern(lhs, rhs);
- else if (left().is_pattern_)
- *result = base::MatchPattern(rhs, lhs);
- else
- *result = (lhs == rhs);
- return true;
- case OP_NE:
- if (right().is_pattern_)
- *result = !base::MatchPattern(lhs, rhs);
- else if (left().is_pattern_)
- *result = !base::MatchPattern(rhs, lhs);
- else
- *result = (lhs != rhs);
- return true;
- case OP_LT:
- *result = (lhs < rhs);
- return true;
- case OP_LE:
- *result = (lhs <= rhs);
- return true;
- case OP_GT:
- *result = (lhs > rhs);
- return true;
- case OP_GE:
- *result = (lhs >= rhs);
- return true;
- default:
- NOTREACHED();
- return false;
- }
-}
-
-bool Query::EvaluateArithmeticOperator(const TraceEvent& event,
- double* num) const {
- DCHECK_EQ(QUERY_ARITHMETIC_OPERATOR, type_);
- DCHECK(left_.get());
- DCHECK(right_.get() || is_unary_operator());
-
- double lhs = 0, rhs = 0;
- if (!left().GetAsDouble(event, &lhs))
- return false;
- if (!is_unary_operator() && !right().GetAsDouble(event, &rhs))
- return false;
-
- switch (operator_) {
- case OP_ADD:
- *num = lhs + rhs;
- return true;
- case OP_SUB:
- *num = lhs - rhs;
- return true;
- case OP_MUL:
- *num = lhs * rhs;
- return true;
- case OP_DIV:
- *num = lhs / rhs;
- return true;
- case OP_MOD:
- *num = static_cast<double>(static_cast<int64_t>(lhs) %
- static_cast<int64_t>(rhs));
- return true;
- case OP_NEGATE:
- *num = -lhs;
- return true;
- default:
- NOTREACHED();
- return false;
- }
-}
-
-bool Query::GetAsDouble(const TraceEvent& event, double* num) const {
- switch (type_) {
- case QUERY_ARITHMETIC_OPERATOR:
- return EvaluateArithmeticOperator(event, num);
- case QUERY_EVENT_MEMBER:
- return GetMemberValueAsDouble(event, num);
- case QUERY_NUMBER:
- *num = number_;
- return true;
- default:
- return false;
- }
-}
-
-bool Query::GetAsString(const TraceEvent& event, std::string* str) const {
- switch (type_) {
- case QUERY_EVENT_MEMBER:
- return GetMemberValueAsString(event, str);
- case QUERY_STRING:
- *str = string_;
- return true;
- default:
- return false;
- }
-}
-
-const TraceEvent* Query::SelectTargetEvent(const TraceEvent* event,
- TraceEventMember member) {
- if (member >= OTHER_FIRST_MEMBER && member <= OTHER_LAST_MEMBER) {
- return event->other_event;
- } else if (member >= PREV_FIRST_MEMBER && member <= PREV_LAST_MEMBER) {
- return event->prev_event;
- } else {
- return event;
- }
-}
-
-bool Query::GetMemberValueAsDouble(const TraceEvent& event,
- double* num) const {
- DCHECK_EQ(QUERY_EVENT_MEMBER, type_);
-
- // This could be a request for a member of |event| or a member of |event|'s
- // associated previous or next event. Store the target event in the_event:
- const TraceEvent* the_event = SelectTargetEvent(&event, member_);
-
- // Request for member of associated event, but there is no associated event.
- if (!the_event)
- return false;
-
- switch (member_) {
- case EVENT_PID:
- case OTHER_PID:
- case PREV_PID:
- *num = static_cast<double>(the_event->thread.process_id);
- return true;
- case EVENT_TID:
- case OTHER_TID:
- case PREV_TID:
- *num = static_cast<double>(the_event->thread.thread_id);
- return true;
- case EVENT_TIME:
- case OTHER_TIME:
- case PREV_TIME:
- *num = the_event->timestamp;
- return true;
- case EVENT_DURATION:
- if (!the_event->has_other_event())
- return false;
- *num = the_event->GetAbsTimeToOtherEvent();
- return true;
- case EVENT_COMPLETE_DURATION:
- if (the_event->phase != TRACE_EVENT_PHASE_COMPLETE)
- return false;
- *num = the_event->duration;
- return true;
- case EVENT_PHASE:
- case OTHER_PHASE:
- case PREV_PHASE:
- *num = static_cast<double>(the_event->phase);
- return true;
- case EVENT_HAS_STRING_ARG:
- case OTHER_HAS_STRING_ARG:
- case PREV_HAS_STRING_ARG:
- *num = (the_event->HasStringArg(string_) ? 1.0 : 0.0);
- return true;
- case EVENT_HAS_NUMBER_ARG:
- case OTHER_HAS_NUMBER_ARG:
- case PREV_HAS_NUMBER_ARG:
- *num = (the_event->HasNumberArg(string_) ? 1.0 : 0.0);
- return true;
- case EVENT_ARG:
- case OTHER_ARG:
- case PREV_ARG: {
- // Search for the argument name and return its value if found.
- std::map<std::string, double>::const_iterator num_i =
- the_event->arg_numbers.find(string_);
- if (num_i == the_event->arg_numbers.end())
- return false;
- *num = num_i->second;
- return true;
- }
- case EVENT_HAS_OTHER:
- // return 1.0 (true) if the other event exists
- *num = event.other_event ? 1.0 : 0.0;
- return true;
- case EVENT_HAS_PREV:
- *num = event.prev_event ? 1.0 : 0.0;
- return true;
- default:
- return false;
- }
-}
-
-bool Query::GetMemberValueAsString(const TraceEvent& event,
- std::string* str) const {
- DCHECK_EQ(QUERY_EVENT_MEMBER, type_);
-
- // This could be a request for a member of |event| or a member of |event|'s
- // associated previous or next event. Store the target event in the_event:
- const TraceEvent* the_event = SelectTargetEvent(&event, member_);
-
- // Request for member of associated event, but there is no associated event.
- if (!the_event)
- return false;
-
- switch (member_) {
- case EVENT_CATEGORY:
- case OTHER_CATEGORY:
- case PREV_CATEGORY:
- *str = the_event->category;
- return true;
- case EVENT_NAME:
- case OTHER_NAME:
- case PREV_NAME:
- *str = the_event->name;
- return true;
- case EVENT_ID:
- case OTHER_ID:
- case PREV_ID:
- *str = the_event->id;
- return true;
- case EVENT_ARG:
- case OTHER_ARG:
- case PREV_ARG: {
- // Search for the argument name and return its value if found.
- std::map<std::string, std::string>::const_iterator str_i =
- the_event->arg_strings.find(string_);
- if (str_i == the_event->arg_strings.end())
- return false;
- *str = str_i->second;
- return true;
- }
- default:
- return false;
- }
-}
-
-Query::Query(const std::string& str)
- : type_(QUERY_STRING),
- operator_(OP_INVALID),
- member_(EVENT_INVALID),
- number_(0),
- string_(str),
- is_pattern_(false) {
-}
-
-Query::Query(double num)
- : type_(QUERY_NUMBER),
- operator_(OP_INVALID),
- member_(EVENT_INVALID),
- number_(num),
- is_pattern_(false) {
-}
-const Query& Query::left() const {
- return left_->query();
-}
-
-const Query& Query::right() const {
- return right_->query();
-}
-
-Query Query::operator==(const Query& rhs) const {
- return Query(*this, rhs, OP_EQ);
-}
-
-Query Query::operator!=(const Query& rhs) const {
- return Query(*this, rhs, OP_NE);
-}
-
-Query Query::operator<(const Query& rhs) const {
- return Query(*this, rhs, OP_LT);
-}
-
-Query Query::operator<=(const Query& rhs) const {
- return Query(*this, rhs, OP_LE);
-}
-
-Query Query::operator>(const Query& rhs) const {
- return Query(*this, rhs, OP_GT);
-}
-
-Query Query::operator>=(const Query& rhs) const {
- return Query(*this, rhs, OP_GE);
-}
-
-Query Query::operator&&(const Query& rhs) const {
- return Query(*this, rhs, OP_AND);
-}
-
-Query Query::operator||(const Query& rhs) const {
- return Query(*this, rhs, OP_OR);
-}
-
-Query Query::operator!() const {
- return Query(*this, OP_NOT);
-}
-
-Query Query::operator+(const Query& rhs) const {
- return Query(*this, rhs, OP_ADD);
-}
-
-Query Query::operator-(const Query& rhs) const {
- return Query(*this, rhs, OP_SUB);
-}
-
-Query Query::operator*(const Query& rhs) const {
- return Query(*this, rhs, OP_MUL);
-}
-
-Query Query::operator/(const Query& rhs) const {
- return Query(*this, rhs, OP_DIV);
-}
-
-Query Query::operator%(const Query& rhs) const {
- return Query(*this, rhs, OP_MOD);
-}
-
-Query Query::operator-() const {
- return Query(*this, OP_NEGATE);
-}
-
-
-Query::Query(const Query& left, const Query& right, Operator binary_op)
- : operator_(binary_op),
- left_(new QueryNode(left)),
- right_(new QueryNode(right)),
- member_(EVENT_INVALID),
- number_(0) {
- type_ = (binary_op < OP_ADD ?
- QUERY_BOOLEAN_OPERATOR : QUERY_ARITHMETIC_OPERATOR);
-}
-
-Query::Query(const Query& left, Operator unary_op)
- : operator_(unary_op),
- left_(new QueryNode(left)),
- member_(EVENT_INVALID),
- number_(0) {
- type_ = (unary_op < OP_ADD ?
- QUERY_BOOLEAN_OPERATOR : QUERY_ARITHMETIC_OPERATOR);
-}
-
-namespace {
-
-// Search |events| for |query| and add matches to |output|.
-size_t FindMatchingEvents(const std::vector<TraceEvent>& events,
- const Query& query,
- TraceEventVector* output,
- bool ignore_metadata_events) {
- for (size_t i = 0; i < events.size(); ++i) {
- if (ignore_metadata_events && events[i].phase == TRACE_EVENT_PHASE_METADATA)
- continue;
- if (query.Evaluate(events[i]))
- output->push_back(&events[i]);
- }
- return output->size();
-}
-
-bool ParseEventsFromJson(const std::string& json,
- std::vector<TraceEvent>* output) {
- std::unique_ptr<base::Value> root = base::JSONReader::Read(json);
-
- base::ListValue* root_list = nullptr;
- if (!root.get() || !root->GetAsList(&root_list))
- return false;
-
- for (size_t i = 0; i < root_list->GetSize(); ++i) {
- base::Value* item = nullptr;
- if (root_list->Get(i, &item)) {
- TraceEvent event;
- if (event.SetFromJSON(item))
- output->push_back(std::move(event));
- else
- return false;
- }
- }
-
- return true;
-}
-
-} // namespace
-
-// TraceAnalyzer
-
-TraceAnalyzer::TraceAnalyzer()
- : ignore_metadata_events_(false), allow_association_changes_(true) {}
-
-TraceAnalyzer::~TraceAnalyzer() = default;
-
-// static
-TraceAnalyzer* TraceAnalyzer::Create(const std::string& json_events) {
- std::unique_ptr<TraceAnalyzer> analyzer(new TraceAnalyzer());
- if (analyzer->SetEvents(json_events))
- return analyzer.release();
- return nullptr;
-}
-
-bool TraceAnalyzer::SetEvents(const std::string& json_events) {
- raw_events_.clear();
- if (!ParseEventsFromJson(json_events, &raw_events_))
- return false;
- std::stable_sort(raw_events_.begin(), raw_events_.end());
- ParseMetadata();
- return true;
-}
-
-void TraceAnalyzer::AssociateBeginEndEvents() {
- using trace_analyzer::Query;
-
- Query begin(Query::EventPhaseIs(TRACE_EVENT_PHASE_BEGIN));
- Query end(Query::EventPhaseIs(TRACE_EVENT_PHASE_END));
- Query match(Query::EventName() == Query::OtherName() &&
- Query::EventCategory() == Query::OtherCategory() &&
- Query::EventTid() == Query::OtherTid() &&
- Query::EventPid() == Query::OtherPid());
-
- AssociateEvents(begin, end, match);
-}
-
-void TraceAnalyzer::AssociateAsyncBeginEndEvents(bool match_pid) {
- using trace_analyzer::Query;
-
- Query begin(
- Query::EventPhaseIs(TRACE_EVENT_PHASE_ASYNC_BEGIN) ||
- Query::EventPhaseIs(TRACE_EVENT_PHASE_ASYNC_STEP_INTO) ||
- Query::EventPhaseIs(TRACE_EVENT_PHASE_ASYNC_STEP_PAST));
- Query end(Query::EventPhaseIs(TRACE_EVENT_PHASE_ASYNC_END) ||
- Query::EventPhaseIs(TRACE_EVENT_PHASE_ASYNC_STEP_INTO) ||
- Query::EventPhaseIs(TRACE_EVENT_PHASE_ASYNC_STEP_PAST));
- Query match(Query::EventCategory() == Query::OtherCategory() &&
- Query::EventId() == Query::OtherId());
-
- if (match_pid) {
- match = match && Query::EventPid() == Query::OtherPid();
- }
-
- AssociateEvents(begin, end, match);
-}
-
-void TraceAnalyzer::AssociateEvents(const Query& first,
- const Query& second,
- const Query& match) {
- DCHECK(allow_association_changes_)
- << "AssociateEvents not allowed after FindEvents";
-
- // Search for matching begin/end event pairs. When a matching end is found,
- // it is associated with the begin event.
- std::vector<TraceEvent*> begin_stack;
- for (size_t event_index = 0; event_index < raw_events_.size();
- ++event_index) {
-
- TraceEvent& this_event = raw_events_[event_index];
-
- if (second.Evaluate(this_event)) {
- // Search stack for matching begin, starting from end.
- for (int stack_index = static_cast<int>(begin_stack.size()) - 1;
- stack_index >= 0; --stack_index) {
- TraceEvent& begin_event = *begin_stack[stack_index];
-
- // Temporarily set other to test against the match query.
- const TraceEvent* other_backup = begin_event.other_event;
- begin_event.other_event = &this_event;
- if (match.Evaluate(begin_event)) {
- // Found a matching begin/end pair.
- // Set the associated previous event
- this_event.prev_event = &begin_event;
- // Erase the matching begin event index from the stack.
- begin_stack.erase(begin_stack.begin() + stack_index);
- break;
- }
-
- // Not a match, restore original other and continue.
- begin_event.other_event = other_backup;
- }
- }
- // Even if this_event is a |second| event that has matched an earlier
- // |first| event, it can still also be a |first| event and be associated
- // with a later |second| event.
- if (first.Evaluate(this_event)) {
- begin_stack.push_back(&this_event);
- }
- }
-}
-
-void TraceAnalyzer::MergeAssociatedEventArgs() {
- for (size_t i = 0; i < raw_events_.size(); ++i) {
- // Merge all associated events with the first event.
- const TraceEvent* other = raw_events_[i].other_event;
- // Avoid looping by keeping set of encountered TraceEvents.
- std::set<const TraceEvent*> encounters;
- encounters.insert(&raw_events_[i]);
- while (other && encounters.find(other) == encounters.end()) {
- encounters.insert(other);
- raw_events_[i].arg_numbers.insert(
- other->arg_numbers.begin(),
- other->arg_numbers.end());
- raw_events_[i].arg_strings.insert(
- other->arg_strings.begin(),
- other->arg_strings.end());
- other = other->other_event;
- }
- }
-}
-
-size_t TraceAnalyzer::FindEvents(const Query& query, TraceEventVector* output) {
- allow_association_changes_ = false;
- output->clear();
- return FindMatchingEvents(
- raw_events_, query, output, ignore_metadata_events_);
-}
-
-const TraceEvent* TraceAnalyzer::FindFirstOf(const Query& query) {
- TraceEventVector output;
- if (FindEvents(query, &output) > 0)
- return output.front();
- return nullptr;
-}
-
-const TraceEvent* TraceAnalyzer::FindLastOf(const Query& query) {
- TraceEventVector output;
- if (FindEvents(query, &output) > 0)
- return output.back();
- return nullptr;
-}
-
-const std::string& TraceAnalyzer::GetThreadName(
- const TraceEvent::ProcessThreadID& thread) {
- // If thread is not found, just add and return empty string.
- return thread_names_[thread];
-}
-
-void TraceAnalyzer::ParseMetadata() {
- for (size_t i = 0; i < raw_events_.size(); ++i) {
- TraceEvent& this_event = raw_events_[i];
- // Check for thread name metadata.
- if (this_event.phase != TRACE_EVENT_PHASE_METADATA ||
- this_event.name != "thread_name")
- continue;
- std::map<std::string, std::string>::const_iterator string_it =
- this_event.arg_strings.find("name");
- if (string_it != this_event.arg_strings.end())
- thread_names_[this_event.thread] = string_it->second;
- }
-}
-
-// Utility functions for collecting process-local traces and creating a
-// |TraceAnalyzer| from the result.
-
-void Start(const std::string& category_filter_string) {
- DCHECK(!base::trace_event::TraceLog::GetInstance()->IsEnabled());
- base::trace_event::TraceLog::GetInstance()->SetEnabled(
- base::trace_event::TraceConfig(category_filter_string, ""),
- base::trace_event::TraceLog::RECORDING_MODE);
-}
-
-std::unique_ptr<TraceAnalyzer> Stop() {
- DCHECK(base::trace_event::TraceLog::GetInstance()->IsEnabled());
- base::trace_event::TraceLog::GetInstance()->SetDisabled();
-
- base::trace_event::TraceResultBuffer buffer;
- base::trace_event::TraceResultBuffer::SimpleOutput trace_output;
- buffer.SetOutputCallback(trace_output.GetCallback());
- base::RunLoop run_loop;
- buffer.Start();
- base::trace_event::TraceLog::GetInstance()->Flush(
- base::BindRepeating(&OnTraceDataCollected, run_loop.QuitClosure(),
- base::Unretained(&buffer)));
- run_loop.Run();
- buffer.Finish();
-
- return base::WrapUnique(TraceAnalyzer::Create(trace_output.json_output));
-}
-
-// TraceEventVector utility functions.
-
-bool GetRateStats(const TraceEventVector& events,
- RateStats* stats,
- const RateStatsOptions* options) {
- DCHECK(stats);
- // Need at least 3 events to calculate rate stats.
- const size_t kMinEvents = 3;
- if (events.size() < kMinEvents) {
- LOG(ERROR) << "Not enough events: " << events.size();
- return false;
- }
-
- std::vector<double> deltas;
- size_t num_deltas = events.size() - 1;
- for (size_t i = 0; i < num_deltas; ++i) {
- double delta = events.at(i + 1)->timestamp - events.at(i)->timestamp;
- if (delta < 0.0) {
- LOG(ERROR) << "Events are out of order";
- return false;
- }
- deltas.push_back(delta);
- }
-
- std::sort(deltas.begin(), deltas.end());
-
- if (options) {
- if (options->trim_min + options->trim_max > events.size() - kMinEvents) {
- LOG(ERROR) << "Attempt to trim too many events";
- return false;
- }
- deltas.erase(deltas.begin(), deltas.begin() + options->trim_min);
- deltas.erase(deltas.end() - options->trim_max, deltas.end());
- }
-
- num_deltas = deltas.size();
- double delta_sum = 0.0;
- for (size_t i = 0; i < num_deltas; ++i)
- delta_sum += deltas[i];
-
- stats->min_us = *std::min_element(deltas.begin(), deltas.end());
- stats->max_us = *std::max_element(deltas.begin(), deltas.end());
- stats->mean_us = delta_sum / static_cast<double>(num_deltas);
-
- double sum_mean_offsets_squared = 0.0;
- for (size_t i = 0; i < num_deltas; ++i) {
- double offset = fabs(deltas[i] - stats->mean_us);
- sum_mean_offsets_squared += offset * offset;
- }
- stats->standard_deviation_us =
- sqrt(sum_mean_offsets_squared / static_cast<double>(num_deltas - 1));
-
- return true;
-}
-
-bool FindFirstOf(const TraceEventVector& events,
- const Query& query,
- size_t position,
- size_t* return_index) {
- DCHECK(return_index);
- for (size_t i = position; i < events.size(); ++i) {
- if (query.Evaluate(*events[i])) {
- *return_index = i;
- return true;
- }
- }
- return false;
-}
-
-bool FindLastOf(const TraceEventVector& events,
- const Query& query,
- size_t position,
- size_t* return_index) {
- DCHECK(return_index);
- for (size_t i = std::min(position + 1, events.size()); i != 0; --i) {
- if (query.Evaluate(*events[i - 1])) {
- *return_index = i - 1;
- return true;
- }
- }
- return false;
-}
-
-bool FindClosest(const TraceEventVector& events,
- const Query& query,
- size_t position,
- size_t* return_closest,
- size_t* return_second_closest) {
- DCHECK(return_closest);
- if (events.empty() || position >= events.size())
- return false;
- size_t closest = events.size();
- size_t second_closest = events.size();
- for (size_t i = 0; i < events.size(); ++i) {
- if (!query.Evaluate(*events.at(i)))
- continue;
- if (closest == events.size()) {
- closest = i;
- continue;
- }
- if (fabs(events.at(i)->timestamp - events.at(position)->timestamp) <
- fabs(events.at(closest)->timestamp - events.at(position)->timestamp)) {
- second_closest = closest;
- closest = i;
- } else if (second_closest == events.size()) {
- second_closest = i;
- }
- }
-
- if (closest < events.size() &&
- (!return_second_closest || second_closest < events.size())) {
- *return_closest = closest;
- if (return_second_closest)
- *return_second_closest = second_closest;
- return true;
- }
-
- return false;
-}
-
-size_t CountMatches(const TraceEventVector& events,
- const Query& query,
- size_t begin_position,
- size_t end_position) {
- if (begin_position >= events.size())
- return 0u;
- end_position = (end_position < events.size()) ? end_position : events.size();
- size_t count = 0u;
- for (size_t i = begin_position; i < end_position; ++i) {
- if (query.Evaluate(*events.at(i)))
- ++count;
- }
- return count;
-}
-
-} // namespace trace_analyzer
diff --git a/base/test/trace_event_analyzer.h b/base/test/trace_event_analyzer.h
deleted file mode 100644
index dcdd2e4..0000000
--- a/base/test/trace_event_analyzer.h
+++ /dev/null
@@ -1,842 +0,0 @@
-// Copyright (c) 2012 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.
-
-// Use trace_analyzer::Query and trace_analyzer::TraceAnalyzer to search for
-// specific trace events that were generated by the trace_event.h API.
-//
-// Basic procedure:
-// - Get trace events JSON string from base::trace_event::TraceLog.
-// - Create TraceAnalyzer with JSON string.
-// - Call TraceAnalyzer::AssociateBeginEndEvents (optional).
-// - Call TraceAnalyzer::AssociateEvents (zero or more times).
-// - Call TraceAnalyzer::FindEvents with queries to find specific events.
-//
-// A Query is a boolean expression tree that evaluates to true or false for a
-// given trace event. Queries can be combined into a tree using boolean,
-// arithmetic and comparison operators that refer to data of an individual trace
-// event.
-//
-// The events are returned as trace_analyzer::TraceEvent objects.
-// TraceEvent contains a single trace event's data, as well as a pointer to
-// a related trace event. The related trace event is typically the matching end
-// of a begin event or the matching begin of an end event.
-//
-// The following examples use this basic setup code to construct TraceAnalyzer
-// with the json trace string retrieved from TraceLog and construct an event
-// vector for retrieving events:
-//
-// TraceAnalyzer analyzer(json_events);
-// TraceEventVector events;
-//
-// EXAMPLE 1: Find events named "my_event".
-//
-// analyzer.FindEvents(Query(EVENT_NAME) == "my_event", &events);
-//
-// EXAMPLE 2: Find begin events named "my_event" with duration > 1 second.
-//
-// Query q = (Query(EVENT_NAME) == Query::String("my_event") &&
-// Query(EVENT_PHASE) == Query::Phase(TRACE_EVENT_PHASE_BEGIN) &&
-// Query(EVENT_DURATION) > Query::Double(1000000.0));
-// analyzer.FindEvents(q, &events);
-//
-// EXAMPLE 3: Associating event pairs across threads.
-//
-// If the test needs to analyze something that starts and ends on different
-// threads, the test needs to use INSTANT events. The typical procedure is to
-// specify the same unique ID as a TRACE_EVENT argument on both the start and
-// finish INSTANT events. Then use the following procedure to associate those
-// events.
-//
-// Step 1: instrument code with custom begin/end trace events.
-// [Thread 1 tracing code]
-// TRACE_EVENT_INSTANT1("test_latency", "timing1_begin", "id", 3);
-// [Thread 2 tracing code]
-// TRACE_EVENT_INSTANT1("test_latency", "timing1_end", "id", 3);
-//
-// Step 2: associate these custom begin/end pairs.
-// Query begin(Query(EVENT_NAME) == Query::String("timing1_begin"));
-// Query end(Query(EVENT_NAME) == Query::String("timing1_end"));
-// Query match(Query(EVENT_ARG, "id") == Query(OTHER_ARG, "id"));
-// analyzer.AssociateEvents(begin, end, match);
-//
-// Step 3: search for "timing1_begin" events with existing other event.
-// Query q = (Query(EVENT_NAME) == Query::String("timing1_begin") &&
-// Query(EVENT_HAS_OTHER));
-// analyzer.FindEvents(q, &events);
-//
-// Step 4: analyze events, such as checking durations.
-// for (size_t i = 0; i < events.size(); ++i) {
-// double duration;
-// EXPECT_TRUE(events[i].GetAbsTimeToOtherEvent(&duration));
-// EXPECT_LT(duration, 1000000.0/60.0); // expect less than 1/60 second.
-// }
-//
-// There are two helper functions, Start(category_filter_string) and Stop(), for
-// facilitating the collection of process-local traces and building a
-// TraceAnalyzer from them. A typical test, that uses the helper functions,
-// looks like the following:
-//
-// TEST_F(...) {
-// Start("*");
-// [Invoke the functions you want to test their traces]
-// auto analyzer = Stop();
-//
-// [Use the analyzer to verify produced traces, as explained above]
-// }
-//
-// Note: The Stop() function needs a SingleThreadTaskRunner.
-
-#ifndef BASE_TEST_TRACE_EVENT_ANALYZER_H_
-#define BASE_TEST_TRACE_EVENT_ANALYZER_H_
-
-#include <stddef.h>
-#include <stdint.h>
-
-#include <map>
-#include <memory>
-#include <string>
-#include <vector>
-
-#include "base/macros.h"
-#include "base/memory/ref_counted.h"
-#include "base/trace_event/trace_event.h"
-
-namespace base {
-class Value;
-}
-
-namespace trace_analyzer {
-class QueryNode;
-
-// trace_analyzer::TraceEvent is a more convenient form of the
-// base::trace_event::TraceEvent class to make tracing-based tests easier to
-// write.
-struct TraceEvent {
- // ProcessThreadID contains a Process ID and Thread ID.
- struct ProcessThreadID {
- ProcessThreadID() : process_id(0), thread_id(0) {}
- ProcessThreadID(int process_id, int thread_id)
- : process_id(process_id), thread_id(thread_id) {}
- bool operator< (const ProcessThreadID& rhs) const {
- if (process_id != rhs.process_id)
- return process_id < rhs.process_id;
- return thread_id < rhs.thread_id;
- }
- int process_id;
- int thread_id;
- };
-
- TraceEvent();
- TraceEvent(TraceEvent&& other);
- ~TraceEvent();
-
- bool SetFromJSON(const base::Value* event_value) WARN_UNUSED_RESULT;
-
- bool operator< (const TraceEvent& rhs) const {
- return timestamp < rhs.timestamp;
- }
-
- TraceEvent& operator=(TraceEvent&& rhs);
-
- bool has_other_event() const { return other_event; }
-
- // Returns absolute duration in microseconds between this event and other
- // event. Must have already verified that other_event exists by
- // Query(EVENT_HAS_OTHER) or by calling has_other_event().
- double GetAbsTimeToOtherEvent() const;
-
- // Return the argument value if it exists and it is a string.
- bool GetArgAsString(const std::string& name, std::string* arg) const;
- // Return the argument value if it exists and it is a number.
- bool GetArgAsNumber(const std::string& name, double* arg) const;
- // Return the argument value if it exists.
- bool GetArgAsValue(const std::string& name,
- std::unique_ptr<base::Value>* arg) const;
-
- // Check if argument exists and is string.
- bool HasStringArg(const std::string& name) const;
- // Check if argument exists and is number (double, int or bool).
- bool HasNumberArg(const std::string& name) const;
- // Check if argument exists.
- bool HasArg(const std::string& name) const;
-
- // Get known existing arguments as specific types.
- // Useful when you have already queried the argument with
- // Query(HAS_NUMBER_ARG) or Query(HAS_STRING_ARG).
- std::string GetKnownArgAsString(const std::string& name) const;
- double GetKnownArgAsDouble(const std::string& name) const;
- int GetKnownArgAsInt(const std::string& name) const;
- bool GetKnownArgAsBool(const std::string& name) const;
- std::unique_ptr<base::Value> GetKnownArgAsValue(
- const std::string& name) const;
-
- // Process ID and Thread ID.
- ProcessThreadID thread;
-
- // Time since epoch in microseconds.
- // Stored as double to match its JSON representation.
- double timestamp;
- double duration;
- char phase;
- std::string category;
- std::string name;
- std::string id;
- double thread_duration = 0.0;
- double thread_timestamp = 0.0;
- std::string scope;
- std::string bind_id;
- bool flow_out = false;
- bool flow_in = false;
- std::string global_id2;
- std::string local_id2;
-
- // All numbers and bool values from TraceEvent args are cast to double.
- // bool becomes 1.0 (true) or 0.0 (false).
- std::map<std::string, double> arg_numbers;
- std::map<std::string, std::string> arg_strings;
- std::map<std::string, std::unique_ptr<base::Value>> arg_values;
-
- // The other event associated with this event (or NULL).
- const TraceEvent* other_event;
-
- // A back-link for |other_event|. That is, if other_event is not null, then
- // |event->other_event->prev_event == event| is always true.
- const TraceEvent* prev_event;
-};
-
-typedef std::vector<const TraceEvent*> TraceEventVector;
-
-class Query {
- public:
- Query(const Query& query);
-
- ~Query();
-
- ////////////////////////////////////////////////////////////////
- // Query literal values
-
- // Compare with the given string.
- static Query String(const std::string& str);
-
- // Compare with the given number.
- static Query Double(double num);
- static Query Int(int32_t num);
- static Query Uint(uint32_t num);
-
- // Compare with the given bool.
- static Query Bool(bool boolean);
-
- // Compare with the given phase.
- static Query Phase(char phase);
-
- // Compare with the given string pattern. Only works with == and != operators.
- // Example: Query(EVENT_NAME) == Query::Pattern("MyEvent*")
- static Query Pattern(const std::string& pattern);
-
- ////////////////////////////////////////////////////////////////
- // Query event members
-
- static Query EventPid() { return Query(EVENT_PID); }
-
- static Query EventTid() { return Query(EVENT_TID); }
-
- // Return the timestamp of the event in microseconds since epoch.
- static Query EventTime() { return Query(EVENT_TIME); }
-
- // Return the absolute time between event and other event in microseconds.
- // Only works if Query::EventHasOther() == true.
- static Query EventDuration() { return Query(EVENT_DURATION); }
-
- // Return the duration of a COMPLETE event.
- static Query EventCompleteDuration() {
- return Query(EVENT_COMPLETE_DURATION);
- }
-
- static Query EventPhase() { return Query(EVENT_PHASE); }
-
- static Query EventCategory() { return Query(EVENT_CATEGORY); }
-
- static Query EventName() { return Query(EVENT_NAME); }
-
- static Query EventId() { return Query(EVENT_ID); }
-
- static Query EventPidIs(int process_id) {
- return Query(EVENT_PID) == Query::Int(process_id);
- }
-
- static Query EventTidIs(int thread_id) {
- return Query(EVENT_TID) == Query::Int(thread_id);
- }
-
- static Query EventThreadIs(const TraceEvent::ProcessThreadID& thread) {
- return EventPidIs(thread.process_id) && EventTidIs(thread.thread_id);
- }
-
- static Query EventTimeIs(double timestamp) {
- return Query(EVENT_TIME) == Query::Double(timestamp);
- }
-
- static Query EventDurationIs(double duration) {
- return Query(EVENT_DURATION) == Query::Double(duration);
- }
-
- static Query EventPhaseIs(char phase) {
- return Query(EVENT_PHASE) == Query::Phase(phase);
- }
-
- static Query EventCategoryIs(const std::string& category) {
- return Query(EVENT_CATEGORY) == Query::String(category);
- }
-
- static Query EventNameIs(const std::string& name) {
- return Query(EVENT_NAME) == Query::String(name);
- }
-
- static Query EventIdIs(const std::string& id) {
- return Query(EVENT_ID) == Query::String(id);
- }
-
- // Evaluates to true if arg exists and is a string.
- static Query EventHasStringArg(const std::string& arg_name) {
- return Query(EVENT_HAS_STRING_ARG, arg_name);
- }
-
- // Evaluates to true if arg exists and is a number.
- // Number arguments include types double, int and bool.
- static Query EventHasNumberArg(const std::string& arg_name) {
- return Query(EVENT_HAS_NUMBER_ARG, arg_name);
- }
-
- // Evaluates to arg value (string or number).
- static Query EventArg(const std::string& arg_name) {
- return Query(EVENT_ARG, arg_name);
- }
-
- // Return true if associated event exists.
- static Query EventHasOther() { return Query(EVENT_HAS_OTHER); }
-
- // Access the associated other_event's members:
-
- static Query OtherPid() { return Query(OTHER_PID); }
-
- static Query OtherTid() { return Query(OTHER_TID); }
-
- static Query OtherTime() { return Query(OTHER_TIME); }
-
- static Query OtherPhase() { return Query(OTHER_PHASE); }
-
- static Query OtherCategory() { return Query(OTHER_CATEGORY); }
-
- static Query OtherName() { return Query(OTHER_NAME); }
-
- static Query OtherId() { return Query(OTHER_ID); }
-
- static Query OtherPidIs(int process_id) {
- return Query(OTHER_PID) == Query::Int(process_id);
- }
-
- static Query OtherTidIs(int thread_id) {
- return Query(OTHER_TID) == Query::Int(thread_id);
- }
-
- static Query OtherThreadIs(const TraceEvent::ProcessThreadID& thread) {
- return OtherPidIs(thread.process_id) && OtherTidIs(thread.thread_id);
- }
-
- static Query OtherTimeIs(double timestamp) {
- return Query(OTHER_TIME) == Query::Double(timestamp);
- }
-
- static Query OtherPhaseIs(char phase) {
- return Query(OTHER_PHASE) == Query::Phase(phase);
- }
-
- static Query OtherCategoryIs(const std::string& category) {
- return Query(OTHER_CATEGORY) == Query::String(category);
- }
-
- static Query OtherNameIs(const std::string& name) {
- return Query(OTHER_NAME) == Query::String(name);
- }
-
- static Query OtherIdIs(const std::string& id) {
- return Query(OTHER_ID) == Query::String(id);
- }
-
- // Evaluates to true if arg exists and is a string.
- static Query OtherHasStringArg(const std::string& arg_name) {
- return Query(OTHER_HAS_STRING_ARG, arg_name);
- }
-
- // Evaluates to true if arg exists and is a number.
- // Number arguments include types double, int and bool.
- static Query OtherHasNumberArg(const std::string& arg_name) {
- return Query(OTHER_HAS_NUMBER_ARG, arg_name);
- }
-
- // Evaluates to arg value (string or number).
- static Query OtherArg(const std::string& arg_name) {
- return Query(OTHER_ARG, arg_name);
- }
-
- // Access the associated prev_event's members:
-
- static Query PrevPid() { return Query(PREV_PID); }
-
- static Query PrevTid() { return Query(PREV_TID); }
-
- static Query PrevTime() { return Query(PREV_TIME); }
-
- static Query PrevPhase() { return Query(PREV_PHASE); }
-
- static Query PrevCategory() { return Query(PREV_CATEGORY); }
-
- static Query PrevName() { return Query(PREV_NAME); }
-
- static Query PrevId() { return Query(PREV_ID); }
-
- static Query PrevPidIs(int process_id) {
- return Query(PREV_PID) == Query::Int(process_id);
- }
-
- static Query PrevTidIs(int thread_id) {
- return Query(PREV_TID) == Query::Int(thread_id);
- }
-
- static Query PrevThreadIs(const TraceEvent::ProcessThreadID& thread) {
- return PrevPidIs(thread.process_id) && PrevTidIs(thread.thread_id);
- }
-
- static Query PrevTimeIs(double timestamp) {
- return Query(PREV_TIME) == Query::Double(timestamp);
- }
-
- static Query PrevPhaseIs(char phase) {
- return Query(PREV_PHASE) == Query::Phase(phase);
- }
-
- static Query PrevCategoryIs(const std::string& category) {
- return Query(PREV_CATEGORY) == Query::String(category);
- }
-
- static Query PrevNameIs(const std::string& name) {
- return Query(PREV_NAME) == Query::String(name);
- }
-
- static Query PrevIdIs(const std::string& id) {
- return Query(PREV_ID) == Query::String(id);
- }
-
- // Evaluates to true if arg exists and is a string.
- static Query PrevHasStringArg(const std::string& arg_name) {
- return Query(PREV_HAS_STRING_ARG, arg_name);
- }
-
- // Evaluates to true if arg exists and is a number.
- // Number arguments include types double, int and bool.
- static Query PrevHasNumberArg(const std::string& arg_name) {
- return Query(PREV_HAS_NUMBER_ARG, arg_name);
- }
-
- // Evaluates to arg value (string or number).
- static Query PrevArg(const std::string& arg_name) {
- return Query(PREV_ARG, arg_name);
- }
-
- ////////////////////////////////////////////////////////////////
- // Common queries:
-
- // Find BEGIN events that have a corresponding END event.
- static Query MatchBeginWithEnd() {
- return (Query(EVENT_PHASE) == Query::Phase(TRACE_EVENT_PHASE_BEGIN)) &&
- Query(EVENT_HAS_OTHER);
- }
-
- // Find COMPLETE events.
- static Query MatchComplete() {
- return (Query(EVENT_PHASE) == Query::Phase(TRACE_EVENT_PHASE_COMPLETE));
- }
-
- // Find ASYNC_BEGIN events that have a corresponding ASYNC_END event.
- static Query MatchAsyncBeginWithNext() {
- return (Query(EVENT_PHASE) ==
- Query::Phase(TRACE_EVENT_PHASE_ASYNC_BEGIN)) &&
- Query(EVENT_HAS_OTHER);
- }
-
- // Find BEGIN events of given |name| which also have associated END events.
- static Query MatchBeginName(const std::string& name) {
- return (Query(EVENT_NAME) == Query(name)) && MatchBeginWithEnd();
- }
-
- // Find COMPLETE events of given |name|.
- static Query MatchCompleteName(const std::string& name) {
- return (Query(EVENT_NAME) == Query(name)) && MatchComplete();
- }
-
- // Match given Process ID and Thread ID.
- static Query MatchThread(const TraceEvent::ProcessThreadID& thread) {
- return (Query(EVENT_PID) == Query::Int(thread.process_id)) &&
- (Query(EVENT_TID) == Query::Int(thread.thread_id));
- }
-
- // Match event pair that spans multiple threads.
- static Query MatchCrossThread() {
- return (Query(EVENT_PID) != Query(OTHER_PID)) ||
- (Query(EVENT_TID) != Query(OTHER_TID));
- }
-
- ////////////////////////////////////////////////////////////////
- // Operators:
-
- // Boolean operators:
- Query operator==(const Query& rhs) const;
- Query operator!=(const Query& rhs) const;
- Query operator< (const Query& rhs) const;
- Query operator<=(const Query& rhs) const;
- Query operator> (const Query& rhs) const;
- Query operator>=(const Query& rhs) const;
- Query operator&&(const Query& rhs) const;
- Query operator||(const Query& rhs) const;
- Query operator!() const;
-
- // Arithmetic operators:
- // Following operators are applied to double arguments:
- Query operator+(const Query& rhs) const;
- Query operator-(const Query& rhs) const;
- Query operator*(const Query& rhs) const;
- Query operator/(const Query& rhs) const;
- Query operator-() const;
- // Mod operates on int64_t args (doubles are casted to int64_t beforehand):
- Query operator%(const Query& rhs) const;
-
- // Return true if the given event matches this query tree.
- // This is a recursive method that walks the query tree.
- bool Evaluate(const TraceEvent& event) const;
-
- enum TraceEventMember {
- EVENT_INVALID,
- EVENT_PID,
- EVENT_TID,
- EVENT_TIME,
- EVENT_DURATION,
- EVENT_COMPLETE_DURATION,
- EVENT_PHASE,
- EVENT_CATEGORY,
- EVENT_NAME,
- EVENT_ID,
- EVENT_HAS_STRING_ARG,
- EVENT_HAS_NUMBER_ARG,
- EVENT_ARG,
- EVENT_HAS_OTHER,
- EVENT_HAS_PREV,
-
- OTHER_PID,
- OTHER_TID,
- OTHER_TIME,
- OTHER_PHASE,
- OTHER_CATEGORY,
- OTHER_NAME,
- OTHER_ID,
- OTHER_HAS_STRING_ARG,
- OTHER_HAS_NUMBER_ARG,
- OTHER_ARG,
-
- PREV_PID,
- PREV_TID,
- PREV_TIME,
- PREV_PHASE,
- PREV_CATEGORY,
- PREV_NAME,
- PREV_ID,
- PREV_HAS_STRING_ARG,
- PREV_HAS_NUMBER_ARG,
- PREV_ARG,
-
- OTHER_FIRST_MEMBER = OTHER_PID,
- OTHER_LAST_MEMBER = OTHER_ARG,
-
- PREV_FIRST_MEMBER = PREV_PID,
- PREV_LAST_MEMBER = PREV_ARG,
- };
-
- enum Operator {
- OP_INVALID,
- // Boolean operators:
- OP_EQ,
- OP_NE,
- OP_LT,
- OP_LE,
- OP_GT,
- OP_GE,
- OP_AND,
- OP_OR,
- OP_NOT,
- // Arithmetic operators:
- OP_ADD,
- OP_SUB,
- OP_MUL,
- OP_DIV,
- OP_MOD,
- OP_NEGATE
- };
-
- enum QueryType {
- QUERY_BOOLEAN_OPERATOR,
- QUERY_ARITHMETIC_OPERATOR,
- QUERY_EVENT_MEMBER,
- QUERY_NUMBER,
- QUERY_STRING
- };
-
- // Compare with the given member.
- explicit Query(TraceEventMember member);
-
- // Compare with the given member argument value.
- Query(TraceEventMember member, const std::string& arg_name);
-
- // Compare with the given string.
- explicit Query(const std::string& str);
-
- // Compare with the given number.
- explicit Query(double num);
-
- // Construct a boolean Query that returns (left <binary_op> right).
- Query(const Query& left, const Query& right, Operator binary_op);
-
- // Construct a boolean Query that returns (<binary_op> left).
- Query(const Query& left, Operator unary_op);
-
- // Try to compare left_ against right_ based on operator_.
- // If either left or right does not convert to double, false is returned.
- // Otherwise, true is returned and |result| is set to the comparison result.
- bool CompareAsDouble(const TraceEvent& event, bool* result) const;
-
- // Try to compare left_ against right_ based on operator_.
- // If either left or right does not convert to string, false is returned.
- // Otherwise, true is returned and |result| is set to the comparison result.
- bool CompareAsString(const TraceEvent& event, bool* result) const;
-
- // Attempt to convert this Query to a double. On success, true is returned
- // and the double value is stored in |num|.
- bool GetAsDouble(const TraceEvent& event, double* num) const;
-
- // Attempt to convert this Query to a string. On success, true is returned
- // and the string value is stored in |str|.
- bool GetAsString(const TraceEvent& event, std::string* str) const;
-
- // Evaluate this Query as an arithmetic operator on left_ and right_.
- bool EvaluateArithmeticOperator(const TraceEvent& event,
- double* num) const;
-
- // For QUERY_EVENT_MEMBER Query: attempt to get the double value of the Query.
- bool GetMemberValueAsDouble(const TraceEvent& event, double* num) const;
-
- // For QUERY_EVENT_MEMBER Query: attempt to get the string value of the Query.
- bool GetMemberValueAsString(const TraceEvent& event, std::string* num) const;
-
- // Does this Query represent a value?
- bool is_value() const { return type_ != QUERY_BOOLEAN_OPERATOR; }
-
- bool is_unary_operator() const {
- return operator_ == OP_NOT || operator_ == OP_NEGATE;
- }
-
- bool is_comparison_operator() const {
- return operator_ != OP_INVALID && operator_ < OP_AND;
- }
-
- static const TraceEvent* SelectTargetEvent(const TraceEvent* ev,
- TraceEventMember member);
-
- const Query& left() const;
- const Query& right() const;
-
- private:
- QueryType type_;
- Operator operator_;
- scoped_refptr<QueryNode> left_;
- scoped_refptr<QueryNode> right_;
- TraceEventMember member_;
- double number_;
- std::string string_;
- bool is_pattern_;
-};
-
-// Implementation detail:
-// QueryNode allows Query to store a ref-counted query tree.
-class QueryNode : public base::RefCounted<QueryNode> {
- public:
- explicit QueryNode(const Query& query);
- const Query& query() const { return query_; }
-
- private:
- friend class base::RefCounted<QueryNode>;
- ~QueryNode();
-
- Query query_;
-};
-
-// TraceAnalyzer helps tests search for trace events.
-class TraceAnalyzer {
- public:
- ~TraceAnalyzer();
-
- // Use trace events from JSON string generated by tracing API.
- // Returns non-NULL if the JSON is successfully parsed.
- static TraceAnalyzer* Create(const std::string& json_events)
- WARN_UNUSED_RESULT;
-
- void SetIgnoreMetadataEvents(bool ignore) {
- ignore_metadata_events_ = ignore;
- }
-
- // Associate BEGIN and END events with each other. This allows Query(OTHER_*)
- // to access the associated event and enables Query(EVENT_DURATION).
- // An end event will match the most recent begin event with the same name,
- // category, process ID and thread ID. This matches what is shown in
- // about:tracing. After association, the BEGIN event will point to the
- // matching END event, but the END event will not point to the BEGIN event.
- void AssociateBeginEndEvents();
-
- // Associate ASYNC_BEGIN, ASYNC_STEP and ASYNC_END events with each other.
- // An ASYNC_END event will match the most recent ASYNC_BEGIN or ASYNC_STEP
- // event with the same name, category, and ID. This creates a singly linked
- // list of ASYNC_BEGIN->ASYNC_STEP...->ASYNC_END.
- // |match_pid| - If true, will only match async events which are running
- // under the same process ID, otherwise will allow linking
- // async events from different processes.
- void AssociateAsyncBeginEndEvents(bool match_pid = true);
-
- // AssociateEvents can be used to customize event associations by setting the
- // other_event member of TraceEvent. This should be used to associate two
- // INSTANT events.
- //
- // The assumptions are:
- // - |first| events occur before |second| events.
- // - the closest matching |second| event is the correct match.
- //
- // |first| - Eligible |first| events match this query.
- // |second| - Eligible |second| events match this query.
- // |match| - This query is run on the |first| event. The OTHER_* EventMember
- // queries will point to an eligible |second| event. The query
- // should evaluate to true if the |first|/|second| pair is a match.
- //
- // When a match is found, the pair will be associated by having the first
- // event's other_event member point to the other. AssociateEvents does not
- // clear previous associations, so it is possible to associate multiple pairs
- // of events by calling AssociateEvents more than once with different queries.
- //
- // NOTE: AssociateEvents will overwrite existing other_event associations if
- // the queries pass for events that already had a previous association.
- //
- // After calling any Find* method, it is not allowed to call AssociateEvents
- // again.
- void AssociateEvents(const Query& first,
- const Query& second,
- const Query& match);
-
- // For each event, copy its arguments to the other_event argument map. If
- // argument name already exists, it will not be overwritten.
- void MergeAssociatedEventArgs();
-
- // Find all events that match query and replace output vector.
- size_t FindEvents(const Query& query, TraceEventVector* output);
-
- // Find first event that matches query or NULL if not found.
- const TraceEvent* FindFirstOf(const Query& query);
-
- // Find last event that matches query or NULL if not found.
- const TraceEvent* FindLastOf(const Query& query);
-
- const std::string& GetThreadName(const TraceEvent::ProcessThreadID& thread);
-
- private:
- TraceAnalyzer();
-
- bool SetEvents(const std::string& json_events) WARN_UNUSED_RESULT;
-
- // Read metadata (thread names, etc) from events.
- void ParseMetadata();
-
- std::map<TraceEvent::ProcessThreadID, std::string> thread_names_;
- std::vector<TraceEvent> raw_events_;
- bool ignore_metadata_events_;
- bool allow_association_changes_;
-
- DISALLOW_COPY_AND_ASSIGN(TraceAnalyzer);
-};
-
-// Utility functions for collecting process-local traces and creating a
-// |TraceAnalyzer| from the result. Please see comments in trace_config.h to
-// understand how the |category_filter_string| works. Use "*" to enable all
-// default categories.
-void Start(const std::string& category_filter_string);
-std::unique_ptr<TraceAnalyzer> Stop();
-
-// Utility functions for TraceEventVector.
-
-struct RateStats {
- double min_us;
- double max_us;
- double mean_us;
- double standard_deviation_us;
-};
-
-struct RateStatsOptions {
- RateStatsOptions() : trim_min(0u), trim_max(0u) {}
- // After the times between events are sorted, the number of specified elements
- // will be trimmed before calculating the RateStats. This is useful in cases
- // where extreme outliers are tolerable and should not skew the overall
- // average.
- size_t trim_min; // Trim this many minimum times.
- size_t trim_max; // Trim this many maximum times.
-};
-
-// Calculate min/max/mean and standard deviation from the times between
-// adjacent events.
-bool GetRateStats(const TraceEventVector& events,
- RateStats* stats,
- const RateStatsOptions* options);
-
-// Starting from |position|, find the first event that matches |query|.
-// Returns true if found, false otherwise.
-bool FindFirstOf(const TraceEventVector& events,
- const Query& query,
- size_t position,
- size_t* return_index);
-
-// Starting from |position|, find the last event that matches |query|.
-// Returns true if found, false otherwise.
-bool FindLastOf(const TraceEventVector& events,
- const Query& query,
- size_t position,
- size_t* return_index);
-
-// Find the closest events to |position| in time that match |query|.
-// return_second_closest may be NULL. Closeness is determined by comparing
-// with the event timestamp.
-// Returns true if found, false otherwise. If both return parameters are
-// requested, both must be found for a successful result.
-bool FindClosest(const TraceEventVector& events,
- const Query& query,
- size_t position,
- size_t* return_closest,
- size_t* return_second_closest);
-
-// Count matches, inclusive of |begin_position|, exclusive of |end_position|.
-size_t CountMatches(const TraceEventVector& events,
- const Query& query,
- size_t begin_position,
- size_t end_position);
-
-// Count all matches.
-static inline size_t CountMatches(const TraceEventVector& events,
- const Query& query) {
- return CountMatches(events, query, 0u, events.size());
-}
-
-} // namespace trace_analyzer
-
-#endif // BASE_TEST_TRACE_EVENT_ANALYZER_H_
diff --git a/base/threading/thread_id_name_manager.cc b/base/threading/thread_id_name_manager.cc
index ca1979d..101b57d 100644
--- a/base/threading/thread_id_name_manager.cc
+++ b/base/threading/thread_id_name_manager.cc
@@ -12,7 +12,6 @@
#include "base/no_destructor.h"
#include "base/strings/string_util.h"
#include "base/threading/thread_local.h"
-#include "base/trace_event/heap_profiler_allocation_context_tracker.h"
namespace base {
namespace {
@@ -88,14 +87,6 @@
}
thread_handle_to_interned_name_[id_to_handle_iter->second] = leaked_str;
}
-
- // Add the leaked thread name to heap profiler context tracker. The name added
- // is valid for the lifetime of the process. AllocationContextTracker cannot
- // call GetName(which holds a lock) during the first allocation because it can
- // cause a deadlock when the first allocation happens in the
- // ThreadIdNameManager itself when holding the lock.
- trace_event::AllocationContextTracker::SetCurrentThreadName(
- leaked_str->c_str());
}
const char* ThreadIdNameManager::GetName(PlatformThreadId id) {
diff --git a/base/trace_event/OWNERS b/base/trace_event/OWNERS
deleted file mode 100644
index 24a0bd2..0000000
--- a/base/trace_event/OWNERS
+++ /dev/null
@@ -1,15 +0,0 @@
-chiniforooshan@chromium.org
-oysteine@chromium.org
-primiano@chromium.org
-per-file trace_event_android.cc=wangxianzhu@chromium.org
-
-# For memory-infra related changes
-ssid@chromium.org
-
-# Emeritus:
-dsinclair@chromium.org
-nduca@chromium.org
-simonhatch@chromium.org
-
-# TEAM: tracing@chromium.org
-# COMPONENT: Speed>Tracing
diff --git a/base/trace_event/auto_open_close_event.cc b/base/trace_event/auto_open_close_event.cc
deleted file mode 100644
index 1879700..0000000
--- a/base/trace_event/auto_open_close_event.cc
+++ /dev/null
@@ -1,52 +0,0 @@
-// Copyright 2016 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/auto_open_close_event.h"
-
-#include "base/macros.h"
-#include "base/time/time.h"
-#include "base/trace_event/trace_event.h"
-
-namespace base {
-namespace trace_event {
-
-AutoOpenCloseEvent::AutoOpenCloseEvent(AutoOpenCloseEvent::Type type,
- const char* category, const char* event_name):
- category_(category),
- event_name_(event_name),
- weak_factory_(this) {
- base::trace_event::TraceLog::GetInstance()->AddAsyncEnabledStateObserver(
- weak_factory_.GetWeakPtr());
-}
-
-AutoOpenCloseEvent::~AutoOpenCloseEvent() {
- DCHECK(thread_checker_.CalledOnValidThread());
- base::trace_event::TraceLog::GetInstance()->RemoveAsyncEnabledStateObserver(
- this);
-}
-
-void AutoOpenCloseEvent::Begin() {
- DCHECK(thread_checker_.CalledOnValidThread());
- start_time_ = TRACE_TIME_TICKS_NOW();
- TRACE_EVENT_ASYNC_BEGIN_WITH_TIMESTAMP0(
- category_, event_name_, static_cast<void*>(this), start_time_);
-}
-
-void AutoOpenCloseEvent::End() {
- DCHECK(thread_checker_.CalledOnValidThread());
- TRACE_EVENT_ASYNC_END0(category_, event_name_, static_cast<void*>(this));
- start_time_ = base::TimeTicks();
-}
-
-void AutoOpenCloseEvent::OnTraceLogEnabled() {
- DCHECK(thread_checker_.CalledOnValidThread());
- if (start_time_.ToInternalValue() != 0)
- TRACE_EVENT_ASYNC_BEGIN_WITH_TIMESTAMP0(
- category_, event_name_, static_cast<void*>(this), start_time_);
-}
-
-void AutoOpenCloseEvent::OnTraceLogDisabled() {}
-
-} // namespace trace_event
-} // namespace base
diff --git a/base/trace_event/auto_open_close_event.h b/base/trace_event/auto_open_close_event.h
deleted file mode 100644
index 795a494..0000000
--- a/base/trace_event/auto_open_close_event.h
+++ /dev/null
@@ -1,57 +0,0 @@
-// Copyright 2016 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_AUTO_OPEN_CLOSE_EVENT_H_
-#define BASE_AUTO_OPEN_CLOSE_EVENT_H_
-
-#include "base/macros.h"
-#include "base/memory/weak_ptr.h"
-#include "base/threading/thread_checker.h"
-#include "base/time/time.h"
-#include "base/trace_event/trace_event.h"
-
-namespace base {
-namespace trace_event {
-
-// Class for tracing events that support "auto-opening" and "auto-closing".
-// "auto-opening" = if the trace event is started (call Begin() before
-// tracing is started,the trace event will be opened, with the start time
-// being the time that the trace event was actually started.
-// "auto-closing" = if the trace event is started but not ended by the time
-// tracing ends, then the trace event will be automatically closed at the
-// end of tracing.
-class BASE_EXPORT AutoOpenCloseEvent
- : public TraceLog::AsyncEnabledStateObserver {
- public:
- enum Type {
- ASYNC
- };
-
- // As in the rest of the tracing macros, the const char* arguments here
- // must be pointers to indefinitely lived strings (e.g. hard-coded string
- // literals are okay, but not strings created by c_str())
- AutoOpenCloseEvent(Type type, const char* category, const char* event_name);
- ~AutoOpenCloseEvent() override;
-
- void Begin();
- void End();
-
- // AsyncEnabledStateObserver implementation
- void OnTraceLogEnabled() override;
- void OnTraceLogDisabled() override;
-
- private:
- const char* const category_;
- const char* const event_name_;
- base::TimeTicks start_time_;
- base::ThreadChecker thread_checker_;
- WeakPtrFactory<AutoOpenCloseEvent> weak_factory_;
-
- DISALLOW_COPY_AND_ASSIGN(AutoOpenCloseEvent);
-};
-
-} // namespace trace_event
-} // namespace base
-
-#endif // BASE_AUTO_OPEN_CLOSE_EVENT_H_
\ No newline at end of file
diff --git a/base/trace_event/blame_context.cc b/base/trace_event/blame_context.cc
deleted file mode 100644
index ae0b718..0000000
--- a/base/trace_event/blame_context.cc
+++ /dev/null
@@ -1,111 +0,0 @@
-// Copyright 2016 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/blame_context.h"
-
-#include "base/strings/stringprintf.h"
-#include "base/trace_event/trace_event.h"
-#include "base/trace_event/trace_event_argument.h"
-
-namespace base {
-namespace trace_event {
-
-BlameContext::BlameContext(const char* category,
- const char* name,
- const char* type,
- const char* scope,
- int64_t id,
- const BlameContext* parent_context)
- : category_(category),
- name_(name),
- type_(type),
- scope_(scope),
- id_(id),
- parent_scope_(parent_context ? parent_context->scope() : nullptr),
- parent_id_(parent_context ? parent_context->id() : 0),
- category_group_enabled_(nullptr),
- weak_factory_(this) {
- DCHECK(!parent_context || !std::strcmp(name_, parent_context->name()))
- << "Parent blame context must have the same name";
-}
-
-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_, 0, nullptr, nullptr, nullptr, nullptr, TRACE_EVENT_FLAG_HAS_ID);
- trace_event::TraceLog::GetInstance()->RemoveAsyncEnabledStateObserver(this);
-}
-
-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);
-}
-
-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);
-}
-
-void BlameContext::TakeSnapshot() {
- DCHECK(thread_checker_.CalledOnValidThread());
- DCHECK(WasInitialized());
- if (!*category_group_enabled_)
- return;
- std::unique_ptr<trace_event::TracedValue> snapshot(
- new trace_event::TracedValue);
- AsValueInto(snapshot.get());
- 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_,
- kNumArgs, &kArgName, arg_types, nullptr,
- arg_values, TRACE_EVENT_FLAG_HAS_ID);
-}
-
-void BlameContext::OnTraceLogEnabled() {
- DCHECK(WasInitialized());
- TakeSnapshot();
-}
-
-void BlameContext::OnTraceLogDisabled() {}
-
-void BlameContext::AsValueInto(trace_event::TracedValue* state) {
- DCHECK(WasInitialized());
- if (!parent_id_)
- return;
- state->BeginDictionary("parent");
- state->SetString("id_ref", StringPrintf("0x%" PRIx64, parent_id_));
- state->SetString("scope", parent_scope_);
- state->EndDictionary();
-}
-
-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_, 0, nullptr, nullptr, nullptr, nullptr, TRACE_EVENT_FLAG_HAS_ID);
- trace_event::TraceLog::GetInstance()->AddAsyncEnabledStateObserver(
- weak_factory_.GetWeakPtr());
- TakeSnapshot();
-}
-
-bool BlameContext::WasInitialized() const {
- return category_group_enabled_ != nullptr;
-}
-
-} // namespace trace_event
-} // namespace base
diff --git a/base/trace_event/blame_context.h b/base/trace_event/blame_context.h
deleted file mode 100644
index a973a28..0000000
--- a/base/trace_event/blame_context.h
+++ /dev/null
@@ -1,138 +0,0 @@
-// Copyright 2016 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_BLAME_CONTEXT_H_
-#define BASE_TRACE_EVENT_BLAME_CONTEXT_H_
-
-#include <inttypes.h>
-
-#include "base/base_export.h"
-#include "base/macros.h"
-#include "base/threading/thread_checker.h"
-#include "base/trace_event/trace_log.h"
-
-namespace base {
-namespace trace_event {
-class TracedValue;
-}
-
-namespace trace_event {
-
-// A blame context represents a logical unit to which we want to attribute
-// different costs (e.g., CPU, network, or memory usage). An example of a blame
-// context is an <iframe> element on a web page. Different subsystems can
-// "enter" and "leave" blame contexts to indicate that they are doing work which
-// should be accounted against this blame context.
-//
-// A blame context can optionally have a parent context, forming a blame context
-// tree. When work is attributed to a particular blame context, it is considered
-// to count against all of that context's children too. This is useful when work
-// cannot be exactly attributed into a more specific context. For example,
-// Javascript garbage collection generally needs to inspect all objects on a
-// page instead looking at each <iframe> individually. In this case the work
-// should be attributed to a blame context which is the parent of all <iframe>
-// blame contexts.
-class BASE_EXPORT BlameContext
- : public trace_event::TraceLog::AsyncEnabledStateObserver {
- public:
- // Construct a blame context belonging to the blame context tree |name|, using
- // the tracing category |category|, identified by |id| from the |scope|
- // namespace. |type| identifies the type of this object snapshot in the blame
- // context tree. |parent_context| is the parent of this blame context or
- // null. Note that all strings must have application lifetime.
- //
- // For example, a blame context which represents a specific <iframe> in a
- // browser frame tree could be specified with:
- //
- // category="blink",
- // name="FrameTree",
- // type="IFrame",
- // scope="IFrameIdentifier",
- // id=1234.
- //
- // Each <iframe> blame context could have another <iframe> context as a
- // parent, or a top-level context which represents the entire browser:
- //
- // category="blink",
- // name="FrameTree",
- // type="Browser",
- // scope="BrowserIdentifier",
- // id=1.
- //
- // Note that the |name| property is identical, signifying that both context
- // types are part of the same tree.
- //
- BlameContext(const char* category,
- const char* name,
- const char* type,
- const char* scope,
- int64_t id,
- const BlameContext* parent_context);
- ~BlameContext() override;
-
- // Initialize the blame context, automatically taking a snapshot if tracing is
- // enabled. Must be called before any other methods on this class.
- void Initialize();
-
- // Indicate that the current thread is now doing work which should count
- // against this blame context. This function is allowed to be called in a
- // thread different from where the blame context was created; However, any
- // client doing that must be fully responsible for ensuring thready safety.
- void Enter();
-
- // Leave and stop doing work for a previously entered blame context. If
- // another blame context belonging to the same tree was entered prior to this
- // one, it becomes the active blame context for this thread again. Similar
- // to Enter(), this function can be called in a thread different from where
- // the blame context was created, and the same requirement on thread safety
- // must be satisfied.
- void Leave();
-
- // Record a snapshot of the blame context. This is normally only needed if a
- // blame context subclass defines custom properties (see AsValueInto) and one
- // or more of those properties have changed.
- void TakeSnapshot();
-
- const char* category() const { return category_; }
- const char* name() const { return name_; }
- const char* type() const { return type_; }
- const char* scope() const { return scope_; }
- int64_t id() const { return id_; }
-
- // trace_event::TraceLog::EnabledStateObserver implementation:
- void OnTraceLogEnabled() override;
- void OnTraceLogDisabled() override;
-
- protected:
- // Serialize the properties of this blame context into |state|. Subclasses can
- // override this method to record additional properties (e.g, the URL for an
- // <iframe> blame context). Note that an overridden implementation must still
- // call this base method.
- virtual void AsValueInto(trace_event::TracedValue* state);
-
- private:
- bool WasInitialized() const;
-
- // The following string pointers have application lifetime.
- const char* category_;
- const char* name_;
- const char* type_;
- const char* scope_;
- const int64_t id_;
-
- const char* parent_scope_;
- const int64_t parent_id_;
-
- const unsigned char* category_group_enabled_;
-
- ThreadChecker thread_checker_;
- WeakPtrFactory<BlameContext> weak_factory_;
-
- DISALLOW_COPY_AND_ASSIGN(BlameContext);
-};
-
-} // namespace trace_event
-} // namespace base
-
-#endif // BASE_TRACE_EVENT_BLAME_CONTEXT_H_
diff --git a/base/trace_event/category_registry.cc b/base/trace_event/category_registry.cc
deleted file mode 100644
index e7c1460..0000000
--- a/base/trace_event/category_registry.cc
+++ /dev/null
@@ -1,156 +0,0 @@
-// Copyright 2016 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/category_registry.h"
-
-#include <string.h>
-
-#include <type_traits>
-
-#include "base/atomicops.h"
-#include "base/debug/leak_annotations.h"
-#include "base/logging.h"
-#include "base/third_party/dynamic_annotations/dynamic_annotations.h"
-#include "base/trace_event/trace_category.h"
-
-namespace base {
-namespace trace_event {
-
-namespace {
-
-constexpr size_t kMaxCategories = 200;
-const int kNumBuiltinCategories = 4;
-
-// |g_categories| might end up causing creating dynamic initializers if not POD.
-static_assert(std::is_pod<TraceCategory>::value, "TraceCategory must be POD");
-
-// These entries must be kept consistent with the kCategory* consts below.
-TraceCategory g_categories[kMaxCategories] = {
- {0, 0, "tracing categories exhausted; must increase kMaxCategories"},
- {0, 0, "tracing already shutdown"}, // See kCategoryAlreadyShutdown below.
- {0, 0, "__metadata"}, // See kCategoryMetadata below.
- {0, 0, "toplevel"}, // Warmup the toplevel category.
-};
-
-base::subtle::AtomicWord g_category_index = kNumBuiltinCategories;
-
-bool IsValidCategoryPtr(const TraceCategory* category) {
- // If any of these are hit, something has cached a corrupt category pointer.
- uintptr_t ptr = reinterpret_cast<uintptr_t>(category);
- return ptr % sizeof(void*) == 0 &&
- ptr >= reinterpret_cast<uintptr_t>(&g_categories[0]) &&
- ptr <= reinterpret_cast<uintptr_t>(&g_categories[kMaxCategories - 1]);
-}
-
-} // namespace
-
-// static
-TraceCategory* const CategoryRegistry::kCategoryExhausted = &g_categories[0];
-TraceCategory* const CategoryRegistry::kCategoryAlreadyShutdown =
- &g_categories[1];
-TraceCategory* const CategoryRegistry::kCategoryMetadata = &g_categories[2];
-
-// static
-void CategoryRegistry::Initialize() {
- // Trace is enabled or disabled on one thread while other threads are
- // accessing the enabled flag. We don't care whether edge-case events are
- // traced or not, so we allow races on the enabled flag to keep the trace
- // macros fast.
- for (size_t i = 0; i < kMaxCategories; ++i) {
- ANNOTATE_BENIGN_RACE(g_categories[i].state_ptr(),
- "trace_event category enabled");
- // If this DCHECK is hit in a test it means that ResetForTesting() is not
- // called and the categories state leaks between test fixtures.
- DCHECK(!g_categories[i].is_enabled());
- }
-}
-
-// static
-void CategoryRegistry::ResetForTesting() {
- // reset_for_testing clears up only the enabled state and filters. The
- // categories themselves cannot be cleared up because the static pointers
- // injected by the macros still point to them and cannot be reset.
- for (size_t i = 0; i < kMaxCategories; ++i)
- g_categories[i].reset_for_testing();
-}
-
-// static
-TraceCategory* CategoryRegistry::GetCategoryByName(const char* category_name) {
- DCHECK(!strchr(category_name, '"'))
- << "Category names may not contain double quote";
-
- // The g_categories is append only, avoid using a lock for the fast path.
- size_t category_index = base::subtle::Acquire_Load(&g_category_index);
-
- // Search for pre-existing category group.
- for (size_t i = 0; i < category_index; ++i) {
- if (strcmp(g_categories[i].name(), category_name) == 0) {
- return &g_categories[i];
- }
- }
- return nullptr;
-}
-
-bool CategoryRegistry::GetOrCreateCategoryLocked(
- const char* category_name,
- CategoryInitializerFn category_initializer_fn,
- TraceCategory** category) {
- // This is the slow path: the lock is not held in the fastpath
- // (GetCategoryByName), so more than one thread could have reached here trying
- // to add the same category.
- *category = GetCategoryByName(category_name);
- if (*category)
- return false;
-
- // Create a new category.
- size_t category_index = base::subtle::Acquire_Load(&g_category_index);
- if (category_index >= kMaxCategories) {
- NOTREACHED() << "must increase kMaxCategories";
- *category = kCategoryExhausted;
- return false;
- }
-
- // TODO(primiano): this strdup should be removed. The only documented reason
- // for it was TraceWatchEvent, which is gone. However, something might have
- // ended up relying on this. Needs some auditing before removal.
- const char* category_name_copy = strdup(category_name);
- ANNOTATE_LEAKING_OBJECT_PTR(category_name_copy);
-
- *category = &g_categories[category_index];
- DCHECK(!(*category)->is_valid());
- DCHECK(!(*category)->is_enabled());
- (*category)->set_name(category_name_copy);
- category_initializer_fn(*category);
-
- // Update the max index now.
- base::subtle::Release_Store(&g_category_index, category_index + 1);
- return true;
-}
-
-// static
-const TraceCategory* CategoryRegistry::GetCategoryByStatePtr(
- const uint8_t* category_state) {
- const TraceCategory* category = TraceCategory::FromStatePtr(category_state);
- DCHECK(IsValidCategoryPtr(category));
- return category;
-}
-
-// static
-bool CategoryRegistry::IsBuiltinCategory(const TraceCategory* category) {
- DCHECK(IsValidCategoryPtr(category));
- return category < &g_categories[kNumBuiltinCategories];
-}
-
-// static
-CategoryRegistry::Range CategoryRegistry::GetAllCategories() {
- // The |g_categories| array is append only. We have to only guarantee to
- // not return an index to a category which is being initialized by
- // GetOrCreateCategoryByName().
- size_t category_index = base::subtle::Acquire_Load(&g_category_index);
- return CategoryRegistry::Range(&g_categories[0],
- &g_categories[category_index]);
-}
-
-} // namespace trace_event
-} // namespace base
diff --git a/base/trace_event/category_registry.h b/base/trace_event/category_registry.h
deleted file mode 100644
index 9c08efa..0000000
--- a/base/trace_event/category_registry.h
+++ /dev/null
@@ -1,93 +0,0 @@
-// Copyright 2016 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_CATEGORY_REGISTRY_H_
-#define BASE_TRACE_EVENT_CATEGORY_REGISTRY_H_
-
-#include <stddef.h>
-#include <stdint.h>
-
-#include "base/base_export.h"
-#include "base/logging.h"
-
-namespace base {
-namespace trace_event {
-
-struct TraceCategory;
-class TraceCategoryTest;
-class TraceLog;
-
-// Allows fast and thread-safe acces to the state of all tracing categories.
-// All the methods in this class can be concurrently called on multiple threads,
-// unless otherwise noted (e.g., GetOrCreateCategoryLocked).
-// The reason why this is a fully static class with global state is to allow to
-// statically define known categories as global linker-initialized structs,
-// without requiring static initializers.
-class BASE_EXPORT CategoryRegistry {
- public:
- // Allows for-each iterations over a slice of the categories array.
- class Range {
- public:
- Range(TraceCategory* begin, TraceCategory* end) : begin_(begin), end_(end) {
- DCHECK_LE(begin, end);
- }
- TraceCategory* begin() const { return begin_; }
- TraceCategory* end() const { return end_; }
-
- private:
- TraceCategory* const begin_;
- TraceCategory* const end_;
- };
-
- // Known categories.
- static TraceCategory* const kCategoryExhausted;
- static TraceCategory* const kCategoryMetadata;
- static TraceCategory* const kCategoryAlreadyShutdown;
-
- // Returns a category entry from the Category.state_ptr() pointer.
- // TODO(primiano): trace macros should just keep a pointer to the entire
- // TraceCategory, not just the enabled state pointer. That would remove the
- // need for this function and make everything cleaner at no extra cost (as
- // long as the |state_| is the first field of the struct, which can be
- // guaranteed via static_assert, see TraceCategory ctor).
- static const TraceCategory* GetCategoryByStatePtr(
- const uint8_t* category_state);
-
- // Returns a category from its name or nullptr if not found.
- // The output |category| argument is an undefinitely lived pointer to the
- // TraceCategory owned by the registry. TRACE_EVENTx macros will cache this
- // pointer and use it for checks in their fast-paths.
- static TraceCategory* GetCategoryByName(const char* category_name);
-
- static bool IsBuiltinCategory(const TraceCategory*);
-
- private:
- friend class TraceCategoryTest;
- friend class TraceLog;
- using CategoryInitializerFn = void (*)(TraceCategory*);
-
- // Only for debugging/testing purposes, is a no-op on release builds.
- static void Initialize();
-
- // Resets the state of all categories, to clear up the state between tests.
- static void ResetForTesting();
-
- // Used to get/create a category in the slow-path. If the category exists
- // already, this has the same effect of GetCategoryByName and returns false.
- // If not, a new category is created and the CategoryInitializerFn is invoked
- // before retuning true. The caller must guarantee serialization: either call
- // this method from a single thread or hold a lock when calling this.
- static bool GetOrCreateCategoryLocked(const char* category_name,
- CategoryInitializerFn,
- TraceCategory**);
-
- // Allows to iterate over the valid categories in a for-each loop.
- // This includes builtin categories such as __metadata.
- static Range GetAllCategories();
-};
-
-} // namespace trace_event
-} // namespace base
-
-#endif // BASE_TRACE_EVENT_CATEGORY_REGISTRY_H_
diff --git a/base/trace_event/common/trace_event_common.h b/base/trace_event/common/trace_event_common.h
deleted file mode 100644
index e2a5ca0..0000000
--- a/base/trace_event/common/trace_event_common.h
+++ /dev/null
@@ -1,1114 +0,0 @@
-// Copyright 2015 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_COMMON_TRACE_EVENT_COMMON_H_
-#define BASE_TRACE_EVENT_COMMON_TRACE_EVENT_COMMON_H_
-
-// This header file defines the set of trace_event macros without specifying
-// how the events actually get collected and stored. If you need to expose trace
-// events to some other universe, you can copy-and-paste this file as well as
-// trace_event.h, modifying the macros contained there as necessary for the
-// target platform. The end result is that multiple libraries can funnel events
-// through to a shared trace event collector.
-
-// IMPORTANT: To avoid conflicts, if you need to modify this file for a library,
-// land your change in base/ first, and then copy-and-paste it.
-
-// Trace events are for tracking application performance and resource usage.
-// Macros are provided to track:
-// Begin and end of function calls
-// Counters
-//
-// Events are issued against categories. Whereas LOG's
-// categories are statically defined, TRACE categories are created
-// implicitly with a string. For example:
-// TRACE_EVENT_INSTANT0("MY_SUBSYSTEM", "SomeImportantEvent",
-// TRACE_EVENT_SCOPE_THREAD)
-//
-// It is often the case that one trace may belong in multiple categories at the
-// same time. The first argument to the trace can be a comma-separated list of
-// categories, forming a category group, like:
-//
-// TRACE_EVENT_INSTANT0("input,views", "OnMouseOver", TRACE_EVENT_SCOPE_THREAD)
-//
-// We can enable/disable tracing of OnMouseOver by enabling/disabling either
-// category.
-//
-// Events can be INSTANT, or can be pairs of BEGIN and END in the same scope:
-// TRACE_EVENT_BEGIN0("MY_SUBSYSTEM", "SomethingCostly")
-// doSomethingCostly()
-// TRACE_EVENT_END0("MY_SUBSYSTEM", "SomethingCostly")
-// Note: our tools can't always determine the correct BEGIN/END pairs unless
-// these are used in the same scope. Use ASYNC_BEGIN/ASYNC_END macros if you
-// need them to be in separate scopes.
-//
-// A common use case is to trace entire function scopes. This
-// issues a trace BEGIN and END automatically:
-// void doSomethingCostly() {
-// TRACE_EVENT0("MY_SUBSYSTEM", "doSomethingCostly");
-// ...
-// }
-//
-// Additional parameters can be associated with an event:
-// void doSomethingCostly2(int howMuch) {
-// TRACE_EVENT1("MY_SUBSYSTEM", "doSomethingCostly",
-// "howMuch", howMuch);
-// ...
-// }
-//
-// The trace system will automatically add to this information the
-// current process id, thread id, and a timestamp in microseconds.
-//
-// To trace an asynchronous procedure such as an IPC send/receive, use
-// ASYNC_BEGIN and ASYNC_END:
-// [single threaded sender code]
-// static int send_count = 0;
-// ++send_count;
-// TRACE_EVENT_ASYNC_BEGIN0("ipc", "message", send_count);
-// Send(new MyMessage(send_count));
-// [receive code]
-// void OnMyMessage(send_count) {
-// TRACE_EVENT_ASYNC_END0("ipc", "message", send_count);
-// }
-// The third parameter is a unique ID to match ASYNC_BEGIN/ASYNC_END pairs.
-// ASYNC_BEGIN and ASYNC_END can occur on any thread of any traced process.
-// Pointers can be used for the ID parameter, and they will be mangled
-// internally so that the same pointer on two different processes will not
-// match. For example:
-// class MyTracedClass {
-// public:
-// MyTracedClass() {
-// TRACE_EVENT_ASYNC_BEGIN0("category", "MyTracedClass", this);
-// }
-// ~MyTracedClass() {
-// TRACE_EVENT_ASYNC_END0("category", "MyTracedClass", this);
-// }
-// }
-//
-// Trace event also supports counters, which is a way to track a quantity
-// as it varies over time. Counters are created with the following macro:
-// TRACE_COUNTER1("MY_SUBSYSTEM", "myCounter", g_myCounterValue);
-//
-// Counters are process-specific. The macro itself can be issued from any
-// thread, however.
-//
-// Sometimes, you want to track two counters at once. You can do this with two
-// counter macros:
-// TRACE_COUNTER1("MY_SUBSYSTEM", "myCounter0", g_myCounterValue[0]);
-// TRACE_COUNTER1("MY_SUBSYSTEM", "myCounter1", g_myCounterValue[1]);
-// Or you can do it with a combined macro:
-// TRACE_COUNTER2("MY_SUBSYSTEM", "myCounter",
-// "bytesPinned", g_myCounterValue[0],
-// "bytesAllocated", g_myCounterValue[1]);
-// This indicates to the tracing UI that these counters should be displayed
-// in a single graph, as a summed area chart.
-//
-// Since counters are in a global namespace, you may want to disambiguate with a
-// unique ID, by using the TRACE_COUNTER_ID* variations.
-//
-// By default, trace collection is compiled in, but turned off at runtime.
-// Collecting trace data is the responsibility of the embedding
-// application. In Chrome's case, navigating to about:tracing will turn on
-// tracing and display data collected across all active processes.
-//
-//
-// Memory scoping note:
-// Tracing copies the pointers, not the string content, of the strings passed
-// in for category_group, name, and arg_names. Thus, the following code will
-// cause problems:
-// char* str = strdup("importantName");
-// TRACE_EVENT_INSTANT0("SUBSYSTEM", str); // BAD!
-// free(str); // Trace system now has dangling pointer
-//
-// To avoid this issue with the |name| and |arg_name| parameters, use the
-// TRACE_EVENT_COPY_XXX overloads of the macros at additional runtime overhead.
-// Notes: The category must always be in a long-lived char* (i.e. static const).
-// The |arg_values|, when used, are always deep copied with the _COPY
-// macros.
-//
-// When are string argument values copied:
-// const char* arg_values are only referenced by default:
-// TRACE_EVENT1("category", "name",
-// "arg1", "literal string is only referenced");
-// Use TRACE_STR_COPY to force copying of a const char*:
-// TRACE_EVENT1("category", "name",
-// "arg1", TRACE_STR_COPY("string will be copied"));
-// std::string arg_values are always copied:
-// TRACE_EVENT1("category", "name",
-// "arg1", std::string("string will be copied"));
-//
-//
-// Convertable notes:
-// Converting a large data type to a string can be costly. To help with this,
-// the trace framework provides an interface ConvertableToTraceFormat. If you
-// inherit from it and implement the AppendAsTraceFormat method the trace
-// framework will call back to your object to convert a trace output time. This
-// means, if the category for the event is disabled, the conversion will not
-// happen.
-//
-// class MyData : public base::trace_event::ConvertableToTraceFormat {
-// public:
-// MyData() {}
-// void AppendAsTraceFormat(std::string* out) const override {
-// out->append("{\"foo\":1}");
-// }
-// private:
-// ~MyData() override {}
-// DISALLOW_COPY_AND_ASSIGN(MyData);
-// };
-//
-// TRACE_EVENT1("foo", "bar", "data",
-// std::unique_ptr<ConvertableToTraceFormat>(new MyData()));
-//
-// The trace framework will take ownership if the passed pointer and it will
-// be free'd when the trace buffer is flushed.
-//
-// Note, we only do the conversion when the buffer is flushed, so the provided
-// data object should not be modified after it's passed to the trace framework.
-//
-//
-// Thread Safety:
-// A thread safe singleton and mutex are used for thread safety. Category
-// enabled flags are used to limit the performance impact when the system
-// is not enabled.
-//
-// TRACE_EVENT macros first cache a pointer to a category. The categories are
-// statically allocated and safe at all times, even after exit. Fetching a
-// category is protected by the TraceLog::lock_. Multiple threads initializing
-// the static variable is safe, as they will be serialized by the lock and
-// multiple calls will return the same pointer to the category.
-//
-// Then the category_group_enabled flag is checked. This is a unsigned char, and
-// not intended to be multithread safe. It optimizes access to AddTraceEvent
-// which is threadsafe internally via TraceLog::lock_. The enabled flag may
-// cause some threads to incorrectly call or skip calling AddTraceEvent near
-// the time of the system being enabled or disabled. This is acceptable as
-// we tolerate some data loss while the system is being enabled/disabled and
-// because AddTraceEvent is threadsafe internally and checks the enabled state
-// again under lock.
-//
-// Without the use of these static category pointers and enabled flags all
-// trace points would carry a significant performance cost of acquiring a lock
-// and resolving the category.
-
-// Check that nobody includes this file directly. Clients are supposed to
-// include the surrounding "trace_event.h" of their project instead.
-#if defined(TRACE_EVENT0)
-#error "Another copy of this file has already been included."
-#endif
-
-// This will mark the trace event as disabled by default. The user will need
-// to explicitly enable the event.
-#define TRACE_DISABLED_BY_DEFAULT(name) "disabled-by-default-" name
-
-// Records a pair of begin and end events called "name" for the current
-// scope, with 0, 1 or 2 associated arguments. If the category is not
-// enabled, then this does nothing.
-// - category and name strings must have application lifetime (statics or
-// literals). They may not include " chars.
-#define TRACE_EVENT0(category_group, name) \
- INTERNAL_TRACE_EVENT_ADD_SCOPED(category_group, name)
-#define TRACE_EVENT_WITH_FLOW0(category_group, name, bind_id, flow_flags) \
- INTERNAL_TRACE_EVENT_ADD_SCOPED_WITH_FLOW(category_group, name, bind_id, \
- flow_flags)
-#define TRACE_EVENT1(category_group, name, arg1_name, arg1_val) \
- INTERNAL_TRACE_EVENT_ADD_SCOPED(category_group, name, arg1_name, arg1_val)
-#define TRACE_EVENT_WITH_FLOW1(category_group, name, bind_id, flow_flags, \
- arg1_name, arg1_val) \
- INTERNAL_TRACE_EVENT_ADD_SCOPED_WITH_FLOW(category_group, name, bind_id, \
- flow_flags, arg1_name, arg1_val)
-#define TRACE_EVENT2(category_group, name, arg1_name, arg1_val, arg2_name, \
- arg2_val) \
- INTERNAL_TRACE_EVENT_ADD_SCOPED(category_group, name, arg1_name, arg1_val, \
- arg2_name, arg2_val)
-#define TRACE_EVENT_WITH_FLOW2(category_group, name, bind_id, flow_flags, \
- arg1_name, arg1_val, arg2_name, arg2_val) \
- INTERNAL_TRACE_EVENT_ADD_SCOPED_WITH_FLOW(category_group, name, bind_id, \
- flow_flags, arg1_name, arg1_val, \
- arg2_name, arg2_val)
-
-// Records a single event called "name" immediately, with 0, 1 or 2
-// associated arguments. If the category is not enabled, then this
-// does nothing.
-// - category and name strings must have application lifetime (statics or
-// literals). They may not include " chars.
-#define TRACE_EVENT_INSTANT0(category_group, name, scope) \
- INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_INSTANT, category_group, name, \
- TRACE_EVENT_FLAG_NONE | scope)
-#define TRACE_EVENT_INSTANT1(category_group, name, scope, arg1_name, arg1_val) \
- INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_INSTANT, category_group, name, \
- TRACE_EVENT_FLAG_NONE | scope, arg1_name, arg1_val)
-#define TRACE_EVENT_INSTANT2(category_group, name, scope, arg1_name, arg1_val, \
- arg2_name, arg2_val) \
- INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_INSTANT, category_group, name, \
- TRACE_EVENT_FLAG_NONE | scope, arg1_name, arg1_val, \
- arg2_name, arg2_val)
-#define TRACE_EVENT_COPY_INSTANT0(category_group, name, scope) \
- INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_INSTANT, category_group, name, \
- TRACE_EVENT_FLAG_COPY | scope)
-#define TRACE_EVENT_COPY_INSTANT1(category_group, name, scope, arg1_name, \
- arg1_val) \
- INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_INSTANT, category_group, name, \
- TRACE_EVENT_FLAG_COPY | scope, arg1_name, arg1_val)
-#define TRACE_EVENT_COPY_INSTANT2(category_group, name, scope, arg1_name, \
- arg1_val, arg2_name, arg2_val) \
- INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_INSTANT, category_group, name, \
- TRACE_EVENT_FLAG_COPY | scope, arg1_name, arg1_val, \
- arg2_name, arg2_val)
-
-#define TRACE_EVENT_INSTANT_WITH_TIMESTAMP0(category_group, name, scope, \
- timestamp) \
- INTERNAL_TRACE_EVENT_ADD_WITH_TIMESTAMP( \
- TRACE_EVENT_PHASE_INSTANT, category_group, name, timestamp, \
- TRACE_EVENT_FLAG_NONE | scope)
-
-#define TRACE_EVENT_INSTANT_WITH_TIMESTAMP1(category_group, name, scope, \
- timestamp, arg_name, arg_val) \
- INTERNAL_TRACE_EVENT_ADD_WITH_TIMESTAMP( \
- TRACE_EVENT_PHASE_INSTANT, category_group, name, timestamp, \
- TRACE_EVENT_FLAG_NONE | scope, arg_name, arg_val)
-
-// Records a single BEGIN event called "name" immediately, with 0, 1 or 2
-// associated arguments. If the category is not enabled, then this
-// does nothing.
-// - category and name strings must have application lifetime (statics or
-// literals). They may not include " chars.
-#define TRACE_EVENT_BEGIN0(category_group, name) \
- INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_BEGIN, category_group, name, \
- TRACE_EVENT_FLAG_NONE)
-#define TRACE_EVENT_BEGIN1(category_group, name, arg1_name, arg1_val) \
- INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_BEGIN, category_group, name, \
- TRACE_EVENT_FLAG_NONE, arg1_name, arg1_val)
-#define TRACE_EVENT_BEGIN2(category_group, name, arg1_name, arg1_val, \
- arg2_name, arg2_val) \
- INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_BEGIN, category_group, name, \
- TRACE_EVENT_FLAG_NONE, arg1_name, arg1_val, \
- arg2_name, arg2_val)
-#define TRACE_EVENT_COPY_BEGIN0(category_group, name) \
- INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_BEGIN, category_group, name, \
- TRACE_EVENT_FLAG_COPY)
-#define TRACE_EVENT_COPY_BEGIN1(category_group, name, arg1_name, arg1_val) \
- INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_BEGIN, category_group, name, \
- TRACE_EVENT_FLAG_COPY, arg1_name, arg1_val)
-#define TRACE_EVENT_COPY_BEGIN2(category_group, name, arg1_name, arg1_val, \
- arg2_name, arg2_val) \
- INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_BEGIN, category_group, name, \
- TRACE_EVENT_FLAG_COPY, arg1_name, arg1_val, \
- arg2_name, arg2_val)
-
-// Similar to TRACE_EVENT_BEGINx but with a custom |at| timestamp provided.
-// - |id| is used to match the _BEGIN event with the _END event.
-// Events are considered to match if their category_group, name and id values
-// all match. |id| must either be a pointer or an integer value up to 64 bits.
-// If it's a pointer, the bits will be xored with a hash of the process ID so
-// that the same pointer on two different processes will not collide.
-#define TRACE_EVENT_BEGIN_WITH_ID_TID_AND_TIMESTAMP0(category_group, name, id, \
- thread_id, timestamp) \
- INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP( \
- TRACE_EVENT_PHASE_ASYNC_BEGIN, category_group, name, id, thread_id, \
- timestamp, TRACE_EVENT_FLAG_NONE)
-#define TRACE_EVENT_COPY_BEGIN_WITH_ID_TID_AND_TIMESTAMP0( \
- category_group, name, id, thread_id, timestamp) \
- INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP( \
- TRACE_EVENT_PHASE_ASYNC_BEGIN, category_group, name, id, thread_id, \
- timestamp, TRACE_EVENT_FLAG_COPY)
-#define TRACE_EVENT_COPY_BEGIN_WITH_ID_TID_AND_TIMESTAMP1( \
- category_group, name, id, thread_id, timestamp, arg1_name, arg1_val) \
- INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP( \
- TRACE_EVENT_PHASE_ASYNC_BEGIN, category_group, name, id, thread_id, \
- timestamp, TRACE_EVENT_FLAG_COPY, arg1_name, arg1_val)
-#define TRACE_EVENT_COPY_BEGIN_WITH_ID_TID_AND_TIMESTAMP2( \
- category_group, name, id, thread_id, timestamp, arg1_name, arg1_val, \
- arg2_name, arg2_val) \
- INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP( \
- TRACE_EVENT_PHASE_ASYNC_BEGIN, category_group, name, id, thread_id, \
- timestamp, TRACE_EVENT_FLAG_COPY, arg1_name, arg1_val, arg2_name, \
- arg2_val)
-
-// Records a single END event for "name" immediately. If the category
-// is not enabled, then this does nothing.
-// - category and name strings must have application lifetime (statics or
-// literals). They may not include " chars.
-#define TRACE_EVENT_END0(category_group, name) \
- INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_END, category_group, name, \
- TRACE_EVENT_FLAG_NONE)
-#define TRACE_EVENT_END1(category_group, name, arg1_name, arg1_val) \
- INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_END, category_group, name, \
- TRACE_EVENT_FLAG_NONE, arg1_name, arg1_val)
-#define TRACE_EVENT_END2(category_group, name, arg1_name, arg1_val, arg2_name, \
- arg2_val) \
- INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_END, category_group, name, \
- TRACE_EVENT_FLAG_NONE, arg1_name, arg1_val, \
- arg2_name, arg2_val)
-#define TRACE_EVENT_COPY_END0(category_group, name) \
- INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_END, category_group, name, \
- TRACE_EVENT_FLAG_COPY)
-#define TRACE_EVENT_COPY_END1(category_group, name, arg1_name, arg1_val) \
- INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_END, category_group, name, \
- TRACE_EVENT_FLAG_COPY, arg1_name, arg1_val)
-#define TRACE_EVENT_COPY_END2(category_group, name, arg1_name, arg1_val, \
- arg2_name, arg2_val) \
- INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_END, category_group, name, \
- TRACE_EVENT_FLAG_COPY, arg1_name, arg1_val, \
- arg2_name, arg2_val)
-
-#define TRACE_EVENT_MARK_WITH_TIMESTAMP0(category_group, name, timestamp) \
- INTERNAL_TRACE_EVENT_ADD_WITH_TIMESTAMP( \
- TRACE_EVENT_PHASE_MARK, category_group, name, timestamp, \
- TRACE_EVENT_FLAG_NONE)
-
-#define TRACE_EVENT_MARK_WITH_TIMESTAMP1(category_group, name, timestamp, \
- arg1_name, arg1_val) \
- INTERNAL_TRACE_EVENT_ADD_WITH_TIMESTAMP( \
- TRACE_EVENT_PHASE_MARK, category_group, name, timestamp, \
- TRACE_EVENT_FLAG_NONE, arg1_name, arg1_val)
-
-#define TRACE_EVENT_MARK_WITH_TIMESTAMP2( \
- category_group, name, timestamp, arg1_name, arg1_val, arg2_name, arg2_val) \
- INTERNAL_TRACE_EVENT_ADD_WITH_TIMESTAMP( \
- TRACE_EVENT_PHASE_MARK, category_group, name, timestamp, \
- TRACE_EVENT_FLAG_NONE, arg1_name, arg1_val, arg2_name, arg2_val)
-
-#define TRACE_EVENT_COPY_MARK(category_group, name) \
- INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_MARK, category_group, name, \
- TRACE_EVENT_FLAG_COPY)
-
-#define TRACE_EVENT_COPY_MARK_WITH_TIMESTAMP(category_group, name, timestamp) \
- INTERNAL_TRACE_EVENT_ADD_WITH_TIMESTAMP( \
- TRACE_EVENT_PHASE_MARK, category_group, name, timestamp, \
- TRACE_EVENT_FLAG_COPY)
-
-// Similar to TRACE_EVENT_ENDx but with a custom |at| timestamp provided.
-// - |id| is used to match the _BEGIN event with the _END event.
-// Events are considered to match if their category_group, name and id values
-// all match. |id| must either be a pointer or an integer value up to 64 bits.
-// If it's a pointer, the bits will be xored with a hash of the process ID so
-// that the same pointer on two different processes will not collide.
-#define TRACE_EVENT_END_WITH_ID_TID_AND_TIMESTAMP0(category_group, name, id, \
- thread_id, timestamp) \
- INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP( \
- TRACE_EVENT_PHASE_ASYNC_END, category_group, name, id, thread_id, \
- timestamp, TRACE_EVENT_FLAG_NONE)
-#define TRACE_EVENT_COPY_END_WITH_ID_TID_AND_TIMESTAMP0( \
- category_group, name, id, thread_id, timestamp) \
- INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP( \
- TRACE_EVENT_PHASE_ASYNC_END, category_group, name, id, thread_id, \
- timestamp, TRACE_EVENT_FLAG_COPY)
-#define TRACE_EVENT_COPY_END_WITH_ID_TID_AND_TIMESTAMP1( \
- category_group, name, id, thread_id, timestamp, arg1_name, arg1_val) \
- INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP( \
- TRACE_EVENT_PHASE_ASYNC_END, category_group, name, id, thread_id, \
- timestamp, TRACE_EVENT_FLAG_COPY, arg1_name, arg1_val)
-#define TRACE_EVENT_COPY_END_WITH_ID_TID_AND_TIMESTAMP2( \
- category_group, name, id, thread_id, timestamp, arg1_name, arg1_val, \
- arg2_name, arg2_val) \
- INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP( \
- TRACE_EVENT_PHASE_ASYNC_END, category_group, name, id, thread_id, \
- timestamp, TRACE_EVENT_FLAG_COPY, arg1_name, arg1_val, arg2_name, \
- arg2_val)
-
-// Records the value of a counter called "name" immediately. Value
-// must be representable as a 32 bit integer.
-// - category and name strings must have application lifetime (statics or
-// literals). They may not include " chars.
-#define TRACE_COUNTER1(category_group, name, value) \
- INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_COUNTER, category_group, name, \
- TRACE_EVENT_FLAG_NONE, "value", \
- static_cast<int>(value))
-#define TRACE_COPY_COUNTER1(category_group, name, value) \
- INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_COUNTER, category_group, name, \
- TRACE_EVENT_FLAG_COPY, "value", \
- static_cast<int>(value))
-
-// Records the values of a multi-parted counter called "name" immediately.
-// The UI will treat value1 and value2 as parts of a whole, displaying their
-// values as a stacked-bar chart.
-// - category and name strings must have application lifetime (statics or
-// literals). They may not include " chars.
-#define TRACE_COUNTER2(category_group, name, value1_name, value1_val, \
- value2_name, value2_val) \
- INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_COUNTER, category_group, name, \
- TRACE_EVENT_FLAG_NONE, value1_name, \
- static_cast<int>(value1_val), value2_name, \
- static_cast<int>(value2_val))
-#define TRACE_COPY_COUNTER2(category_group, name, value1_name, value1_val, \
- value2_name, value2_val) \
- INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_COUNTER, category_group, name, \
- TRACE_EVENT_FLAG_COPY, value1_name, \
- static_cast<int>(value1_val), value2_name, \
- static_cast<int>(value2_val))
-
-// Similar to TRACE_COUNTERx, but with a custom |timestamp| provided.
-#define TRACE_COUNTER_WITH_TIMESTAMP1(category_group, name, timestamp, value) \
- INTERNAL_TRACE_EVENT_ADD_WITH_TIMESTAMP( \
- TRACE_EVENT_PHASE_COUNTER, category_group, name, timestamp, \
- TRACE_EVENT_FLAG_NONE, "value", static_cast<int>(value))
-
-#define TRACE_COUNTER_WITH_TIMESTAMP2(category_group, name, timestamp, \
- value1_name, value1_val, value2_name, \
- value2_val) \
- INTERNAL_TRACE_EVENT_ADD_WITH_TIMESTAMP( \
- TRACE_EVENT_PHASE_COUNTER, category_group, name, timestamp, \
- TRACE_EVENT_FLAG_NONE, value1_name, static_cast<int>(value1_val), \
- value2_name, static_cast<int>(value2_val))
-
-// Records the value of a counter called "name" immediately. Value
-// must be representable as a 32 bit integer.
-// - category and name strings must have application lifetime (statics or
-// literals). They may not include " chars.
-// - |id| is used to disambiguate counters with the same name. It must either
-// be a pointer or an integer value up to 64 bits. If it's a pointer, the bits
-// will be xored with a hash of the process ID so that the same pointer on
-// two different processes will not collide.
-#define TRACE_COUNTER_ID1(category_group, name, id, value) \
- INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_COUNTER, category_group, \
- name, id, TRACE_EVENT_FLAG_NONE, "value", \
- static_cast<int>(value))
-#define TRACE_COPY_COUNTER_ID1(category_group, name, id, value) \
- INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_COUNTER, category_group, \
- name, id, TRACE_EVENT_FLAG_COPY, "value", \
- static_cast<int>(value))
-
-// Records the values of a multi-parted counter called "name" immediately.
-// The UI will treat value1 and value2 as parts of a whole, displaying their
-// values as a stacked-bar chart.
-// - category and name strings must have application lifetime (statics or
-// literals). They may not include " chars.
-// - |id| is used to disambiguate counters with the same name. It must either
-// be a pointer or an integer value up to 64 bits. If it's a pointer, the bits
-// will be xored with a hash of the process ID so that the same pointer on
-// two different processes will not collide.
-#define TRACE_COUNTER_ID2(category_group, name, id, value1_name, value1_val, \
- value2_name, value2_val) \
- INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_COUNTER, category_group, \
- name, id, TRACE_EVENT_FLAG_NONE, \
- value1_name, static_cast<int>(value1_val), \
- value2_name, static_cast<int>(value2_val))
-#define TRACE_COPY_COUNTER_ID2(category_group, name, id, value1_name, \
- value1_val, value2_name, value2_val) \
- INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_COUNTER, category_group, \
- name, id, TRACE_EVENT_FLAG_COPY, \
- value1_name, static_cast<int>(value1_val), \
- value2_name, static_cast<int>(value2_val))
-
-// TRACE_EVENT_SAMPLE_* events are injected by the sampling profiler.
-#define TRACE_EVENT_SAMPLE_WITH_TID_AND_TIMESTAMP0(category_group, name, \
- thread_id, timestamp) \
- INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP( \
- TRACE_EVENT_PHASE_SAMPLE, category_group, name, 0, thread_id, timestamp, \
- TRACE_EVENT_FLAG_NONE)
-
-#define TRACE_EVENT_SAMPLE_WITH_TID_AND_TIMESTAMP1( \
- category_group, name, thread_id, timestamp, arg1_name, arg1_val) \
- INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP( \
- TRACE_EVENT_PHASE_SAMPLE, category_group, name, 0, thread_id, timestamp, \
- TRACE_EVENT_FLAG_NONE, arg1_name, arg1_val)
-
-#define TRACE_EVENT_SAMPLE_WITH_TID_AND_TIMESTAMP2(category_group, name, \
- thread_id, timestamp, \
- arg1_name, arg1_val, \
- arg2_name, arg2_val) \
- INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP( \
- TRACE_EVENT_PHASE_SAMPLE, category_group, name, 0, thread_id, timestamp, \
- TRACE_EVENT_FLAG_NONE, arg1_name, arg1_val, arg2_name, arg2_val)
-
-#define TRACE_EVENT_SAMPLE_WITH_ID1(category_group, name, id, arg1_name, \
- arg1_val) \
- INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_SAMPLE, category_group, \
- name, id, TRACE_EVENT_FLAG_NONE, arg1_name, \
- arg1_val)
-
-// ASYNC_STEP_* APIs should be only used by legacy code. New code should
-// consider using NESTABLE_ASYNC_* APIs to describe substeps within an async
-// event.
-// Records a single ASYNC_BEGIN event called "name" immediately, with 0, 1 or 2
-// associated arguments. If the category is not enabled, then this
-// does nothing.
-// - category and name strings must have application lifetime (statics or
-// literals). They may not include " chars.
-// - |id| is used to match the ASYNC_BEGIN event with the ASYNC_END event. ASYNC
-// events are considered to match if their category_group, name and id values
-// all match. |id| must either be a pointer or an integer value up to 64 bits.
-// If it's a pointer, the bits will be xored with a hash of the process ID so
-// that the same pointer on two different processes will not collide.
-//
-// An asynchronous operation can consist of multiple phases. The first phase is
-// defined by the ASYNC_BEGIN calls. Additional phases can be defined using the
-// ASYNC_STEP_INTO or ASYNC_STEP_PAST macros. The ASYNC_STEP_INTO macro will
-// annotate the block following the call. The ASYNC_STEP_PAST macro will
-// annotate the block prior to the call. Note that any particular event must use
-// only STEP_INTO or STEP_PAST macros; they can not mix and match. When the
-// operation completes, call ASYNC_END.
-//
-// An ASYNC trace typically occurs on a single thread (if not, they will only be
-// drawn on the thread defined in the ASYNC_BEGIN event), but all events in that
-// operation must use the same |name| and |id|. Each step can have its own
-// args.
-#define TRACE_EVENT_ASYNC_BEGIN0(category_group, name, id) \
- INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_BEGIN, \
- category_group, name, id, \
- TRACE_EVENT_FLAG_NONE)
-#define TRACE_EVENT_ASYNC_BEGIN1(category_group, name, id, arg1_name, \
- arg1_val) \
- INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_BEGIN, \
- category_group, name, id, \
- TRACE_EVENT_FLAG_NONE, arg1_name, arg1_val)
-#define TRACE_EVENT_ASYNC_BEGIN2(category_group, name, id, arg1_name, \
- arg1_val, arg2_name, arg2_val) \
- INTERNAL_TRACE_EVENT_ADD_WITH_ID( \
- TRACE_EVENT_PHASE_ASYNC_BEGIN, category_group, name, id, \
- TRACE_EVENT_FLAG_NONE, arg1_name, arg1_val, arg2_name, arg2_val)
-#define TRACE_EVENT_COPY_ASYNC_BEGIN0(category_group, name, id) \
- INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_BEGIN, \
- category_group, name, id, \
- TRACE_EVENT_FLAG_COPY)
-#define TRACE_EVENT_COPY_ASYNC_BEGIN1(category_group, name, id, arg1_name, \
- arg1_val) \
- INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_BEGIN, \
- category_group, name, id, \
- TRACE_EVENT_FLAG_COPY, arg1_name, arg1_val)
-#define TRACE_EVENT_COPY_ASYNC_BEGIN2(category_group, name, id, arg1_name, \
- arg1_val, arg2_name, arg2_val) \
- INTERNAL_TRACE_EVENT_ADD_WITH_ID( \
- TRACE_EVENT_PHASE_ASYNC_BEGIN, category_group, name, id, \
- TRACE_EVENT_FLAG_COPY, arg1_name, arg1_val, arg2_name, arg2_val)
-
-// Similar to TRACE_EVENT_ASYNC_BEGINx but with a custom |at| timestamp
-// provided.
-#define TRACE_EVENT_ASYNC_BEGIN_WITH_TIMESTAMP0(category_group, name, id, \
- timestamp) \
- INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP( \
- TRACE_EVENT_PHASE_ASYNC_BEGIN, category_group, name, id, \
- TRACE_EVENT_API_CURRENT_THREAD_ID, timestamp, TRACE_EVENT_FLAG_NONE)
-#define TRACE_EVENT_ASYNC_BEGIN_WITH_TIMESTAMP1( \
- category_group, name, id, timestamp, arg1_name, arg1_val) \
- INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP( \
- TRACE_EVENT_PHASE_ASYNC_BEGIN, category_group, name, id, \
- TRACE_EVENT_API_CURRENT_THREAD_ID, timestamp, TRACE_EVENT_FLAG_NONE, \
- arg1_name, arg1_val)
-#define TRACE_EVENT_ASYNC_BEGIN_WITH_TIMESTAMP2(category_group, name, id, \
- timestamp, arg1_name, \
- arg1_val, arg2_name, arg2_val) \
- INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP( \
- TRACE_EVENT_PHASE_ASYNC_BEGIN, category_group, name, id, \
- TRACE_EVENT_API_CURRENT_THREAD_ID, timestamp, TRACE_EVENT_FLAG_NONE, \
- arg1_name, arg1_val, arg2_name, arg2_val)
-#define TRACE_EVENT_COPY_ASYNC_BEGIN_WITH_TIMESTAMP0(category_group, name, id, \
- timestamp) \
- INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP( \
- TRACE_EVENT_PHASE_ASYNC_BEGIN, category_group, name, id, \
- TRACE_EVENT_API_CURRENT_THREAD_ID, timestamp, TRACE_EVENT_FLAG_COPY)
-
-// Records a single ASYNC_STEP_INTO event for |step| immediately. If the
-// category is not enabled, then this does nothing. The |name| and |id| must
-// match the ASYNC_BEGIN event above. The |step| param identifies this step
-// within the async event. This should be called at the beginning of the next
-// phase of an asynchronous operation. The ASYNC_BEGIN event must not have any
-// ASYNC_STEP_PAST events.
-#define TRACE_EVENT_ASYNC_STEP_INTO0(category_group, name, id, step) \
- INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_STEP_INTO, \
- category_group, name, id, \
- TRACE_EVENT_FLAG_NONE, "step", step)
-#define TRACE_EVENT_ASYNC_STEP_INTO1(category_group, name, id, step, \
- arg1_name, arg1_val) \
- INTERNAL_TRACE_EVENT_ADD_WITH_ID( \
- TRACE_EVENT_PHASE_ASYNC_STEP_INTO, category_group, name, id, \
- TRACE_EVENT_FLAG_NONE, "step", step, arg1_name, arg1_val)
-
-// Similar to TRACE_EVENT_ASYNC_STEP_INTOx but with a custom |at| timestamp
-// provided.
-#define TRACE_EVENT_ASYNC_STEP_INTO_WITH_TIMESTAMP0(category_group, name, id, \
- step, timestamp) \
- INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP( \
- TRACE_EVENT_PHASE_ASYNC_STEP_INTO, category_group, name, id, \
- TRACE_EVENT_API_CURRENT_THREAD_ID, timestamp, TRACE_EVENT_FLAG_NONE, \
- "step", step)
-
-// Records a single ASYNC_STEP_PAST event for |step| immediately. If the
-// category is not enabled, then this does nothing. The |name| and |id| must
-// match the ASYNC_BEGIN event above. The |step| param identifies this step
-// within the async event. This should be called at the beginning of the next
-// phase of an asynchronous operation. The ASYNC_BEGIN event must not have any
-// ASYNC_STEP_INTO events.
-#define TRACE_EVENT_ASYNC_STEP_PAST0(category_group, name, id, step) \
- INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_STEP_PAST, \
- category_group, name, id, \
- TRACE_EVENT_FLAG_NONE, "step", step)
-#define TRACE_EVENT_ASYNC_STEP_PAST1(category_group, name, id, step, \
- arg1_name, arg1_val) \
- INTERNAL_TRACE_EVENT_ADD_WITH_ID( \
- TRACE_EVENT_PHASE_ASYNC_STEP_PAST, category_group, name, id, \
- TRACE_EVENT_FLAG_NONE, "step", step, arg1_name, arg1_val)
-
-// Records a single ASYNC_END event for "name" immediately. If the category
-// is not enabled, then this does nothing.
-#define TRACE_EVENT_ASYNC_END0(category_group, name, id) \
- INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_END, \
- category_group, name, id, \
- TRACE_EVENT_FLAG_NONE)
-#define TRACE_EVENT_ASYNC_END1(category_group, name, id, arg1_name, arg1_val) \
- INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_END, \
- category_group, name, id, \
- TRACE_EVENT_FLAG_NONE, arg1_name, arg1_val)
-#define TRACE_EVENT_ASYNC_END2(category_group, name, id, arg1_name, arg1_val, \
- arg2_name, arg2_val) \
- INTERNAL_TRACE_EVENT_ADD_WITH_ID( \
- TRACE_EVENT_PHASE_ASYNC_END, category_group, name, id, \
- TRACE_EVENT_FLAG_NONE, arg1_name, arg1_val, arg2_name, arg2_val)
-#define TRACE_EVENT_COPY_ASYNC_END0(category_group, name, id) \
- INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_END, \
- category_group, name, id, \
- TRACE_EVENT_FLAG_COPY)
-#define TRACE_EVENT_COPY_ASYNC_END1(category_group, name, id, arg1_name, \
- arg1_val) \
- INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_END, \
- category_group, name, id, \
- TRACE_EVENT_FLAG_COPY, arg1_name, arg1_val)
-#define TRACE_EVENT_COPY_ASYNC_END2(category_group, name, id, arg1_name, \
- arg1_val, arg2_name, arg2_val) \
- INTERNAL_TRACE_EVENT_ADD_WITH_ID( \
- TRACE_EVENT_PHASE_ASYNC_END, category_group, name, id, \
- TRACE_EVENT_FLAG_COPY, arg1_name, arg1_val, arg2_name, arg2_val)
-
-// Similar to TRACE_EVENT_ASYNC_ENDx but with a custom |at| timestamp provided.
-#define TRACE_EVENT_ASYNC_END_WITH_TIMESTAMP0(category_group, name, id, \
- timestamp) \
- INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP( \
- TRACE_EVENT_PHASE_ASYNC_END, category_group, name, id, \
- TRACE_EVENT_API_CURRENT_THREAD_ID, timestamp, TRACE_EVENT_FLAG_NONE)
-#define TRACE_EVENT_ASYNC_END_WITH_TIMESTAMP1(category_group, name, id, \
- timestamp, arg1_name, arg1_val) \
- INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP( \
- TRACE_EVENT_PHASE_ASYNC_END, category_group, name, id, \
- TRACE_EVENT_API_CURRENT_THREAD_ID, timestamp, TRACE_EVENT_FLAG_NONE, \
- arg1_name, arg1_val)
-#define TRACE_EVENT_ASYNC_END_WITH_TIMESTAMP2(category_group, name, id, \
- timestamp, arg1_name, arg1_val, \
- arg2_name, arg2_val) \
- INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP( \
- TRACE_EVENT_PHASE_ASYNC_END, category_group, name, id, \
- TRACE_EVENT_API_CURRENT_THREAD_ID, timestamp, TRACE_EVENT_FLAG_NONE, \
- arg1_name, arg1_val, arg2_name, arg2_val)
-#define TRACE_EVENT_COPY_ASYNC_END_WITH_TIMESTAMP0(category_group, name, id, \
- timestamp) \
- INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP( \
- TRACE_EVENT_PHASE_ASYNC_END, category_group, name, id, \
- TRACE_EVENT_API_CURRENT_THREAD_ID, timestamp, TRACE_EVENT_FLAG_COPY)
-
-// NESTABLE_ASYNC_* APIs are used to describe an async operation, which can
-// be nested within a NESTABLE_ASYNC event and/or have inner NESTABLE_ASYNC
-// events.
-// - category and name strings must have application lifetime (statics or
-// literals). They may not include " chars.
-// - A pair of NESTABLE_ASYNC_BEGIN event and NESTABLE_ASYNC_END event is
-// considered as a match if their category_group, name and id all match.
-// - |id| must either be a pointer or an integer value up to 64 bits.
-// If it's a pointer, the bits will be xored with a hash of the process ID so
-// that the same pointer on two different processes will not collide.
-// - |id| is used to match a child NESTABLE_ASYNC event with its parent
-// NESTABLE_ASYNC event. Therefore, events in the same nested event tree must
-// be logged using the same id and category_group.
-//
-// Unmatched NESTABLE_ASYNC_END event will be parsed as an event that starts
-// at the first NESTABLE_ASYNC event of that id, and unmatched
-// NESTABLE_ASYNC_BEGIN event will be parsed as an event that ends at the last
-// NESTABLE_ASYNC event of that id. Corresponding warning messages for
-// unmatched events will be shown in the analysis view.
-
-// Records a single NESTABLE_ASYNC_BEGIN event called "name" immediately, with
-// 0, 1 or 2 associated arguments. If the category is not enabled, then this
-// does nothing.
-#define TRACE_EVENT_NESTABLE_ASYNC_BEGIN0(category_group, name, id) \
- INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_NESTABLE_ASYNC_BEGIN, \
- category_group, name, id, \
- TRACE_EVENT_FLAG_NONE)
-#define TRACE_EVENT_NESTABLE_ASYNC_BEGIN1(category_group, name, id, arg1_name, \
- arg1_val) \
- INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_NESTABLE_ASYNC_BEGIN, \
- category_group, name, id, \
- TRACE_EVENT_FLAG_NONE, arg1_name, arg1_val)
-#define TRACE_EVENT_NESTABLE_ASYNC_BEGIN2(category_group, name, id, arg1_name, \
- arg1_val, arg2_name, arg2_val) \
- INTERNAL_TRACE_EVENT_ADD_WITH_ID( \
- TRACE_EVENT_PHASE_NESTABLE_ASYNC_BEGIN, category_group, name, id, \
- TRACE_EVENT_FLAG_NONE, arg1_name, arg1_val, arg2_name, arg2_val)
-// Records a single NESTABLE_ASYNC_END event called "name" immediately, with 0
-// or 2 associated arguments. If the category is not enabled, then this does
-// nothing.
-#define TRACE_EVENT_NESTABLE_ASYNC_END0(category_group, name, id) \
- INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_NESTABLE_ASYNC_END, \
- category_group, name, id, \
- TRACE_EVENT_FLAG_NONE)
-// Records a single NESTABLE_ASYNC_END event called "name" immediately, with 1
-// associated argument. If the category is not enabled, then this does nothing.
-#define TRACE_EVENT_NESTABLE_ASYNC_END1(category_group, name, id, arg1_name, \
- arg1_val) \
- INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_NESTABLE_ASYNC_END, \
- category_group, name, id, \
- TRACE_EVENT_FLAG_NONE, arg1_name, arg1_val)
-#define TRACE_EVENT_NESTABLE_ASYNC_END2(category_group, name, id, arg1_name, \
- arg1_val, arg2_name, arg2_val) \
- INTERNAL_TRACE_EVENT_ADD_WITH_ID( \
- TRACE_EVENT_PHASE_NESTABLE_ASYNC_END, category_group, name, id, \
- TRACE_EVENT_FLAG_NONE, arg1_name, arg1_val, arg2_name, arg2_val)
-
-// Records a single NESTABLE_ASYNC_INSTANT event called "name" immediately,
-// with none, one or two associated argument. If the category is not enabled,
-// then this does nothing.
-#define TRACE_EVENT_NESTABLE_ASYNC_INSTANT0(category_group, name, id) \
- INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_NESTABLE_ASYNC_INSTANT, \
- category_group, name, id, \
- TRACE_EVENT_FLAG_NONE)
-
-#define TRACE_EVENT_NESTABLE_ASYNC_INSTANT1(category_group, name, id, \
- arg1_name, arg1_val) \
- INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_NESTABLE_ASYNC_INSTANT, \
- category_group, name, id, \
- TRACE_EVENT_FLAG_NONE, arg1_name, arg1_val)
-
-#define TRACE_EVENT_NESTABLE_ASYNC_INSTANT2( \
- category_group, name, id, arg1_name, arg1_val, arg2_name, arg2_val) \
- INTERNAL_TRACE_EVENT_ADD_WITH_ID( \
- TRACE_EVENT_PHASE_NESTABLE_ASYNC_INSTANT, category_group, name, id, \
- TRACE_EVENT_FLAG_NONE, arg1_name, arg1_val, arg2_name, arg2_val)
-
-#define TRACE_EVENT_COPY_NESTABLE_ASYNC_BEGIN_WITH_TTS2( \
- category_group, name, id, arg1_name, arg1_val, arg2_name, arg2_val) \
- INTERNAL_TRACE_EVENT_ADD_WITH_ID( \
- TRACE_EVENT_PHASE_NESTABLE_ASYNC_BEGIN, category_group, name, id, \
- TRACE_EVENT_FLAG_ASYNC_TTS | TRACE_EVENT_FLAG_COPY, arg1_name, arg1_val, \
- arg2_name, arg2_val)
-#define TRACE_EVENT_COPY_NESTABLE_ASYNC_END_WITH_TTS2( \
- category_group, name, id, arg1_name, arg1_val, arg2_name, arg2_val) \
- INTERNAL_TRACE_EVENT_ADD_WITH_ID( \
- TRACE_EVENT_PHASE_NESTABLE_ASYNC_END, category_group, name, id, \
- TRACE_EVENT_FLAG_ASYNC_TTS | TRACE_EVENT_FLAG_COPY, arg1_name, arg1_val, \
- arg2_name, arg2_val)
-
-// Similar to TRACE_EVENT_NESTABLE_ASYNC_{BEGIN,END}x but with a custom
-// |timestamp| provided.
-#define TRACE_EVENT_NESTABLE_ASYNC_BEGIN_WITH_TIMESTAMP0(category_group, name, \
- id, timestamp) \
- INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP( \
- TRACE_EVENT_PHASE_NESTABLE_ASYNC_BEGIN, category_group, name, id, \
- TRACE_EVENT_API_CURRENT_THREAD_ID, timestamp, TRACE_EVENT_FLAG_NONE)
-#define TRACE_EVENT_NESTABLE_ASYNC_END_WITH_TIMESTAMP0(category_group, name, \
- id, timestamp) \
- INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP( \
- TRACE_EVENT_PHASE_NESTABLE_ASYNC_END, category_group, name, id, \
- TRACE_EVENT_API_CURRENT_THREAD_ID, timestamp, TRACE_EVENT_FLAG_NONE)
-#define TRACE_EVENT_NESTABLE_ASYNC_END_WITH_TIMESTAMP1( \
- category_group, name, id, timestamp, arg1_name, arg1_val) \
- INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP( \
- TRACE_EVENT_PHASE_NESTABLE_ASYNC_END, category_group, name, id, \
- TRACE_EVENT_API_CURRENT_THREAD_ID, timestamp, TRACE_EVENT_FLAG_NONE, \
- arg1_name, arg1_val)
-#define TRACE_EVENT_NESTABLE_ASYNC_INSTANT_WITH_TIMESTAMP0( \
- category_group, name, id, timestamp) \
- INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP( \
- TRACE_EVENT_PHASE_NESTABLE_ASYNC_INSTANT, category_group, name, id, \
- TRACE_EVENT_API_CURRENT_THREAD_ID, timestamp, TRACE_EVENT_FLAG_NONE)
-#define TRACE_EVENT_COPY_NESTABLE_ASYNC_BEGIN_WITH_TIMESTAMP0( \
- category_group, name, id, timestamp) \
- INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP( \
- TRACE_EVENT_PHASE_NESTABLE_ASYNC_BEGIN, category_group, name, id, \
- TRACE_EVENT_API_CURRENT_THREAD_ID, timestamp, TRACE_EVENT_FLAG_COPY)
-#define TRACE_EVENT_COPY_NESTABLE_ASYNC_END_WITH_TIMESTAMP0( \
- category_group, name, id, timestamp) \
- INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP( \
- TRACE_EVENT_PHASE_NESTABLE_ASYNC_END, category_group, name, id, \
- TRACE_EVENT_API_CURRENT_THREAD_ID, timestamp, TRACE_EVENT_FLAG_COPY)
-
-// Records a single FLOW_BEGIN event called "name" immediately, with 0, 1 or 2
-// associated arguments. If the category is not enabled, then this
-// does nothing.
-// - category and name strings must have application lifetime (statics or
-// literals). They may not include " chars.
-// - |id| is used to match the FLOW_BEGIN event with the FLOW_END event. FLOW
-// events are considered to match if their category_group, name and id values
-// all match. |id| must either be a pointer or an integer value up to 64 bits.
-// If it's a pointer, the bits will be xored with a hash of the process ID so
-// that the same pointer on two different processes will not collide.
-// FLOW events are different from ASYNC events in how they are drawn by the
-// tracing UI. A FLOW defines asynchronous data flow, such as posting a task
-// (FLOW_BEGIN) and later executing that task (FLOW_END). Expect FLOWs to be
-// drawn as lines or arrows from FLOW_BEGIN scopes to FLOW_END scopes. Similar
-// to ASYNC, a FLOW can consist of multiple phases. The first phase is defined
-// by the FLOW_BEGIN calls. Additional phases can be defined using the FLOW_STEP
-// macros. When the operation completes, call FLOW_END. An async operation can
-// span threads and processes, but all events in that operation must use the
-// same |name| and |id|. Each event can have its own args.
-#define TRACE_EVENT_FLOW_BEGIN0(category_group, name, id) \
- INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_FLOW_BEGIN, \
- category_group, name, id, \
- TRACE_EVENT_FLAG_NONE)
-#define TRACE_EVENT_FLOW_BEGIN1(category_group, name, id, arg1_name, arg1_val) \
- INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_FLOW_BEGIN, \
- category_group, name, id, \
- TRACE_EVENT_FLAG_NONE, arg1_name, arg1_val)
-#define TRACE_EVENT_FLOW_BEGIN2(category_group, name, id, arg1_name, arg1_val, \
- arg2_name, arg2_val) \
- INTERNAL_TRACE_EVENT_ADD_WITH_ID( \
- TRACE_EVENT_PHASE_FLOW_BEGIN, category_group, name, id, \
- TRACE_EVENT_FLAG_NONE, arg1_name, arg1_val, arg2_name, arg2_val)
-#define TRACE_EVENT_COPY_FLOW_BEGIN0(category_group, name, id) \
- INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_FLOW_BEGIN, \
- category_group, name, id, \
- TRACE_EVENT_FLAG_COPY)
-#define TRACE_EVENT_COPY_FLOW_BEGIN1(category_group, name, id, arg1_name, \
- arg1_val) \
- INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_FLOW_BEGIN, \
- category_group, name, id, \
- TRACE_EVENT_FLAG_COPY, arg1_name, arg1_val)
-#define TRACE_EVENT_COPY_FLOW_BEGIN2(category_group, name, id, arg1_name, \
- arg1_val, arg2_name, arg2_val) \
- INTERNAL_TRACE_EVENT_ADD_WITH_ID( \
- TRACE_EVENT_PHASE_FLOW_BEGIN, category_group, name, id, \
- TRACE_EVENT_FLAG_COPY, arg1_name, arg1_val, arg2_name, arg2_val)
-
-// Records a single FLOW_STEP event for |step| immediately. If the category
-// is not enabled, then this does nothing. The |name| and |id| must match the
-// FLOW_BEGIN event above. The |step| param identifies this step within the
-// async event. This should be called at the beginning of the next phase of an
-// asynchronous operation.
-#define TRACE_EVENT_FLOW_STEP0(category_group, name, id, step) \
- INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_FLOW_STEP, \
- category_group, name, id, \
- TRACE_EVENT_FLAG_NONE, "step", step)
-#define TRACE_EVENT_FLOW_STEP1(category_group, name, id, step, arg1_name, \
- arg1_val) \
- INTERNAL_TRACE_EVENT_ADD_WITH_ID( \
- TRACE_EVENT_PHASE_FLOW_STEP, category_group, name, id, \
- TRACE_EVENT_FLAG_NONE, "step", step, arg1_name, arg1_val)
-#define TRACE_EVENT_COPY_FLOW_STEP0(category_group, name, id, step) \
- INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_FLOW_STEP, \
- category_group, name, id, \
- TRACE_EVENT_FLAG_COPY, "step", step)
-#define TRACE_EVENT_COPY_FLOW_STEP1(category_group, name, id, step, arg1_name, \
- arg1_val) \
- INTERNAL_TRACE_EVENT_ADD_WITH_ID( \
- TRACE_EVENT_PHASE_FLOW_STEP, category_group, name, id, \
- TRACE_EVENT_FLAG_COPY, "step", step, arg1_name, arg1_val)
-
-// Records a single FLOW_END event for "name" immediately. If the category
-// is not enabled, then this does nothing.
-#define TRACE_EVENT_FLOW_END0(category_group, name, id) \
- INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_FLOW_END, category_group, \
- name, id, TRACE_EVENT_FLAG_NONE)
-#define TRACE_EVENT_FLOW_END_BIND_TO_ENCLOSING0(category_group, name, id) \
- INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_FLOW_END, category_group, \
- name, id, \
- TRACE_EVENT_FLAG_BIND_TO_ENCLOSING)
-#define TRACE_EVENT_FLOW_END1(category_group, name, id, arg1_name, arg1_val) \
- INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_FLOW_END, category_group, \
- name, id, TRACE_EVENT_FLAG_NONE, arg1_name, \
- arg1_val)
-#define TRACE_EVENT_FLOW_END2(category_group, name, id, arg1_name, arg1_val, \
- arg2_name, arg2_val) \
- INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_FLOW_END, category_group, \
- name, id, TRACE_EVENT_FLAG_NONE, arg1_name, \
- arg1_val, arg2_name, arg2_val)
-#define TRACE_EVENT_COPY_FLOW_END0(category_group, name, id) \
- INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_FLOW_END, category_group, \
- name, id, TRACE_EVENT_FLAG_COPY)
-#define TRACE_EVENT_COPY_FLOW_END1(category_group, name, id, arg1_name, \
- arg1_val) \
- INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_FLOW_END, category_group, \
- name, id, TRACE_EVENT_FLAG_COPY, arg1_name, \
- arg1_val)
-#define TRACE_EVENT_COPY_FLOW_END2(category_group, name, id, arg1_name, \
- arg1_val, arg2_name, arg2_val) \
- INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_FLOW_END, category_group, \
- name, id, TRACE_EVENT_FLAG_COPY, arg1_name, \
- arg1_val, arg2_name, arg2_val)
-
-// Special trace event macro to trace task execution with the location where it
-// was posted from.
-#define TRACE_TASK_EXECUTION(run_function, task) \
- INTERNAL_TRACE_TASK_EXECUTION(run_function, task)
-
-// TRACE_EVENT_METADATA* events are information related to other
-// injected events, not events in their own right.
-#define TRACE_EVENT_METADATA1(category_group, name, arg1_name, arg1_val) \
- INTERNAL_TRACE_EVENT_METADATA_ADD(category_group, name, arg1_name, arg1_val)
-
-// Records a clock sync event.
-#define TRACE_EVENT_CLOCK_SYNC_RECEIVER(sync_id) \
- INTERNAL_TRACE_EVENT_ADD( \
- TRACE_EVENT_PHASE_CLOCK_SYNC, "__metadata", "clock_sync", \
- TRACE_EVENT_FLAG_NONE, "sync_id", sync_id)
-#define TRACE_EVENT_CLOCK_SYNC_ISSUER(sync_id, issue_ts, issue_end_ts) \
- INTERNAL_TRACE_EVENT_ADD_WITH_TIMESTAMP( \
- TRACE_EVENT_PHASE_CLOCK_SYNC, "__metadata", "clock_sync", \
- issue_end_ts, TRACE_EVENT_FLAG_NONE, \
- "sync_id", sync_id, "issue_ts", issue_ts)
-
-// Macros to track the life time and value of arbitrary client objects.
-// See also TraceTrackableObject.
-#define TRACE_EVENT_OBJECT_CREATED_WITH_ID(category_group, name, id) \
- INTERNAL_TRACE_EVENT_ADD_WITH_ID( \
- TRACE_EVENT_PHASE_CREATE_OBJECT, category_group, name, id, \
- TRACE_EVENT_FLAG_NONE)
-
-#define TRACE_EVENT_OBJECT_SNAPSHOT_WITH_ID(category_group, name, id, \
- snapshot) \
- INTERNAL_TRACE_EVENT_ADD_WITH_ID( \
- TRACE_EVENT_PHASE_SNAPSHOT_OBJECT, category_group, name, \
- id, TRACE_EVENT_FLAG_NONE, "snapshot", snapshot)
-
-#define TRACE_EVENT_OBJECT_SNAPSHOT_WITH_ID_AND_TIMESTAMP( \
- category_group, name, id, timestamp, snapshot) \
- INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP( \
- TRACE_EVENT_PHASE_SNAPSHOT_OBJECT, category_group, name, \
- id, TRACE_EVENT_API_CURRENT_THREAD_ID, timestamp, TRACE_EVENT_FLAG_NONE, \
- "snapshot", snapshot)
-
-#define TRACE_EVENT_OBJECT_DELETED_WITH_ID(category_group, name, id) \
- INTERNAL_TRACE_EVENT_ADD_WITH_ID( \
- TRACE_EVENT_PHASE_DELETE_OBJECT, category_group, name, id, \
- TRACE_EVENT_FLAG_NONE)
-
-// Records entering and leaving trace event contexts. |category_group| and
-// |name| specify the context category and type. |context| is a
-// snapshotted context object id.
-#define TRACE_EVENT_ENTER_CONTEXT(category_group, name, context) \
- INTERNAL_TRACE_EVENT_ADD_WITH_ID( \
- TRACE_EVENT_PHASE_ENTER_CONTEXT, category_group, name, context, \
- TRACE_EVENT_FLAG_NONE)
-#define TRACE_EVENT_LEAVE_CONTEXT(category_group, name, context) \
- INTERNAL_TRACE_EVENT_ADD_WITH_ID( \
- TRACE_EVENT_PHASE_LEAVE_CONTEXT, category_group, name, context, \
- TRACE_EVENT_FLAG_NONE)
-#define TRACE_EVENT_SCOPED_CONTEXT(category_group, name, context) \
- INTERNAL_TRACE_EVENT_SCOPED_CONTEXT(category_group, name, context)
-
-// Macro to specify that two trace IDs are identical. For example,
-// TRACE_LINK_IDS(
-// "category", "name",
-// TRACE_ID_WITH_SCOPE("net::URLRequest", 0x1000),
-// TRACE_ID_WITH_SCOPE("blink::ResourceFetcher::FetchRequest", 0x2000))
-// tells the trace consumer that events with ID ("net::URLRequest", 0x1000) from
-// the current process have the same ID as events with ID
-// ("blink::ResourceFetcher::FetchRequest", 0x2000).
-#define TRACE_LINK_IDS(category_group, name, id, linked_id) \
- INTERNAL_TRACE_EVENT_ADD_LINK_IDS(category_group, name, id, linked_id);
-
-// Macro to efficiently determine if a given category group is enabled.
-#define TRACE_EVENT_CATEGORY_GROUP_ENABLED(category_group, ret) \
- do { \
- INTERNAL_TRACE_EVENT_GET_CATEGORY_INFO(category_group); \
- if (INTERNAL_TRACE_EVENT_CATEGORY_GROUP_ENABLED_FOR_RECORDING_MODE()) { \
- *ret = true; \
- } else { \
- *ret = false; \
- } \
- } while (0)
-
-// Macro to explicitly warm up a given category group. This could be useful in
-// cases where we want to initialize a category group before any trace events
-// for that category group is reported. For example, to have a category group
-// always show up in the "record categories" list for manually selecting
-// settings in about://tracing.
-#define TRACE_EVENT_WARMUP_CATEGORY(category_group) \
- INTERNAL_TRACE_EVENT_GET_CATEGORY_INFO(category_group)
-
-// Macro to efficiently determine, through polling, if a new trace has begun.
-#define TRACE_EVENT_IS_NEW_TRACE(ret) \
- do { \
- static int INTERNAL_TRACE_EVENT_UID(lastRecordingNumber) = 0; \
- int num_traces_recorded = TRACE_EVENT_API_GET_NUM_TRACES_RECORDED(); \
- if (num_traces_recorded != -1 && \
- num_traces_recorded != \
- INTERNAL_TRACE_EVENT_UID(lastRecordingNumber)) { \
- INTERNAL_TRACE_EVENT_UID(lastRecordingNumber) = num_traces_recorded; \
- *ret = true; \
- } else { \
- *ret = false; \
- } \
- } while (0)
-
-// Macro for getting the real base::TimeTicks::Now() which can be overridden in
-// headless when VirtualTime is enabled.
-#define TRACE_TIME_TICKS_NOW() INTERNAL_TRACE_TIME_TICKS_NOW()
-
-// Macro for getting the real base::Time::Now() which can be overridden in
-// headless when VirtualTime is enabled.
-#define TRACE_TIME_NOW() INTERNAL_TRACE_TIME_NOW()
-
-// Notes regarding the following definitions:
-// New values can be added and propagated to third party libraries, but existing
-// definitions must never be changed, because third party libraries may use old
-// definitions.
-
-// Phase indicates the nature of an event entry. E.g. part of a begin/end pair.
-#define TRACE_EVENT_PHASE_BEGIN ('B')
-#define TRACE_EVENT_PHASE_END ('E')
-#define TRACE_EVENT_PHASE_COMPLETE ('X')
-#define TRACE_EVENT_PHASE_INSTANT ('I')
-#define TRACE_EVENT_PHASE_ASYNC_BEGIN ('S')
-#define TRACE_EVENT_PHASE_ASYNC_STEP_INTO ('T')
-#define TRACE_EVENT_PHASE_ASYNC_STEP_PAST ('p')
-#define TRACE_EVENT_PHASE_ASYNC_END ('F')
-#define TRACE_EVENT_PHASE_NESTABLE_ASYNC_BEGIN ('b')
-#define TRACE_EVENT_PHASE_NESTABLE_ASYNC_END ('e')
-#define TRACE_EVENT_PHASE_NESTABLE_ASYNC_INSTANT ('n')
-#define TRACE_EVENT_PHASE_FLOW_BEGIN ('s')
-#define TRACE_EVENT_PHASE_FLOW_STEP ('t')
-#define TRACE_EVENT_PHASE_FLOW_END ('f')
-#define TRACE_EVENT_PHASE_METADATA ('M')
-#define TRACE_EVENT_PHASE_COUNTER ('C')
-#define TRACE_EVENT_PHASE_SAMPLE ('P')
-#define TRACE_EVENT_PHASE_CREATE_OBJECT ('N')
-#define TRACE_EVENT_PHASE_SNAPSHOT_OBJECT ('O')
-#define TRACE_EVENT_PHASE_DELETE_OBJECT ('D')
-#define TRACE_EVENT_PHASE_MEMORY_DUMP ('v')
-#define TRACE_EVENT_PHASE_MARK ('R')
-#define TRACE_EVENT_PHASE_CLOCK_SYNC ('c')
-#define TRACE_EVENT_PHASE_ENTER_CONTEXT ('(')
-#define TRACE_EVENT_PHASE_LEAVE_CONTEXT (')')
-#define TRACE_EVENT_PHASE_LINK_IDS ('=')
-
-// Flags for changing the behavior of TRACE_EVENT_API_ADD_TRACE_EVENT.
-#define TRACE_EVENT_FLAG_NONE (static_cast<unsigned int>(0))
-#define TRACE_EVENT_FLAG_COPY (static_cast<unsigned int>(1 << 0))
-#define TRACE_EVENT_FLAG_HAS_ID (static_cast<unsigned int>(1 << 1))
-// TODO(crbug.com/639003): Free this bit after ID mangling is deprecated.
-#define TRACE_EVENT_FLAG_MANGLE_ID (static_cast<unsigned int>(1 << 2))
-#define TRACE_EVENT_FLAG_SCOPE_OFFSET (static_cast<unsigned int>(1 << 3))
-#define TRACE_EVENT_FLAG_SCOPE_EXTRA (static_cast<unsigned int>(1 << 4))
-#define TRACE_EVENT_FLAG_EXPLICIT_TIMESTAMP (static_cast<unsigned int>(1 << 5))
-#define TRACE_EVENT_FLAG_ASYNC_TTS (static_cast<unsigned int>(1 << 6))
-#define TRACE_EVENT_FLAG_BIND_TO_ENCLOSING (static_cast<unsigned int>(1 << 7))
-#define TRACE_EVENT_FLAG_FLOW_IN (static_cast<unsigned int>(1 << 8))
-#define TRACE_EVENT_FLAG_FLOW_OUT (static_cast<unsigned int>(1 << 9))
-#define TRACE_EVENT_FLAG_HAS_CONTEXT_ID (static_cast<unsigned int>(1 << 10))
-#define TRACE_EVENT_FLAG_HAS_PROCESS_ID (static_cast<unsigned int>(1 << 11))
-#define TRACE_EVENT_FLAG_HAS_LOCAL_ID (static_cast<unsigned int>(1 << 12))
-#define TRACE_EVENT_FLAG_HAS_GLOBAL_ID (static_cast<unsigned int>(1 << 13))
-
-#define TRACE_EVENT_FLAG_SCOPE_MASK \
- (static_cast<unsigned int>(TRACE_EVENT_FLAG_SCOPE_OFFSET | \
- TRACE_EVENT_FLAG_SCOPE_EXTRA))
-
-// Type values for identifying types in the TraceValue union.
-#define TRACE_VALUE_TYPE_BOOL (static_cast<unsigned char>(1))
-#define TRACE_VALUE_TYPE_UINT (static_cast<unsigned char>(2))
-#define TRACE_VALUE_TYPE_INT (static_cast<unsigned char>(3))
-#define TRACE_VALUE_TYPE_DOUBLE (static_cast<unsigned char>(4))
-#define TRACE_VALUE_TYPE_POINTER (static_cast<unsigned char>(5))
-#define TRACE_VALUE_TYPE_STRING (static_cast<unsigned char>(6))
-#define TRACE_VALUE_TYPE_COPY_STRING (static_cast<unsigned char>(7))
-#define TRACE_VALUE_TYPE_CONVERTABLE (static_cast<unsigned char>(8))
-
-// Enum reflecting the scope of an INSTANT event. Must fit within
-// TRACE_EVENT_FLAG_SCOPE_MASK.
-#define TRACE_EVENT_SCOPE_GLOBAL (static_cast<unsigned char>(0 << 3))
-#define TRACE_EVENT_SCOPE_PROCESS (static_cast<unsigned char>(1 << 3))
-#define TRACE_EVENT_SCOPE_THREAD (static_cast<unsigned char>(2 << 3))
-
-#define TRACE_EVENT_SCOPE_NAME_GLOBAL ('g')
-#define TRACE_EVENT_SCOPE_NAME_PROCESS ('p')
-#define TRACE_EVENT_SCOPE_NAME_THREAD ('t')
-
-#endif // BASE_TRACE_EVENT_COMMON_TRACE_EVENT_COMMON_H_
diff --git a/base/trace_event/etw_manifest/chrome_events_win.man b/base/trace_event/etw_manifest/chrome_events_win.man
deleted file mode 100644
index 10a8ddf..0000000
--- a/base/trace_event/etw_manifest/chrome_events_win.man
+++ /dev/null
@@ -1,84 +0,0 @@
-<?xml version='1.0' encoding='utf-8' standalone='yes'?>
-<instrumentationManifest
- xmlns="http://schemas.microsoft.com/win/2004/08/events"
- xmlns:win="http://manifests.microsoft.com/win/2004/08/windows/events"
- xmlns:xs="http://www.w3.org/2001/XMLSchema"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://schemas.microsoft.com/win/2004/08/events eventman.xsd"
- >
- <instrumentation>
- <events>
- <provider
- guid="{D2D578D9-2936-45B6-A09f-30E32715F42D}"
- messageFileName="chrome.dll"
- name="Chrome"
- resourceFileName="chrome.dll"
- symbol="CHROME"
- >
- <channels>
- <importChannel
- chid="SYSTEM"
- name="System"
- />
- </channels>
- <templates>
- <template tid="tid_chrome_event">
- <data
- inType="win:AnsiString"
- name="Name"
- />
- <data
- inType="win:AnsiString"
- name="Phase"
- />
- <data
- inType="win:AnsiString"
- name="Arg Name 1"
- />
- <data
- inType="win:AnsiString"
- name="Arg Value 1"
- />
- <data
- inType="win:AnsiString"
- name="Arg Name 2"
- />
- <data
- inType="win:AnsiString"
- name="Arg Value 2"
- />
- <data
- inType="win:AnsiString"
- name="Arg Name 3"
- />
- <data
- inType="win:AnsiString"
- name="Arg Value 3"
- />
- </template>
- </templates>
- <events>
- <event
- channel="SYSTEM"
- level="win:Informational"
- message="$(string.ChromeEvent.EventMessage)"
- opcode="win:Info"
- symbol="ChromeEvent"
- template="tid_chrome_event"
- value="1"
- />
- </events>
- </provider>
- </events>
- </instrumentation>
- <localization xmlns="http://schemas.microsoft.com/win/2004/08/events">
- <resources culture="en-US">
- <stringTable>
- <string
- id="ChromeEvent.EventMessage"
- value="Chrome Event: %1 (%2)"
- />
- </stringTable>
- </resources>
- </localization>
-</instrumentationManifest>
diff --git a/base/trace_event/event_name_filter.cc b/base/trace_event/event_name_filter.cc
deleted file mode 100644
index 7bf932e..0000000
--- a/base/trace_event/event_name_filter.cc
+++ /dev/null
@@ -1,26 +0,0 @@
-// Copyright 2016 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/event_name_filter.h"
-
-#include "base/trace_event/trace_event_impl.h"
-
-namespace base {
-namespace trace_event {
-
-// static
-const char EventNameFilter::kName[] = "event_whitelist_predicate";
-
-EventNameFilter::EventNameFilter(
- std::unique_ptr<EventNamesWhitelist> event_names_whitelist)
- : event_names_whitelist_(std::move(event_names_whitelist)) {}
-
-EventNameFilter::~EventNameFilter() = default;
-
-bool EventNameFilter::FilterTraceEvent(const TraceEvent& trace_event) const {
- return event_names_whitelist_->count(trace_event.name()) != 0;
-}
-
-} // namespace trace_event
-} // namespace base
diff --git a/base/trace_event/event_name_filter.h b/base/trace_event/event_name_filter.h
deleted file mode 100644
index 19333b3..0000000
--- a/base/trace_event/event_name_filter.h
+++ /dev/null
@@ -1,46 +0,0 @@
-// Copyright 2016 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_EVENT_NAME_FILTER_H_
-#define BASE_TRACE_EVENT_EVENT_NAME_FILTER_H_
-
-#include <memory>
-#include <string>
-#include <unordered_set>
-
-#include "base/base_export.h"
-#include "base/macros.h"
-#include "base/trace_event/trace_event_filter.h"
-
-namespace base {
-namespace trace_event {
-
-class TraceEvent;
-
-// Filters trace events by checking the full name against a whitelist.
-// The current implementation is quite simple and dumb and just uses a
-// hashtable which requires char* to std::string conversion. It could be smarter
-// and use a bloom filter trie. However, today this is used too rarely to
-// justify that cost.
-class BASE_EXPORT EventNameFilter : public TraceEventFilter {
- public:
- using EventNamesWhitelist = std::unordered_set<std::string>;
- static const char kName[];
-
- EventNameFilter(std::unique_ptr<EventNamesWhitelist>);
- ~EventNameFilter() override;
-
- // TraceEventFilter implementation.
- bool FilterTraceEvent(const TraceEvent&) const override;
-
- private:
- std::unique_ptr<const EventNamesWhitelist> event_names_whitelist_;
-
- DISALLOW_COPY_AND_ASSIGN(EventNameFilter);
-};
-
-} // namespace trace_event
-} // namespace base
-
-#endif // BASE_TRACE_EVENT_EVENT_NAME_FILTER_H_
diff --git a/base/trace_event/heap_profiler.h b/base/trace_event/heap_profiler.h
deleted file mode 100644
index c8deaf6..0000000
--- a/base/trace_event/heap_profiler.h
+++ /dev/null
@@ -1,119 +0,0 @@
-// Copyright 2016 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_HEAP_PROFILER_H
-#define BASE_TRACE_EVENT_HEAP_PROFILER_H
-
-#include "base/compiler_specific.h"
-#include "base/trace_event/heap_profiler_allocation_context_tracker.h"
-
-// This header file defines the set of macros that are used to track memory
-// usage in the heap profiler. This is in addition to the macros defined in
-// trace_event.h and are specific to heap profiler. This file also defines
-// implementation details of these macros.
-
-// Implementation detail: heap profiler macros create temporary variables to
-// keep instrumentation overhead low. These macros give each temporary variable
-// a unique name based on the line number to prevent name collisions.
-#define INTERNAL_HEAP_PROFILER_UID3(a, b) heap_profiler_unique_##a##b
-#define INTERNAL_HEAP_PROFILER_UID2(a, b) INTERNAL_HEAP_PROFILER_UID3(a, b)
-#define INTERNAL_HEAP_PROFILER_UID(name_prefix) \
- INTERNAL_HEAP_PROFILER_UID2(name_prefix, __LINE__)
-
-// Scoped tracker for task execution context in the heap profiler.
-#define TRACE_HEAP_PROFILER_API_SCOPED_TASK_EXECUTION \
- trace_event_internal::HeapProfilerScopedTaskExecutionTracker
-
-// Scoped tracker that tracks the given program counter as a native stack frame
-// in the heap profiler.
-#define TRACE_HEAP_PROFILER_API_SCOPED_WITH_PROGRAM_COUNTER \
- trace_event_internal::HeapProfilerScopedStackFrame
-
-// A scoped ignore event used to tell heap profiler to ignore all the
-// allocations in the scope. It is useful to exclude allocations made for
-// tracing from the heap profiler dumps.
-#define HEAP_PROFILER_SCOPED_IGNORE \
- trace_event_internal::HeapProfilerScopedIgnore INTERNAL_HEAP_PROFILER_UID( \
- scoped_ignore)
-
-namespace trace_event_internal {
-
-// HeapProfilerScopedTaskExecutionTracker records the current task's context in
-// the heap profiler.
-class HeapProfilerScopedTaskExecutionTracker {
- public:
- inline explicit HeapProfilerScopedTaskExecutionTracker(
- const char* task_context)
- : context_(task_context) {
- using base::trace_event::AllocationContextTracker;
- if (UNLIKELY(AllocationContextTracker::capture_mode() !=
- AllocationContextTracker::CaptureMode::DISABLED)) {
- AllocationContextTracker::GetInstanceForCurrentThread()
- ->PushCurrentTaskContext(context_);
- }
- }
-
- inline ~HeapProfilerScopedTaskExecutionTracker() {
- using base::trace_event::AllocationContextTracker;
- if (UNLIKELY(AllocationContextTracker::capture_mode() !=
- AllocationContextTracker::CaptureMode::DISABLED)) {
- AllocationContextTracker::GetInstanceForCurrentThread()
- ->PopCurrentTaskContext(context_);
- }
- }
-
- private:
- const char* context_;
-};
-
-class HeapProfilerScopedStackFrame {
- public:
- inline explicit HeapProfilerScopedStackFrame(const void* program_counter)
- : program_counter_(program_counter) {
- using base::trace_event::AllocationContextTracker;
- if (UNLIKELY(AllocationContextTracker::capture_mode() ==
- AllocationContextTracker::CaptureMode::MIXED_STACK)) {
- AllocationContextTracker::GetInstanceForCurrentThread()
- ->PushNativeStackFrame(program_counter_);
- }
- }
-
- inline ~HeapProfilerScopedStackFrame() {
- using base::trace_event::AllocationContextTracker;
- if (UNLIKELY(AllocationContextTracker::capture_mode() ==
- AllocationContextTracker::CaptureMode::MIXED_STACK)) {
- AllocationContextTracker::GetInstanceForCurrentThread()
- ->PopNativeStackFrame(program_counter_);
- }
- }
-
- private:
- const void* const program_counter_;
-};
-
-class BASE_EXPORT HeapProfilerScopedIgnore {
- public:
- inline HeapProfilerScopedIgnore() {
- using base::trace_event::AllocationContextTracker;
- if (UNLIKELY(
- AllocationContextTracker::capture_mode() !=
- AllocationContextTracker::CaptureMode::DISABLED)) {
- AllocationContextTracker::GetInstanceForCurrentThread()
- ->begin_ignore_scope();
- }
- }
- inline ~HeapProfilerScopedIgnore() {
- using base::trace_event::AllocationContextTracker;
- if (UNLIKELY(
- AllocationContextTracker::capture_mode() !=
- AllocationContextTracker::CaptureMode::DISABLED)) {
- AllocationContextTracker::GetInstanceForCurrentThread()
- ->end_ignore_scope();
- }
- }
-};
-
-} // namespace trace_event_internal
-
-#endif // BASE_TRACE_EVENT_HEAP_PROFILER_H
diff --git a/base/trace_event/heap_profiler_allocation_context.cc b/base/trace_event/heap_profiler_allocation_context.cc
deleted file mode 100644
index bdc3c58..0000000
--- a/base/trace_event/heap_profiler_allocation_context.cc
+++ /dev/null
@@ -1,88 +0,0 @@
-// Copyright 2015 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/heap_profiler_allocation_context.h"
-
-#include <cstring>
-
-#include "base/hash.h"
-#include "base/macros.h"
-
-namespace base {
-namespace trace_event {
-
-bool operator < (const StackFrame& lhs, const StackFrame& rhs) {
- return lhs.value < rhs.value;
-}
-
-bool operator == (const StackFrame& lhs, const StackFrame& rhs) {
- return lhs.value == rhs.value;
-}
-
-bool operator != (const StackFrame& lhs, const StackFrame& rhs) {
- return !(lhs.value == rhs.value);
-}
-
-Backtrace::Backtrace() = default;
-
-bool operator==(const Backtrace& lhs, const Backtrace& rhs) {
- if (lhs.frame_count != rhs.frame_count) return false;
- return std::equal(lhs.frames, lhs.frames + lhs.frame_count, rhs.frames);
-}
-
-bool operator!=(const Backtrace& lhs, const Backtrace& rhs) {
- return !(lhs == rhs);
-}
-
-AllocationContext::AllocationContext(): type_name(nullptr) {}
-
-AllocationContext::AllocationContext(const Backtrace& backtrace,
- const char* type_name)
- : backtrace(backtrace), type_name(type_name) {}
-
-bool operator==(const AllocationContext& lhs, const AllocationContext& rhs) {
- return (lhs.backtrace == rhs.backtrace) && (lhs.type_name == rhs.type_name);
-}
-
-bool operator!=(const AllocationContext& lhs, const AllocationContext& rhs) {
- return !(lhs == rhs);
-}
-
-} // namespace trace_event
-} // namespace base
-
-namespace std {
-
-using base::trace_event::AllocationContext;
-using base::trace_event::Backtrace;
-using base::trace_event::StackFrame;
-
-size_t hash<StackFrame>::operator()(const StackFrame& frame) const {
- return hash<const void*>()(frame.value);
-}
-
-size_t hash<Backtrace>::operator()(const Backtrace& backtrace) const {
- const void* values[Backtrace::kMaxFrameCount];
- for (size_t i = 0; i != backtrace.frame_count; ++i) {
- values[i] = backtrace.frames[i].value;
- }
- return base::PersistentHash(values, backtrace.frame_count * sizeof(*values));
-}
-
-size_t hash<AllocationContext>::operator()(const AllocationContext& ctx) const {
- size_t backtrace_hash = hash<Backtrace>()(ctx.backtrace);
-
- // Multiplicative hash from [Knuth 1998]. Works best if |size_t| is 32 bits,
- // because the magic number is a prime very close to 2^32 / golden ratio, but
- // will still redistribute keys bijectively on 64-bit architectures because
- // the magic number is coprime to 2^64.
- size_t type_hash = reinterpret_cast<size_t>(ctx.type_name) * 2654435761;
-
- // Multiply one side to break the commutativity of +. Multiplication with a
- // number coprime to |numeric_limits<size_t>::max() + 1| is bijective so
- // randomness is preserved.
- return (backtrace_hash * 3) + type_hash;
-}
-
-} // namespace std
diff --git a/base/trace_event/heap_profiler_allocation_context.h b/base/trace_event/heap_profiler_allocation_context.h
deleted file mode 100644
index c35663f..0000000
--- a/base/trace_event/heap_profiler_allocation_context.h
+++ /dev/null
@@ -1,132 +0,0 @@
-// Copyright 2015 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_HEAP_PROFILER_ALLOCATION_CONTEXT_H_
-#define BASE_TRACE_EVENT_HEAP_PROFILER_ALLOCATION_CONTEXT_H_
-
-#include <stddef.h>
-#include <stdint.h>
-
-#include <functional>
-
-#include "base/base_export.h"
-
-namespace base {
-namespace trace_event {
-
-// When heap profiling is enabled, tracing keeps track of the allocation
-// context for each allocation intercepted. It is generated by the
-// |AllocationContextTracker| which keeps stacks of context in TLS.
-// The tracker is initialized lazily.
-
-// The backtrace in the allocation context is a snapshot of the stack. For now,
-// this is the pseudo stack where frames are created by trace event macros. In
-// the future, we might add the option to use the native call stack. In that
-// case, |Backtrace| and |AllocationContextTracker::GetContextSnapshot| might
-// have different implementations that can be selected by a compile time flag.
-
-// The number of stack frames stored in the backtrace is a trade off between
-// memory used for tracing and accuracy. Measurements done on a prototype
-// revealed that:
-//
-// - In 60 percent of the cases, pseudo stack depth <= 7.
-// - In 87 percent of the cases, pseudo stack depth <= 9.
-// - In 95 percent of the cases, pseudo stack depth <= 11.
-//
-// See the design doc (https://goo.gl/4s7v7b) for more details.
-
-// Represents (pseudo) stack frame. Used in Backtrace class below.
-//
-// Conceptually stack frame is identified by its value, and type is used
-// mostly to properly format the value. Value is expected to be a valid
-// pointer from process' address space.
-struct BASE_EXPORT StackFrame {
- enum class Type {
- TRACE_EVENT_NAME, // const char* string
- THREAD_NAME, // const char* thread name
- PROGRAM_COUNTER, // as returned by stack tracing (e.g. by StackTrace)
- };
-
- static StackFrame FromTraceEventName(const char* name) {
- return {Type::TRACE_EVENT_NAME, name};
- }
- static StackFrame FromThreadName(const char* name) {
- return {Type::THREAD_NAME, name};
- }
- static StackFrame FromProgramCounter(const void* pc) {
- return {Type::PROGRAM_COUNTER, pc};
- }
-
- Type type;
- const void* value;
-};
-
-bool BASE_EXPORT operator < (const StackFrame& lhs, const StackFrame& rhs);
-bool BASE_EXPORT operator == (const StackFrame& lhs, const StackFrame& rhs);
-bool BASE_EXPORT operator != (const StackFrame& lhs, const StackFrame& rhs);
-
-struct BASE_EXPORT Backtrace {
- Backtrace();
-
- // If the stack is higher than what can be stored here, the top frames
- // (the ones further from main()) are stored. Depth of 12 is enough for most
- // pseudo traces (see above), but not for native traces, where we need more.
- enum { kMaxFrameCount = 48 };
- StackFrame frames[kMaxFrameCount];
- size_t frame_count = 0;
-};
-
-bool BASE_EXPORT operator==(const Backtrace& lhs, const Backtrace& rhs);
-bool BASE_EXPORT operator!=(const Backtrace& lhs, const Backtrace& rhs);
-
-// The |AllocationContext| is context metadata that is kept for every allocation
-// when heap profiling is enabled. To simplify memory management for book-
-// keeping, this struct has a fixed size.
-struct BASE_EXPORT AllocationContext {
- AllocationContext();
- AllocationContext(const Backtrace& backtrace, const char* type_name);
-
- Backtrace backtrace;
-
- // Type name of the type stored in the allocated memory. A null pointer
- // indicates "unknown type". Grouping is done by comparing pointers, not by
- // deep string comparison. In a component build, where a type name can have a
- // string literal in several dynamic libraries, this may distort grouping.
- const char* type_name;
-};
-
-bool BASE_EXPORT operator==(const AllocationContext& lhs,
- const AllocationContext& rhs);
-bool BASE_EXPORT operator!=(const AllocationContext& lhs,
- const AllocationContext& rhs);
-
-// Struct to store the size and count of the allocations.
-struct AllocationMetrics {
- size_t size;
- size_t count;
-};
-
-} // namespace trace_event
-} // namespace base
-
-namespace std {
-
-template <>
-struct BASE_EXPORT hash<base::trace_event::StackFrame> {
- size_t operator()(const base::trace_event::StackFrame& frame) const;
-};
-
-template <>
-struct BASE_EXPORT hash<base::trace_event::Backtrace> {
- size_t operator()(const base::trace_event::Backtrace& backtrace) const;
-};
-
-template <>
-struct BASE_EXPORT hash<base::trace_event::AllocationContext> {
- size_t operator()(const base::trace_event::AllocationContext& context) const;
-};
-
-} // namespace std
-
-#endif // BASE_TRACE_EVENT_HEAP_PROFILER_ALLOCATION_CONTEXT_H_
diff --git a/base/trace_event/heap_profiler_allocation_context_tracker.cc b/base/trace_event/heap_profiler_allocation_context_tracker.cc
deleted file mode 100644
index 526eac8..0000000
--- a/base/trace_event/heap_profiler_allocation_context_tracker.cc
+++ /dev/null
@@ -1,253 +0,0 @@
-// Copyright 2015 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/heap_profiler_allocation_context_tracker.h"
-
-#include <algorithm>
-#include <iterator>
-
-#include "base/atomicops.h"
-#include "base/debug/leak_annotations.h"
-#include "base/debug/stack_trace.h"
-#include "base/no_destructor.h"
-#include "base/threading/platform_thread.h"
-#include "base/threading/thread_local_storage.h"
-#include "base/trace_event/heap_profiler_allocation_context.h"
-#include "build_config.h"
-
-#if defined(OS_LINUX) || defined(OS_ANDROID)
-#include <sys/prctl.h>
-#endif
-
-namespace base {
-namespace trace_event {
-
-subtle::Atomic32 AllocationContextTracker::capture_mode_ =
- static_cast<int32_t>(AllocationContextTracker::CaptureMode::DISABLED);
-
-namespace {
-
-const size_t kMaxStackDepth = 128u;
-const size_t kMaxTaskDepth = 16u;
-AllocationContextTracker* const kInitializingSentinel =
- reinterpret_cast<AllocationContextTracker*>(-1);
-
-// This function is added to the TLS slot to clean up the instance when the
-// thread exits.
-void DestructAllocationContextTracker(void* alloc_ctx_tracker) {
- delete static_cast<AllocationContextTracker*>(alloc_ctx_tracker);
-}
-
-ThreadLocalStorage::Slot& AllocationContextTrackerTLS() {
- static NoDestructor<ThreadLocalStorage::Slot> tls_alloc_ctx_tracker(
- &DestructAllocationContextTracker);
- return *tls_alloc_ctx_tracker;
-}
-
-// Cannot call ThreadIdNameManager::GetName because it holds a lock and causes
-// deadlock when lock is already held by ThreadIdNameManager before the current
-// allocation. Gets the thread name from kernel if available or returns a string
-// with id. This function intentionally leaks the allocated strings since they
-// are used to tag allocations even after the thread dies.
-const char* GetAndLeakThreadName() {
- char name[16];
-#if defined(OS_LINUX) || defined(OS_ANDROID)
- // If the thread name is not set, try to get it from prctl. Thread name might
- // not be set in cases where the thread started before heap profiling was
- // enabled.
- int err = prctl(PR_GET_NAME, name);
- if (!err) {
- return strdup(name);
- }
-#endif // defined(OS_LINUX) || defined(OS_ANDROID)
-
- // Use tid if we don't have a thread name.
- snprintf(name, sizeof(name), "%lu",
- static_cast<unsigned long>(PlatformThread::CurrentId()));
- return strdup(name);
-}
-
-} // namespace
-
-// static
-AllocationContextTracker*
-AllocationContextTracker::GetInstanceForCurrentThread() {
- AllocationContextTracker* tracker = static_cast<AllocationContextTracker*>(
- AllocationContextTrackerTLS().Get());
- if (tracker == kInitializingSentinel)
- return nullptr; // Re-entrancy case.
-
- if (!tracker) {
- AllocationContextTrackerTLS().Set(kInitializingSentinel);
- tracker = new AllocationContextTracker();
- AllocationContextTrackerTLS().Set(tracker);
- }
-
- return tracker;
-}
-
-AllocationContextTracker::AllocationContextTracker()
- : thread_name_(nullptr), ignore_scope_depth_(0) {
- tracked_stack_.reserve(kMaxStackDepth);
- task_contexts_.reserve(kMaxTaskDepth);
-}
-AllocationContextTracker::~AllocationContextTracker() = default;
-
-// static
-void AllocationContextTracker::SetCurrentThreadName(const char* name) {
- if (name && capture_mode() != CaptureMode::DISABLED) {
- GetInstanceForCurrentThread()->thread_name_ = name;
- }
-}
-
-// static
-void AllocationContextTracker::SetCaptureMode(CaptureMode mode) {
- // Release ordering ensures that when a thread observes |capture_mode_| to
- // be true through an acquire load, the TLS slot has been initialized.
- subtle::Release_Store(&capture_mode_, static_cast<int32_t>(mode));
-}
-
-void AllocationContextTracker::PushPseudoStackFrame(
- AllocationContextTracker::PseudoStackFrame stack_frame) {
- // Impose a limit on the height to verify that every push is popped, because
- // in practice the pseudo stack never grows higher than ~20 frames.
- if (tracked_stack_.size() < kMaxStackDepth) {
- tracked_stack_.push_back(
- StackFrame::FromTraceEventName(stack_frame.trace_event_name));
- } else {
- NOTREACHED();
- }
-}
-
-void AllocationContextTracker::PopPseudoStackFrame(
- AllocationContextTracker::PseudoStackFrame stack_frame) {
- // Guard for stack underflow. If tracing was started with a TRACE_EVENT in
- // scope, the frame was never pushed, so it is possible that pop is called
- // on an empty stack.
- if (tracked_stack_.empty())
- return;
-
- tracked_stack_.pop_back();
-}
-
-void AllocationContextTracker::PushNativeStackFrame(const void* pc) {
- if (tracked_stack_.size() < kMaxStackDepth)
- tracked_stack_.push_back(StackFrame::FromProgramCounter(pc));
- else
- NOTREACHED();
-}
-
-void AllocationContextTracker::PopNativeStackFrame(const void* pc) {
- if (tracked_stack_.empty())
- return;
-
- DCHECK_EQ(pc, tracked_stack_.back().value);
- tracked_stack_.pop_back();
-}
-
-void AllocationContextTracker::PushCurrentTaskContext(const char* context) {
- DCHECK(context);
- if (task_contexts_.size() < kMaxTaskDepth)
- task_contexts_.push_back(context);
- else
- NOTREACHED();
-}
-
-void AllocationContextTracker::PopCurrentTaskContext(const char* context) {
- // Guard for stack underflow. If tracing was started with a TRACE_EVENT in
- // scope, the context was never pushed, so it is possible that pop is called
- // on an empty stack.
- if (task_contexts_.empty())
- return;
-
- DCHECK_EQ(context, task_contexts_.back())
- << "Encountered an unmatched context end";
- task_contexts_.pop_back();
-}
-
-bool AllocationContextTracker::GetContextSnapshot(AllocationContext* ctx) {
- if (ignore_scope_depth_)
- return false;
-
- CaptureMode mode = static_cast<CaptureMode>(
- subtle::NoBarrier_Load(&capture_mode_));
-
- auto* backtrace = std::begin(ctx->backtrace.frames);
- auto* backtrace_end = std::end(ctx->backtrace.frames);
-
- if (!thread_name_) {
- // Ignore the string allocation made by GetAndLeakThreadName to avoid
- // reentrancy.
- ignore_scope_depth_++;
- thread_name_ = GetAndLeakThreadName();
- ANNOTATE_LEAKING_OBJECT_PTR(thread_name_);
- DCHECK(thread_name_);
- ignore_scope_depth_--;
- }
-
- // Add the thread name as the first entry in pseudo stack.
- if (thread_name_) {
- *backtrace++ = StackFrame::FromThreadName(thread_name_);
- }
-
- switch (mode) {
- case CaptureMode::DISABLED:
- {
- break;
- }
- case CaptureMode::PSEUDO_STACK:
- case CaptureMode::MIXED_STACK:
- {
- for (const StackFrame& stack_frame : tracked_stack_) {
- if (backtrace == backtrace_end)
- break;
- *backtrace++ = stack_frame;
- }
- break;
- }
- case CaptureMode::NATIVE_STACK:
- {
-// Backtrace contract requires us to return bottom frames, i.e.
-// from main() and up. Stack unwinding produces top frames, i.e.
-// from this point and up until main(). We intentionally request
-// kMaxFrameCount + 1 frames, so that we know if there are more frames
-// than our backtrace capacity.
-#if !defined(OS_NACL) // We don't build base/debug/stack_trace.cc for NaCl.
- // Fall-back to capturing the stack with base::debug::StackTrace,
- // which is likely slower, but more reliable.
- base::debug::StackTrace stack_trace(Backtrace::kMaxFrameCount + 1);
- size_t frame_count = 0u;
- const void* const* frames = stack_trace.Addresses(&frame_count);
-
- // If there are too many frames, keep the ones furthest from main().
- size_t backtrace_capacity = backtrace_end - backtrace;
- int32_t starting_frame_index = frame_count;
- if (frame_count > backtrace_capacity) {
- starting_frame_index = backtrace_capacity - 1;
- *backtrace++ = StackFrame::FromTraceEventName("<truncated>");
- }
- for (int32_t i = starting_frame_index - 1; i >= 0; --i) {
- const void* frame = frames[i];
- *backtrace++ = StackFrame::FromProgramCounter(frame);
- }
-#endif // !defined(OS_NACL)
- break;
- }
- }
-
- ctx->backtrace.frame_count = backtrace - std::begin(ctx->backtrace.frames);
-
- // TODO(ssid): Fix crbug.com/594803 to add file name as 3rd dimension
- // (component name) in the heap profiler and not piggy back on the type name.
- if (!task_contexts_.empty()) {
- ctx->type_name = task_contexts_.back();
- } else {
- ctx->type_name = nullptr;
- }
-
- return true;
-}
-
-} // namespace trace_event
-} // namespace base
diff --git a/base/trace_event/heap_profiler_allocation_context_tracker.h b/base/trace_event/heap_profiler_allocation_context_tracker.h
deleted file mode 100644
index da03b7f..0000000
--- a/base/trace_event/heap_profiler_allocation_context_tracker.h
+++ /dev/null
@@ -1,140 +0,0 @@
-// Copyright 2015 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_HEAP_PROFILER_ALLOCATION_CONTEXT_TRACKER_H_
-#define BASE_TRACE_EVENT_HEAP_PROFILER_ALLOCATION_CONTEXT_TRACKER_H_
-
-#include <vector>
-
-#include "base/atomicops.h"
-#include "base/base_export.h"
-#include "base/macros.h"
-#include "base/trace_event/heap_profiler_allocation_context.h"
-
-namespace base {
-namespace trace_event {
-
-// AllocationContextTracker is a thread-local object. Its main purpose is to
-// keep track of a pseudo stack of trace events. Chrome has been instrumented
-// with lots of `TRACE_EVENT` macros. These trace events push their name to a
-// thread-local stack when they go into scope, and pop when they go out of
-// scope, if all of the following conditions have been met:
-//
-// * A trace is being recorded.
-// * The category of the event is enabled in the trace config.
-// * Heap profiling is enabled (with the `--enable-heap-profiling` flag).
-//
-// This means that allocations that occur before tracing is started will not
-// have backtrace information in their context.
-//
-// AllocationContextTracker also keeps track of some thread state not related to
-// trace events. See |AllocationContext|.
-//
-// A thread-local instance of the context tracker is initialized lazily when it
-// is first accessed. This might be because a trace event pushed or popped, or
-// because `GetContextSnapshot()` was called when an allocation occurred
-class BASE_EXPORT AllocationContextTracker {
- public:
- enum class CaptureMode : int32_t {
- DISABLED, // Don't capture anything
- PSEUDO_STACK, // Backtrace has trace events
- MIXED_STACK, // Backtrace has trace events + from
- // HeapProfilerScopedStackFrame
- NATIVE_STACK, // Backtrace has full native backtraces from stack unwinding
- };
-
- // Stack frame constructed from trace events in codebase.
- struct BASE_EXPORT PseudoStackFrame {
- const char* trace_event_category;
- const char* trace_event_name;
-
- bool operator==(const PseudoStackFrame& other) const {
- return trace_event_category == other.trace_event_category &&
- trace_event_name == other.trace_event_name;
- }
- };
-
- // Globally sets capturing mode.
- // TODO(primiano): How to guard against *_STACK -> DISABLED -> *_STACK?
- static void SetCaptureMode(CaptureMode mode);
-
- // Returns global capturing mode.
- inline static CaptureMode capture_mode() {
- // A little lag after heap profiling is enabled or disabled is fine, it is
- // more important that the check is as cheap as possible when capturing is
- // not enabled, so do not issue a memory barrier in the fast path.
- if (subtle::NoBarrier_Load(&capture_mode_) ==
- static_cast<int32_t>(CaptureMode::DISABLED))
- return CaptureMode::DISABLED;
-
- // In the slow path, an acquire load is required to pair with the release
- // store in |SetCaptureMode|. This is to ensure that the TLS slot for
- // the thread-local allocation context tracker has been initialized if
- // |capture_mode| returns something other than DISABLED.
- return static_cast<CaptureMode>(subtle::Acquire_Load(&capture_mode_));
- }
-
- // Returns the thread-local instance, creating one if necessary. Returns
- // always a valid instance, unless it is called re-entrantly, in which case
- // returns nullptr in the nested calls.
- static AllocationContextTracker* GetInstanceForCurrentThread();
-
- // Set the thread name in the AllocationContextTracker of the current thread
- // if capture is enabled.
- static void SetCurrentThreadName(const char* name);
-
- // Starts and ends a new ignore scope between which the allocations are
- // ignored by the heap profiler. GetContextSnapshot() returns false when
- // allocations are ignored.
- void begin_ignore_scope() { ignore_scope_depth_++; }
- void end_ignore_scope() {
- if (ignore_scope_depth_)
- ignore_scope_depth_--;
- }
-
- // Pushes and pops a frame onto the thread-local pseudo stack.
- // TODO(ssid): Change PseudoStackFrame to const char*. Only event name is
- // used.
- void PushPseudoStackFrame(PseudoStackFrame stack_frame);
- void PopPseudoStackFrame(PseudoStackFrame stack_frame);
-
- // Pushes and pops a native stack frame onto thread local tracked stack.
- void PushNativeStackFrame(const void* pc);
- void PopNativeStackFrame(const void* pc);
-
- // Push and pop current task's context. A stack is used to support nested
- // tasks and the top of the stack will be used in allocation context.
- void PushCurrentTaskContext(const char* context);
- void PopCurrentTaskContext(const char* context);
-
- // Fills a snapshot of the current thread-local context. Doesn't fill and
- // returns false if allocations are being ignored.
- bool GetContextSnapshot(AllocationContext* snapshot);
-
- ~AllocationContextTracker();
-
- private:
- AllocationContextTracker();
-
- static subtle::Atomic32 capture_mode_;
-
- // The pseudo stack where frames are |TRACE_EVENT| names or inserted PCs.
- std::vector<StackFrame> tracked_stack_;
-
- // The thread name is used as the first entry in the pseudo stack.
- const char* thread_name_;
-
- // Stack of tasks' contexts. Context serves as a different dimension than
- // pseudo stack to cluster allocations.
- std::vector<const char*> task_contexts_;
-
- uint32_t ignore_scope_depth_;
-
- DISALLOW_COPY_AND_ASSIGN(AllocationContextTracker);
-};
-
-} // namespace trace_event
-} // namespace base
-
-#endif // BASE_TRACE_EVENT_HEAP_PROFILER_ALLOCATION_CONTEXT_TRACKER_H_
diff --git a/base/trace_event/heap_profiler_event_filter.cc b/base/trace_event/heap_profiler_event_filter.cc
deleted file mode 100644
index 937072c..0000000
--- a/base/trace_event/heap_profiler_event_filter.cc
+++ /dev/null
@@ -1,70 +0,0 @@
-// Copyright 2016 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/heap_profiler_event_filter.h"
-
-#include "base/trace_event/category_registry.h"
-#include "base/trace_event/heap_profiler_allocation_context_tracker.h"
-#include "base/trace_event/trace_category.h"
-#include "base/trace_event/trace_event.h"
-#include "base/trace_event/trace_event_impl.h"
-
-namespace base {
-namespace trace_event {
-
-namespace {
-
-inline bool IsPseudoStackEnabled() {
- // Only PSEUDO_STACK and MIXED_STACK modes require trace events.
- return AllocationContextTracker::capture_mode() ==
- AllocationContextTracker::CaptureMode::PSEUDO_STACK ||
- AllocationContextTracker::capture_mode() ==
- AllocationContextTracker::CaptureMode::MIXED_STACK;
-}
-
-inline AllocationContextTracker* GetThreadLocalTracker() {
- return AllocationContextTracker::GetInstanceForCurrentThread();
-}
-
-} // namespace
-
-// static
-const char HeapProfilerEventFilter::kName[] = "heap_profiler_predicate";
-
-HeapProfilerEventFilter::HeapProfilerEventFilter() = default;
-HeapProfilerEventFilter::~HeapProfilerEventFilter() = default;
-
-bool HeapProfilerEventFilter::FilterTraceEvent(
- const TraceEvent& trace_event) const {
- if (!IsPseudoStackEnabled())
- return true;
-
- // TODO(primiano): Add support for events with copied name crbug.com/581079.
- if (trace_event.flags() & TRACE_EVENT_FLAG_COPY)
- return true;
-
- const auto* category = CategoryRegistry::GetCategoryByStatePtr(
- trace_event.category_group_enabled());
- AllocationContextTracker::PseudoStackFrame frame = {category->name(),
- trace_event.name()};
- if (trace_event.phase() == TRACE_EVENT_PHASE_BEGIN ||
- trace_event.phase() == TRACE_EVENT_PHASE_COMPLETE) {
- GetThreadLocalTracker()->PushPseudoStackFrame(frame);
- } else if (trace_event.phase() == TRACE_EVENT_PHASE_END) {
- // The pop for |TRACE_EVENT_PHASE_COMPLETE| events is in |EndEvent|.
- GetThreadLocalTracker()->PopPseudoStackFrame(frame);
- }
- // Do not filter-out any events and always return true. TraceLog adds the
- // event only if it is enabled for recording.
- return true;
-}
-
-void HeapProfilerEventFilter::EndEvent(const char* category_name,
- const char* event_name) const {
- if (IsPseudoStackEnabled())
- GetThreadLocalTracker()->PopPseudoStackFrame({category_name, event_name});
-}
-
-} // namespace trace_event
-} // namespace base
diff --git a/base/trace_event/heap_profiler_event_filter.h b/base/trace_event/heap_profiler_event_filter.h
deleted file mode 100644
index 47368a1..0000000
--- a/base/trace_event/heap_profiler_event_filter.h
+++ /dev/null
@@ -1,40 +0,0 @@
-// Copyright 2016 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_HEAP_PROFILER_EVENT_FILTER_H_
-#define BASE_TRACE_EVENT_HEAP_PROFILER_EVENT_FILTER_H_
-
-#include "base/base_export.h"
-#include "base/macros.h"
-#include "base/trace_event/trace_event_filter.h"
-
-namespace base {
-namespace trace_event {
-
-class TraceEvent;
-
-// This filter unconditionally accepts all events and pushes/pops them from the
-// thread-local AllocationContextTracker instance as they are seen.
-// This is used to cheaply construct the heap profiler pseudo stack without
-// having to actually record all events.
-class BASE_EXPORT HeapProfilerEventFilter : public TraceEventFilter {
- public:
- static const char kName[];
-
- HeapProfilerEventFilter();
- ~HeapProfilerEventFilter() override;
-
- // TraceEventFilter implementation.
- bool FilterTraceEvent(const TraceEvent& trace_event) const override;
- void EndEvent(const char* category_name,
- const char* event_name) const override;
-
- private:
- DISALLOW_COPY_AND_ASSIGN(HeapProfilerEventFilter);
-};
-
-} // namespace trace_event
-} // namespace base
-
-#endif // BASE_TRACE_EVENT_HEAP_PROFILER_EVENT_FILTER_H_
diff --git a/base/trace_event/heap_profiler_heap_dump_writer.cc b/base/trace_event/heap_profiler_heap_dump_writer.cc
deleted file mode 100644
index 71c3d97..0000000
--- a/base/trace_event/heap_profiler_heap_dump_writer.cc
+++ /dev/null
@@ -1,323 +0,0 @@
-// Copyright 2015 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/heap_profiler_heap_dump_writer.h"
-
-#include <stdint.h>
-
-#include <algorithm>
-#include <iterator>
-#include <tuple>
-#include <utility>
-#include <vector>
-
-#include "base/format_macros.h"
-#include "base/logging.h"
-#include "base/macros.h"
-#include "base/strings/stringprintf.h"
-#include "base/trace_event/heap_profiler_serialization_state.h"
-#include "base/trace_event/heap_profiler_stack_frame_deduplicator.h"
-#include "base/trace_event/heap_profiler_type_name_deduplicator.h"
-#include "base/trace_event/trace_config.h"
-#include "base/trace_event/trace_event.h"
-#include "base/trace_event/trace_event_argument.h"
-#include "base/trace_event/trace_log.h"
-
-// Most of what the |HeapDumpWriter| does is aggregating detailed information
-// about the heap and deciding what to dump. The Input to this process is a list
-// of |AllocationContext|s and size pairs.
-//
-// The pairs are grouped into |Bucket|s. A bucket is a group of (context, size)
-// pairs where the properties of the contexts share a prefix. (Type name is
-// considered a list of length one here.) First all pairs are put into one
-// bucket that represents the entire heap. Then this bucket is recursively
-// broken down into smaller buckets. Each bucket keeps track of whether further
-// breakdown is possible.
-
-namespace base {
-namespace trace_event {
-namespace internal {
-namespace {
-
-// Denotes a property of |AllocationContext| to break down by.
-enum class BreakDownMode { kByBacktrace, kByTypeName };
-
-// A group of bytes for which the context shares a prefix.
-struct Bucket {
- Bucket()
- : size(0),
- count(0),
- backtrace_cursor(0),
- is_broken_down_by_type_name(false) {}
-
- std::vector<std::pair<const AllocationContext*, AllocationMetrics>>
- metrics_by_context;
-
- // The sum of the sizes of |metrics_by_context|.
- size_t size;
-
- // The sum of number of allocations of |metrics_by_context|.
- size_t count;
-
- // The index of the stack frame that has not yet been broken down by. For all
- // elements in this bucket, the stack frames 0 up to (but not including) the
- // cursor, must be equal.
- size_t backtrace_cursor;
-
- // When true, the type name for all elements in this bucket must be equal.
- bool is_broken_down_by_type_name;
-};
-
-// Comparison operator to order buckets by their size.
-bool operator<(const Bucket& lhs, const Bucket& rhs) {
- return lhs.size < rhs.size;
-}
-
-// Groups the allocations in the bucket by |break_by|. The buckets in the
-// returned list will have |backtrace_cursor| advanced or
-// |is_broken_down_by_type_name| set depending on the property to group by.
-std::vector<Bucket> GetSubbuckets(const Bucket& bucket,
- BreakDownMode break_by) {
- std::unordered_map<const void*, Bucket> breakdown;
-
- if (break_by == BreakDownMode::kByBacktrace) {
- for (const auto& context_and_metrics : bucket.metrics_by_context) {
- const Backtrace& backtrace = context_and_metrics.first->backtrace;
- const StackFrame* begin = std::begin(backtrace.frames);
- const StackFrame* end = begin + backtrace.frame_count;
- const StackFrame* cursor = begin + bucket.backtrace_cursor;
-
- DCHECK_LE(cursor, end);
-
- if (cursor != end) {
- Bucket& subbucket = breakdown[cursor->value];
- subbucket.size += context_and_metrics.second.size;
- subbucket.count += context_and_metrics.second.count;
- subbucket.metrics_by_context.push_back(context_and_metrics);
- subbucket.backtrace_cursor = bucket.backtrace_cursor + 1;
- subbucket.is_broken_down_by_type_name =
- bucket.is_broken_down_by_type_name;
- DCHECK_GT(subbucket.size, 0u);
- DCHECK_GT(subbucket.count, 0u);
- }
- }
- } else if (break_by == BreakDownMode::kByTypeName) {
- if (!bucket.is_broken_down_by_type_name) {
- for (const auto& context_and_metrics : bucket.metrics_by_context) {
- const AllocationContext* context = context_and_metrics.first;
- Bucket& subbucket = breakdown[context->type_name];
- subbucket.size += context_and_metrics.second.size;
- subbucket.count += context_and_metrics.second.count;
- subbucket.metrics_by_context.push_back(context_and_metrics);
- subbucket.backtrace_cursor = bucket.backtrace_cursor;
- subbucket.is_broken_down_by_type_name = true;
- DCHECK_GT(subbucket.size, 0u);
- DCHECK_GT(subbucket.count, 0u);
- }
- }
- }
-
- std::vector<Bucket> buckets;
- buckets.reserve(breakdown.size());
- for (auto key_bucket : breakdown)
- buckets.push_back(key_bucket.second);
-
- return buckets;
-}
-
-// Breaks down the bucket by |break_by|. Returns only buckets that contribute
-// more than |min_size_bytes| to the total size. The long tail is omitted.
-std::vector<Bucket> BreakDownBy(const Bucket& bucket,
- BreakDownMode break_by,
- size_t min_size_bytes) {
- std::vector<Bucket> buckets = GetSubbuckets(bucket, break_by);
-
- // Ensure that |buckets| is a max-heap (the data structure, not memory heap),
- // so its front contains the largest bucket. Buckets should be iterated
- // ordered by size, but sorting the vector is overkill because the long tail
- // of small buckets will be discarded. By using a max-heap, the optimal case
- // where all but the first bucket are discarded is O(n). The worst case where
- // no bucket is discarded is doing a heap sort, which is O(n log n).
- std::make_heap(buckets.begin(), buckets.end());
-
- // Keep including buckets until adding one would increase the number of
- // bytes accounted for by |min_size_bytes|. The large buckets end up in
- // [it, end()), [begin(), it) is the part that contains the max-heap
- // of small buckets.
- std::vector<Bucket>::iterator it;
- for (it = buckets.end(); it != buckets.begin(); --it) {
- if (buckets.front().size < min_size_bytes)
- break;
-
- // Put the largest bucket in [begin, it) at |it - 1| and max-heapify
- // [begin, it - 1). This puts the next largest bucket at |buckets.front()|.
- std::pop_heap(buckets.begin(), it);
- }
-
- // At this point, |buckets| looks like this (numbers are bucket sizes):
- //
- // <-- max-heap of small buckets --->
- // <-- large buckets by ascending size -->
- // [ 19 | 11 | 13 | 7 | 2 | 5 | ... | 83 | 89 | 97 ]
- // ^ ^ ^
- // | | |
- // begin() it end()
-
- // Discard the long tail of buckets that contribute less than a percent.
- buckets.erase(buckets.begin(), it);
-
- return buckets;
-}
-
-} // namespace
-
-bool operator<(Entry lhs, Entry rhs) {
- // There is no need to compare |size|. If the backtrace and type name are
- // equal then the sizes must be equal as well.
- return std::tie(lhs.stack_frame_id, lhs.type_id) <
- std::tie(rhs.stack_frame_id, rhs.type_id);
-}
-
-HeapDumpWriter::HeapDumpWriter(StackFrameDeduplicator* stack_frame_deduplicator,
- TypeNameDeduplicator* type_name_deduplicator,
- uint32_t breakdown_threshold_bytes)
- : stack_frame_deduplicator_(stack_frame_deduplicator),
- type_name_deduplicator_(type_name_deduplicator),
- breakdown_threshold_bytes_(breakdown_threshold_bytes) {}
-
-HeapDumpWriter::~HeapDumpWriter() = default;
-
-bool HeapDumpWriter::AddEntryForBucket(const Bucket& bucket) {
- // The contexts in the bucket are all different, but the [begin, cursor) range
- // is equal for all contexts in the bucket, and the type names are the same if
- // |is_broken_down_by_type_name| is set.
- DCHECK(!bucket.metrics_by_context.empty());
-
- const AllocationContext* context = bucket.metrics_by_context.front().first;
-
- const StackFrame* backtrace_begin = std::begin(context->backtrace.frames);
- const StackFrame* backtrace_end = backtrace_begin + bucket.backtrace_cursor;
- DCHECK_LE(bucket.backtrace_cursor, arraysize(context->backtrace.frames));
-
- Entry entry;
- entry.stack_frame_id =
- stack_frame_deduplicator_->Insert(backtrace_begin, backtrace_end);
-
- // Deduplicate the type name, or use ID -1 if type name is not set.
- entry.type_id = bucket.is_broken_down_by_type_name
- ? type_name_deduplicator_->Insert(context->type_name)
- : -1;
-
- entry.size = bucket.size;
- entry.count = bucket.count;
-
- auto position_and_inserted = entries_.insert(entry);
- return position_and_inserted.second;
-}
-
-void HeapDumpWriter::BreakDown(const Bucket& bucket) {
- auto by_backtrace = BreakDownBy(bucket, BreakDownMode::kByBacktrace,
- breakdown_threshold_bytes_);
- auto by_type_name = BreakDownBy(bucket, BreakDownMode::kByTypeName,
- breakdown_threshold_bytes_);
-
- // Insert entries for the buckets. If a bucket was not present before, it has
- // not been broken down before, so recursively continue breaking down in that
- // case. There might be multiple routes to the same entry (first break down
- // by type name, then by backtrace, or first by backtrace and then by type),
- // so a set is used to avoid dumping and breaking down entries more than once.
-
- for (const Bucket& subbucket : by_backtrace)
- if (AddEntryForBucket(subbucket))
- BreakDown(subbucket);
-
- for (const Bucket& subbucket : by_type_name)
- if (AddEntryForBucket(subbucket))
- BreakDown(subbucket);
-}
-
-const std::set<Entry>& HeapDumpWriter::Summarize(
- const std::unordered_map<AllocationContext, AllocationMetrics>&
- metrics_by_context) {
- // Start with one bucket that represents the entire heap. Iterate by
- // reference, because the allocation contexts are going to point to allocation
- // contexts stored in |metrics_by_context|.
- Bucket root_bucket;
- for (const auto& context_and_metrics : metrics_by_context) {
- DCHECK_GT(context_and_metrics.second.size, 0u);
- DCHECK_GT(context_and_metrics.second.count, 0u);
- const AllocationContext* context = &context_and_metrics.first;
- root_bucket.metrics_by_context.push_back(
- std::make_pair(context, context_and_metrics.second));
- root_bucket.size += context_and_metrics.second.size;
- root_bucket.count += context_and_metrics.second.count;
- }
-
- AddEntryForBucket(root_bucket);
-
- // Recursively break down the heap and fill |entries_| with entries to dump.
- BreakDown(root_bucket);
-
- return entries_;
-}
-
-std::unique_ptr<TracedValue> Serialize(const std::set<Entry>& entries) {
- std::string buffer;
- std::unique_ptr<TracedValue> traced_value(new TracedValue);
-
- traced_value->BeginArray("entries");
-
- for (const Entry& entry : entries) {
- traced_value->BeginDictionary();
-
- // Format size as hexadecimal string into |buffer|.
- SStringPrintf(&buffer, "%" PRIx64, static_cast<uint64_t>(entry.size));
- traced_value->SetString("size", buffer);
-
- SStringPrintf(&buffer, "%" PRIx64, static_cast<uint64_t>(entry.count));
- traced_value->SetString("count", buffer);
-
- if (entry.stack_frame_id == -1) {
- // An empty backtrace (which will have ID -1) is represented by the empty
- // string, because there is no leaf frame to reference in |stackFrames|.
- traced_value->SetString("bt", "");
- } else {
- // Format index of the leaf frame as a string, because |stackFrames| is a
- // dictionary, not an array.
- SStringPrintf(&buffer, "%i", entry.stack_frame_id);
- traced_value->SetString("bt", buffer);
- }
-
- // Type ID -1 (cumulative size for all types) is represented by the absence
- // of the "type" key in the dictionary.
- if (entry.type_id != -1) {
- // Format the type ID as a string.
- SStringPrintf(&buffer, "%i", entry.type_id);
- traced_value->SetString("type", buffer);
- }
-
- traced_value->EndDictionary();
- }
-
- traced_value->EndArray(); // "entries"
- return traced_value;
-}
-
-} // namespace internal
-
-std::unique_ptr<TracedValue> ExportHeapDump(
- const std::unordered_map<AllocationContext, AllocationMetrics>&
- metrics_by_context,
- const HeapProfilerSerializationState& heap_profiler_serialization_state) {
- TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("memory-infra"), "ExportHeapDump");
- internal::HeapDumpWriter writer(
- heap_profiler_serialization_state.stack_frame_deduplicator(),
- heap_profiler_serialization_state.type_name_deduplicator(),
- heap_profiler_serialization_state
- .heap_profiler_breakdown_threshold_bytes());
- return Serialize(writer.Summarize(metrics_by_context));
-}
-
-} // namespace trace_event
-} // namespace base
diff --git a/base/trace_event/heap_profiler_heap_dump_writer.h b/base/trace_event/heap_profiler_heap_dump_writer.h
deleted file mode 100644
index 3366c28..0000000
--- a/base/trace_event/heap_profiler_heap_dump_writer.h
+++ /dev/null
@@ -1,115 +0,0 @@
-// Copyright 2015 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_HEAP_PROFILER_HEAP_DUMP_WRITER_H_
-#define BASE_TRACE_EVENT_HEAP_PROFILER_HEAP_DUMP_WRITER_H_
-
-#include <stddef.h>
-
-#include <memory>
-#include <set>
-#include <unordered_map>
-
-#include "base/base_export.h"
-#include "base/macros.h"
-#include "base/trace_event/heap_profiler_allocation_context.h"
-
-namespace base {
-namespace trace_event {
-
-class HeapProfilerSerializationState;
-class StackFrameDeduplicator;
-class TracedValue;
-class TypeNameDeduplicator;
-
-// Aggregates |metrics_by_context|, recursively breaks down the heap, and
-// returns a traced value with an "entries" array that can be dumped in the
-// trace log, following the format described in https://goo.gl/KY7zVE. The
-// number of entries is kept reasonable because long tails are not included.
-BASE_EXPORT std::unique_ptr<TracedValue> ExportHeapDump(
- const std::unordered_map<AllocationContext, AllocationMetrics>&
- metrics_by_context,
- const HeapProfilerSerializationState& heap_profiler_serialization_state);
-
-namespace internal {
-
-namespace {
-struct Bucket;
-}
-
-// An entry in the "entries" array as described in https://goo.gl/KY7zVE.
-struct BASE_EXPORT Entry {
- size_t size;
- size_t count;
-
- // References a backtrace in the stack frame deduplicator. -1 means empty
- // backtrace (the root of the tree).
- int stack_frame_id;
-
- // References a type name in the type name deduplicator. -1 indicates that
- // the size is the cumulative size for all types (the root of the tree).
- int type_id;
-};
-
-// Comparison operator to enable putting |Entry| in a |std::set|.
-BASE_EXPORT bool operator<(Entry lhs, Entry rhs);
-
-// Serializes entries to an "entries" array in a traced value.
-BASE_EXPORT std::unique_ptr<TracedValue> Serialize(const std::set<Entry>& dump);
-
-// Helper class to dump a snapshot of an |AllocationRegister| or other heap
-// bookkeeping structure into a |TracedValue|. This class is intended to be
-// used as a one-shot local instance on the stack.
-class BASE_EXPORT HeapDumpWriter {
- public:
- // The |stack_frame_deduplicator| and |type_name_deduplicator| are not owned.
- // The heap dump writer assumes exclusive access to them during the lifetime
- // of the dump writer. The heap dumps are broken down for allocations bigger
- // than |breakdown_threshold_bytes|.
- HeapDumpWriter(StackFrameDeduplicator* stack_frame_deduplicator,
- TypeNameDeduplicator* type_name_deduplicator,
- uint32_t breakdown_threshold_bytes);
-
- ~HeapDumpWriter();
-
- // Aggregates allocations to compute the total size of the heap, then breaks
- // down the heap recursively. This produces the values that should be dumped
- // in the "entries" array. The number of entries is kept reasonable because
- // long tails are not included. Use |Serialize| to convert to a traced value.
- const std::set<Entry>& Summarize(
- const std::unordered_map<AllocationContext, AllocationMetrics>&
- metrics_by_context);
-
- private:
- // Inserts an |Entry| for |Bucket| into |entries_|. Returns false if the
- // entry was present before, true if it was not.
- bool AddEntryForBucket(const Bucket& bucket);
-
- // Recursively breaks down a bucket into smaller buckets and adds entries for
- // the buckets worth dumping to |entries_|.
- void BreakDown(const Bucket& bucket);
-
- // The collection of entries that is filled by |Summarize|.
- std::set<Entry> entries_;
-
- // Helper for generating the |stackFrames| dictionary. Not owned, must outlive
- // this heap dump writer instance.
- StackFrameDeduplicator* const stack_frame_deduplicator_;
-
- // Helper for converting type names to IDs. Not owned, must outlive this heap
- // dump writer instance.
- TypeNameDeduplicator* const type_name_deduplicator_;
-
- // Minimum size of an allocation for which an allocation bucket will be
- // broken down with children.
- uint32_t breakdown_threshold_bytes_;
-
- DISALLOW_COPY_AND_ASSIGN(HeapDumpWriter);
-};
-
-} // namespace internal
-} // namespace trace_event
-} // namespace base
-
-#endif // BASE_TRACE_EVENT_HEAP_PROFILER_HEAP_DUMP_WRITER_H_
diff --git a/base/trace_event/heap_profiler_serialization_state.cc b/base/trace_event/heap_profiler_serialization_state.cc
deleted file mode 100644
index b1866e7..0000000
--- a/base/trace_event/heap_profiler_serialization_state.cc
+++ /dev/null
@@ -1,27 +0,0 @@
-// Copyright 2015 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/heap_profiler_serialization_state.h"
-
-namespace base {
-namespace trace_event {
-
-HeapProfilerSerializationState::HeapProfilerSerializationState()
- : heap_profiler_breakdown_threshold_bytes_(0) {}
-HeapProfilerSerializationState::~HeapProfilerSerializationState() = default;
-
-void HeapProfilerSerializationState::SetStackFrameDeduplicator(
- std::unique_ptr<StackFrameDeduplicator> stack_frame_deduplicator) {
- DCHECK(!stack_frame_deduplicator_);
- stack_frame_deduplicator_ = std::move(stack_frame_deduplicator);
-}
-
-void HeapProfilerSerializationState::SetTypeNameDeduplicator(
- std::unique_ptr<TypeNameDeduplicator> type_name_deduplicator) {
- DCHECK(!type_name_deduplicator_);
- type_name_deduplicator_ = std::move(type_name_deduplicator);
-}
-
-} // namespace trace_event
-} // namespace base
diff --git a/base/trace_event/heap_profiler_serialization_state.h b/base/trace_event/heap_profiler_serialization_state.h
deleted file mode 100644
index 53c5687..0000000
--- a/base/trace_event/heap_profiler_serialization_state.h
+++ /dev/null
@@ -1,80 +0,0 @@
-// Copyright 2015 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_HEAP_PROFILER_SERIALIZATION_STATE_H_
-#define BASE_TRACE_EVENT_HEAP_PROFILER_SERIALIZATION_STATE_H_
-
-#include <memory>
-#include <set>
-
-#include "base/base_export.h"
-#include "base/trace_event/heap_profiler_stack_frame_deduplicator.h"
-#include "base/trace_event/heap_profiler_type_name_deduplicator.h"
-#include "base/trace_event/memory_dump_request_args.h"
-
-namespace base {
-namespace trace_event {
-
-// Container for state variables that should be shared across all the memory
-// dumps in a tracing session.
-class BASE_EXPORT HeapProfilerSerializationState
- : public RefCountedThreadSafe<HeapProfilerSerializationState> {
- public:
- HeapProfilerSerializationState();
-
- // Returns the stack frame deduplicator that should be used by memory dump
- // providers when doing a heap dump.
- StackFrameDeduplicator* stack_frame_deduplicator() const {
- return stack_frame_deduplicator_.get();
- }
-
- void SetStackFrameDeduplicator(
- std::unique_ptr<StackFrameDeduplicator> stack_frame_deduplicator);
-
- // Returns the type name deduplicator that should be used by memory dump
- // providers when doing a heap dump.
- TypeNameDeduplicator* type_name_deduplicator() const {
- return type_name_deduplicator_.get();
- }
-
- void SetTypeNameDeduplicator(
- std::unique_ptr<TypeNameDeduplicator> type_name_deduplicator);
-
- void SetAllowedDumpModes(
- std::set<MemoryDumpLevelOfDetail> allowed_dump_modes);
-
- bool IsDumpModeAllowed(MemoryDumpLevelOfDetail dump_mode) const;
-
- void set_heap_profiler_breakdown_threshold_bytes(uint32_t value) {
- heap_profiler_breakdown_threshold_bytes_ = value;
- }
-
- uint32_t heap_profiler_breakdown_threshold_bytes() const {
- return heap_profiler_breakdown_threshold_bytes_;
- }
-
- bool is_initialized() const {
- return stack_frame_deduplicator_ && type_name_deduplicator_ &&
- heap_profiler_breakdown_threshold_bytes_;
- }
-
- private:
- friend class RefCountedThreadSafe<HeapProfilerSerializationState>;
- ~HeapProfilerSerializationState();
-
- // Deduplicates backtraces in heap dumps so they can be written once when the
- // trace is finalized.
- std::unique_ptr<StackFrameDeduplicator> stack_frame_deduplicator_;
-
- // Deduplicates type names in heap dumps so they can be written once when the
- // trace is finalized.
- std::unique_ptr<TypeNameDeduplicator> type_name_deduplicator_;
-
- uint32_t heap_profiler_breakdown_threshold_bytes_;
-};
-
-} // namespace trace_event
-} // namespace base
-
-#endif // BASE_TRACE_EVENT_HEAP_PROFILER_SERIALIZATION_STATE_H
diff --git a/base/trace_event/heap_profiler_stack_frame_deduplicator.cc b/base/trace_event/heap_profiler_stack_frame_deduplicator.cc
deleted file mode 100644
index c05cd0a..0000000
--- a/base/trace_event/heap_profiler_stack_frame_deduplicator.cc
+++ /dev/null
@@ -1,195 +0,0 @@
-// Copyright 2015 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/heap_profiler_stack_frame_deduplicator.h"
-
-#include <inttypes.h>
-#include <stddef.h>
-
-#include <algorithm>
-#include <string>
-#include <utility>
-
-#include "base/hash.h"
-#include "base/strings/stringprintf.h"
-#include "base/trace_event/memory_usage_estimator.h"
-#include "base/trace_event/trace_event.h"
-#include "base/trace_event/trace_event_argument.h"
-#include "base/trace_event/trace_event_memory_overhead.h"
-
-namespace base {
-namespace trace_event {
-
-namespace {
-
-// Dumb hash function that nevertheless works surprisingly well and
-// produces ~0 collisions on real backtraces.
-size_t HashBacktrace(const StackFrame* begin, const StackFrame* end) {
- size_t hash = 0;
- for (; begin != end; begin++) {
- hash += reinterpret_cast<uintptr_t>(begin->value);
- }
- return hash;
-}
-
-} // namespace
-
-StackFrameDeduplicator::FrameNode::FrameNode(StackFrame frame,
- int parent_frame_index)
- : frame(frame), parent_frame_index(parent_frame_index) {}
-StackFrameDeduplicator::FrameNode::FrameNode(const FrameNode& other) = default;
-StackFrameDeduplicator::FrameNode::~FrameNode() = default;
-
-size_t StackFrameDeduplicator::FrameNode::EstimateMemoryUsage() const {
- return base::trace_event::EstimateMemoryUsage(children);
-}
-
-StackFrameDeduplicator::StackFrameDeduplicator() = default;
-StackFrameDeduplicator::~StackFrameDeduplicator() = default;
-
-bool StackFrameDeduplicator::Match(int frame_index,
- const StackFrame* begin_frame,
- const StackFrame* end_frame) const {
- // |frame_index| identifies the bottom frame, i.e. we need to walk
- // backtrace backwards.
- const StackFrame* current_frame = end_frame - 1;
- for (; current_frame >= begin_frame; --current_frame) {
- const FrameNode& node = frames_[frame_index];
- if (node.frame != *current_frame) {
- break;
- }
-
- frame_index = node.parent_frame_index;
- if (frame_index == FrameNode::kInvalidFrameIndex) {
- if (current_frame == begin_frame) {
- // We're at the top node and we matched all backtrace frames,
- // i.e. we successfully matched the backtrace.
- return true;
- }
- break;
- }
- }
-
- return false;
-}
-
-int StackFrameDeduplicator::Insert(const StackFrame* begin_frame,
- const StackFrame* end_frame) {
- if (begin_frame == end_frame) {
- return FrameNode::kInvalidFrameIndex;
- }
-
- size_t backtrace_hash = HashBacktrace(begin_frame, end_frame);
-
- // Check if we know about this backtrace.
- auto backtrace_it = backtrace_lookup_table_.find(backtrace_hash);
- if (backtrace_it != backtrace_lookup_table_.end()) {
- int backtrace_index = backtrace_it->second;
- if (Match(backtrace_index, begin_frame, end_frame)) {
- return backtrace_index;
- }
- }
-
- int frame_index = FrameNode::kInvalidFrameIndex;
- base::flat_map<StackFrame, int>* nodes = &roots_;
-
- // Loop through the frames, early out when a frame is null.
- for (const StackFrame* it = begin_frame; it != end_frame; it++) {
- StackFrame frame = *it;
-
- auto node = nodes->find(frame);
- if (node == nodes->end()) {
- // There is no tree node for this frame yet, create it. The parent node
- // is the node associated with the previous frame.
- FrameNode frame_node(frame, frame_index);
-
- // The new frame node will be appended, so its index is the current size
- // of the vector.
- frame_index = static_cast<int>(frames_.size());
-
- // Add the node to the trie so it will be found next time.
- nodes->insert(std::make_pair(frame, frame_index));
-
- // Append the node after modifying |nodes|, because the |frames_| vector
- // might need to resize, and this invalidates the |nodes| pointer.
- frames_.push_back(frame_node);
- } else {
- // A tree node for this frame exists. Look for the next one.
- frame_index = node->second;
- }
-
- nodes = &frames_[frame_index].children;
- }
-
- // Remember the backtrace.
- backtrace_lookup_table_[backtrace_hash] = frame_index;
-
- return frame_index;
-}
-
-void StackFrameDeduplicator::AppendAsTraceFormat(std::string* out) const {
- TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("memory-infra"),
- "StackFrameDeduplicator::AppendAsTraceFormat");
- out->append("{"); // Begin the |stackFrames| dictionary.
-
- int i = 0;
- auto frame_node = begin();
- auto it_end = end();
- std::string stringify_buffer;
-
- while (frame_node != it_end) {
- // The |stackFrames| format is a dictionary, not an array, so the
- // keys are stringified indices. Write the index manually, then use
- // |TracedValue| to format the object. This is to avoid building the
- // entire dictionary as a |TracedValue| in memory.
- SStringPrintf(&stringify_buffer, "\"%d\":", i);
- out->append(stringify_buffer);
-
- std::unique_ptr<TracedValue> frame_node_value(new TracedValue);
- const StackFrame& frame = frame_node->frame;
- switch (frame.type) {
- case StackFrame::Type::TRACE_EVENT_NAME:
- frame_node_value->SetString("name",
- static_cast<const char*>(frame.value));
- break;
- case StackFrame::Type::THREAD_NAME:
- SStringPrintf(&stringify_buffer,
- "[Thread: %s]",
- static_cast<const char*>(frame.value));
- frame_node_value->SetString("name", stringify_buffer);
- break;
- case StackFrame::Type::PROGRAM_COUNTER:
- SStringPrintf(&stringify_buffer,
- "pc:%" PRIxPTR,
- reinterpret_cast<uintptr_t>(frame.value));
- frame_node_value->SetString("name", stringify_buffer);
- break;
- }
- if (frame_node->parent_frame_index != FrameNode::kInvalidFrameIndex) {
- SStringPrintf(&stringify_buffer, "%d", frame_node->parent_frame_index);
- frame_node_value->SetString("parent", stringify_buffer);
- }
- frame_node_value->AppendAsTraceFormat(out);
-
- i++;
- frame_node++;
-
- if (frame_node != it_end)
- out->append(",");
- }
-
- out->append("}"); // End the |stackFrames| dictionary.
-}
-
-void StackFrameDeduplicator::EstimateTraceMemoryOverhead(
- TraceEventMemoryOverhead* overhead) {
- size_t memory_usage = EstimateMemoryUsage(frames_) +
- EstimateMemoryUsage(roots_) +
- EstimateMemoryUsage(backtrace_lookup_table_);
- overhead->Add(TraceEventMemoryOverhead::kHeapProfilerStackFrameDeduplicator,
- sizeof(StackFrameDeduplicator) + memory_usage);
-}
-
-} // namespace trace_event
-} // namespace base
diff --git a/base/trace_event/heap_profiler_stack_frame_deduplicator.h b/base/trace_event/heap_profiler_stack_frame_deduplicator.h
deleted file mode 100644
index ac8d895..0000000
--- a/base/trace_event/heap_profiler_stack_frame_deduplicator.h
+++ /dev/null
@@ -1,94 +0,0 @@
-// Copyright 2015 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_HEAP_PROFILER_STACK_FRAME_DEDUPLICATOR_H_
-#define BASE_TRACE_EVENT_HEAP_PROFILER_STACK_FRAME_DEDUPLICATOR_H_
-
-#include <string>
-#include <unordered_map>
-
-#include "base/base_export.h"
-#include "base/containers/circular_deque.h"
-#include "base/containers/flat_map.h"
-#include "base/macros.h"
-#include "base/trace_event/heap_profiler_allocation_context.h"
-#include "base/trace_event/trace_event_impl.h"
-
-namespace base {
-namespace trace_event {
-
-class TraceEventMemoryOverhead;
-
-// A data structure that allows grouping a set of backtraces in a space-
-// efficient manner by creating a call tree and writing it as a set of (node,
-// parent) pairs. The tree nodes reference both parent and children. The parent
-// is referenced by index into |frames_|. The children are referenced via a map
-// of |StackFrame|s to index into |frames_|. So there is a trie for bottum-up
-// lookup of a backtrace for deduplication, and a tree for compact storage in
-// the trace log.
-class BASE_EXPORT StackFrameDeduplicator : public ConvertableToTraceFormat {
- public:
- // A node in the call tree.
- struct FrameNode {
- FrameNode(StackFrame frame, int parent_frame_index);
- FrameNode(const FrameNode& other);
- ~FrameNode();
-
- size_t EstimateMemoryUsage() const;
-
- StackFrame frame;
-
- // The index of the parent stack frame in |frames_|, or kInvalidFrameIndex
- // if there is no parent frame (when it is at the bottom of the call stack).
- int parent_frame_index;
- constexpr static int kInvalidFrameIndex = -1;
-
- // Indices into |frames_| of frames called from the current frame.
- base::flat_map<StackFrame, int> children;
- };
-
- using ConstIterator = base::circular_deque<FrameNode>::const_iterator;
-
- StackFrameDeduplicator();
- ~StackFrameDeduplicator() override;
-
- // Inserts a backtrace where |beginFrame| is a pointer to the bottom frame
- // (e.g. main) and |endFrame| is a pointer past the top frame (most recently
- // called function), and returns the index of its leaf node in |frames_|.
- // Returns -1 if the backtrace is empty.
- int Insert(const StackFrame* beginFrame, const StackFrame* endFrame);
-
- // Iterators over the frame nodes in the call tree.
- ConstIterator begin() const { return frames_.begin(); }
- ConstIterator end() const { return frames_.end(); }
-
- // Writes the |stackFrames| dictionary as defined in https://goo.gl/GerkV8 to
- // the trace log.
- void AppendAsTraceFormat(std::string* out) const override;
-
- // Estimates memory overhead including |sizeof(StackFrameDeduplicator)|.
- void EstimateTraceMemoryOverhead(TraceEventMemoryOverhead* overhead) override;
-
- private:
- // Checks that existing backtrace identified by |frame_index| equals
- // to the one identified by |begin_frame|, |end_frame|.
- bool Match(int frame_index,
- const StackFrame* begin_frame,
- const StackFrame* end_frame) const;
-
- base::flat_map<StackFrame, int> roots_;
- base::circular_deque<FrameNode> frames_;
-
- // {backtrace_hash -> frame_index} map for finding backtraces that are
- // already added. Backtraces themselves are not stored in the map, instead
- // Match() is used on the found frame_index to detect collisions.
- std::unordered_map<size_t, int> backtrace_lookup_table_;
-
- DISALLOW_COPY_AND_ASSIGN(StackFrameDeduplicator);
-};
-
-} // namespace trace_event
-} // namespace base
-
-#endif // BASE_TRACE_EVENT_HEAP_PROFILER_STACK_FRAME_DEDUPLICATOR_H_
diff --git a/base/trace_event/heap_profiler_type_name_deduplicator.cc b/base/trace_event/heap_profiler_type_name_deduplicator.cc
deleted file mode 100644
index 360f239..0000000
--- a/base/trace_event/heap_profiler_type_name_deduplicator.cc
+++ /dev/null
@@ -1,82 +0,0 @@
-// Copyright 2015 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/heap_profiler_type_name_deduplicator.h"
-
-#include <stddef.h>
-#include <stdlib.h>
-#include <string>
-#include <utility>
-
-#include "base/json/string_escape.h"
-#include "base/strings/string_split.h"
-#include "base/strings/stringprintf.h"
-#include "base/trace_event/memory_usage_estimator.h"
-#include "base/trace_event/trace_event.h"
-#include "base/trace_event/trace_event_memory_overhead.h"
-
-namespace base {
-namespace trace_event {
-
-TypeNameDeduplicator::TypeNameDeduplicator() {
- // A null pointer has type ID 0 ("unknown type");
- type_ids_.insert(std::make_pair(nullptr, 0));
-}
-
-TypeNameDeduplicator::~TypeNameDeduplicator() = default;
-
-int TypeNameDeduplicator::Insert(const char* type_name) {
- auto result = type_ids_.insert(std::make_pair(type_name, 0));
- auto& elem = result.first;
- bool did_not_exist_before = result.second;
-
- if (did_not_exist_before) {
- // The type IDs are assigned sequentially and they are zero-based, so
- // |size() - 1| is the ID of the new element.
- elem->second = static_cast<int>(type_ids_.size() - 1);
- }
-
- return elem->second;
-}
-
-void TypeNameDeduplicator::AppendAsTraceFormat(std::string* out) const {
- TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("memory-infra"),
- "TypeNameDeduplicator::AppendAsTraceFormat");
- out->append("{"); // Begin the type names dictionary.
-
- auto it = type_ids_.begin();
- std::string buffer;
-
- // Write the first entry manually; the null pointer must not be dereferenced.
- // (The first entry is the null pointer because a |std::map| is ordered.)
- it++;
- out->append("\"0\":\"[unknown]\"");
-
- for (; it != type_ids_.end(); it++) {
- // Type IDs in the trace are strings, write them as stringified keys of
- // a dictionary.
- SStringPrintf(&buffer, ",\"%d\":", it->second);
-
- // TODO(ssid): crbug.com/594803 the type name is misused for file name in
- // some cases.
- StringPiece type_info = it->first;
-
- // |EscapeJSONString| appends, it does not overwrite |buffer|.
- bool put_in_quotes = true;
- EscapeJSONString(type_info, put_in_quotes, &buffer);
- out->append(buffer);
- }
-
- out->append("}"); // End the type names dictionary.
-}
-
-void TypeNameDeduplicator::EstimateTraceMemoryOverhead(
- TraceEventMemoryOverhead* overhead) {
- size_t memory_usage = EstimateMemoryUsage(type_ids_);
- overhead->Add(TraceEventMemoryOverhead::kHeapProfilerTypeNameDeduplicator,
- sizeof(TypeNameDeduplicator) + memory_usage);
-}
-
-} // namespace trace_event
-} // namespace base
diff --git a/base/trace_event/heap_profiler_type_name_deduplicator.h b/base/trace_event/heap_profiler_type_name_deduplicator.h
deleted file mode 100644
index 2d26c73..0000000
--- a/base/trace_event/heap_profiler_type_name_deduplicator.h
+++ /dev/null
@@ -1,45 +0,0 @@
-// Copyright 2015 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_HEAP_PROFILER_TYPE_NAME_DEDUPLICATOR_H_
-#define BASE_TRACE_EVENT_HEAP_PROFILER_TYPE_NAME_DEDUPLICATOR_H_
-
-#include <map>
-#include <string>
-
-#include "base/base_export.h"
-#include "base/macros.h"
-#include "base/trace_event/trace_event_impl.h"
-
-namespace base {
-namespace trace_event {
-
-class TraceEventMemoryOverhead;
-
-// Data structure that assigns a unique numeric ID to |const char*|s.
-class BASE_EXPORT TypeNameDeduplicator : public ConvertableToTraceFormat {
- public:
- TypeNameDeduplicator();
- ~TypeNameDeduplicator() override;
-
- // Inserts a type name and returns its ID.
- int Insert(const char* type_name);
-
- // Writes the type ID -> type name mapping to the trace log.
- void AppendAsTraceFormat(std::string* out) const override;
-
- // Estimates memory overhead including |sizeof(TypeNameDeduplicator)|.
- void EstimateTraceMemoryOverhead(TraceEventMemoryOverhead* overhead) override;
-
- private:
- // Map from type name to type ID.
- std::map<const char*, int> type_ids_;
-
- DISALLOW_COPY_AND_ASSIGN(TypeNameDeduplicator);
-};
-
-} // namespace trace_event
-} // namespace base
-
-#endif // BASE_TRACE_EVENT_HEAP_PROFILER_TYPE_NAME_DEDUPLICATOR_H_
diff --git a/base/trace_event/java_heap_dump_provider_android.cc b/base/trace_event/java_heap_dump_provider_android.cc
deleted file mode 100644
index 684f730..0000000
--- a/base/trace_event/java_heap_dump_provider_android.cc
+++ /dev/null
@@ -1,47 +0,0 @@
-// Copyright 2015 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/java_heap_dump_provider_android.h"
-
-#include "base/android/java_runtime.h"
-#include "base/trace_event/process_memory_dump.h"
-
-namespace base {
-namespace trace_event {
-
-// static
-JavaHeapDumpProvider* JavaHeapDumpProvider::GetInstance() {
- return Singleton<JavaHeapDumpProvider,
- LeakySingletonTraits<JavaHeapDumpProvider>>::get();
-}
-
-JavaHeapDumpProvider::JavaHeapDumpProvider() {
-}
-
-JavaHeapDumpProvider::~JavaHeapDumpProvider() {
-}
-
-// Called at trace dump point time. Creates a snapshot with the memory counters
-// for the current process.
-bool JavaHeapDumpProvider::OnMemoryDump(const MemoryDumpArgs& args,
- ProcessMemoryDump* pmd) {
- // These numbers come from java.lang.Runtime stats.
- long total_heap_size = 0;
- long free_heap_size = 0;
- android::JavaRuntime::GetMemoryUsage(&total_heap_size, &free_heap_size);
-
- MemoryAllocatorDump* outer_dump = pmd->CreateAllocatorDump("java_heap");
- outer_dump->AddScalar(MemoryAllocatorDump::kNameSize,
- MemoryAllocatorDump::kUnitsBytes, total_heap_size);
-
- MemoryAllocatorDump* inner_dump =
- pmd->CreateAllocatorDump("java_heap/allocated_objects");
- inner_dump->AddScalar(MemoryAllocatorDump::kNameSize,
- MemoryAllocatorDump::kUnitsBytes,
- total_heap_size - free_heap_size);
- return true;
-}
-
-} // namespace trace_event
-} // namespace base
diff --git a/base/trace_event/java_heap_dump_provider_android.h b/base/trace_event/java_heap_dump_provider_android.h
deleted file mode 100644
index b9f2333..0000000
--- a/base/trace_event/java_heap_dump_provider_android.h
+++ /dev/null
@@ -1,36 +0,0 @@
-// Copyright 2015 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_JAVA_HEAP_DUMP_PROVIDER_ANDROID_H_
-#define BASE_TRACE_EVENT_JAVA_HEAP_DUMP_PROVIDER_ANDROID_H_
-
-#include "base/macros.h"
-#include "base/memory/singleton.h"
-#include "base/trace_event/memory_dump_provider.h"
-
-namespace base {
-namespace trace_event {
-
-// Dump provider which collects process-wide memory stats.
-class BASE_EXPORT JavaHeapDumpProvider : public MemoryDumpProvider {
- public:
- static JavaHeapDumpProvider* GetInstance();
-
- // MemoryDumpProvider implementation.
- bool OnMemoryDump(const MemoryDumpArgs& args,
- ProcessMemoryDump* pmd) override;
-
- private:
- friend struct DefaultSingletonTraits<JavaHeapDumpProvider>;
-
- JavaHeapDumpProvider();
- ~JavaHeapDumpProvider() override;
-
- DISALLOW_COPY_AND_ASSIGN(JavaHeapDumpProvider);
-};
-
-} // namespace trace_event
-} // namespace base
-
-#endif // BASE_TRACE_EVENT_JAVA_HEAP_DUMP_PROVIDER_ANDROID_H_
diff --git a/base/trace_event/malloc_dump_provider.cc b/base/trace_event/malloc_dump_provider.cc
deleted file mode 100644
index 04a4dd5..0000000
--- a/base/trace_event/malloc_dump_provider.cc
+++ /dev/null
@@ -1,188 +0,0 @@
-// Copyright 2015 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/malloc_dump_provider.h"
-
-#include <stddef.h>
-
-#include <unordered_map>
-
-#include "base/allocator/allocator_extension.h"
-#include "base/debug/profiler.h"
-#include "base/trace_event/process_memory_dump.h"
-#include "base/trace_event/trace_event_argument.h"
-#include "build_config.h"
-
-#if defined(OS_MACOSX)
-#include <malloc/malloc.h>
-#else
-#include <malloc.h>
-#endif
-#if defined(OS_WIN)
-#include <windows.h>
-#endif
-
-namespace base {
-namespace trace_event {
-
-namespace {
-#if defined(OS_WIN)
-// A structure containing some information about a given heap.
-struct WinHeapInfo {
- size_t committed_size;
- size_t uncommitted_size;
- size_t allocated_size;
- size_t block_count;
-};
-
-// NOTE: crbug.com/665516
-// Unfortunately, there is no safe way to collect information from secondary
-// heaps due to limitations and racy nature of this piece of WinAPI.
-void WinHeapMemoryDumpImpl(WinHeapInfo* crt_heap_info) {
- // Iterate through whichever heap our CRT is using.
- HANDLE crt_heap = reinterpret_cast<HANDLE>(_get_heap_handle());
- ::HeapLock(crt_heap);
- PROCESS_HEAP_ENTRY heap_entry;
- heap_entry.lpData = nullptr;
- // Walk over all the entries in the main heap.
- while (::HeapWalk(crt_heap, &heap_entry) != FALSE) {
- if ((heap_entry.wFlags & PROCESS_HEAP_ENTRY_BUSY) != 0) {
- crt_heap_info->allocated_size += heap_entry.cbData;
- crt_heap_info->block_count++;
- } else if ((heap_entry.wFlags & PROCESS_HEAP_REGION) != 0) {
- crt_heap_info->committed_size += heap_entry.Region.dwCommittedSize;
- crt_heap_info->uncommitted_size += heap_entry.Region.dwUnCommittedSize;
- }
- }
- CHECK(::HeapUnlock(crt_heap) == TRUE);
-}
-#endif // defined(OS_WIN)
-} // namespace
-
-// static
-const char MallocDumpProvider::kAllocatedObjects[] = "malloc/allocated_objects";
-
-// static
-MallocDumpProvider* MallocDumpProvider::GetInstance() {
- return Singleton<MallocDumpProvider,
- LeakySingletonTraits<MallocDumpProvider>>::get();
-}
-
-MallocDumpProvider::MallocDumpProvider() = default;
-MallocDumpProvider::~MallocDumpProvider() = default;
-
-// Called at trace dump point time. Creates a snapshot the memory counters for
-// the current process.
-bool MallocDumpProvider::OnMemoryDump(const MemoryDumpArgs& args,
- ProcessMemoryDump* pmd) {
- {
- base::AutoLock auto_lock(emit_metrics_on_memory_dump_lock_);
- if (!emit_metrics_on_memory_dump_)
- return true;
- }
-
- size_t total_virtual_size = 0;
- size_t resident_size = 0;
- size_t allocated_objects_size = 0;
- size_t allocated_objects_count = 0;
-#if defined(USE_TCMALLOC)
- bool res =
- allocator::GetNumericProperty("generic.heap_size", &total_virtual_size);
- DCHECK(res);
- res = allocator::GetNumericProperty("generic.total_physical_bytes",
- &resident_size);
- DCHECK(res);
- res = allocator::GetNumericProperty("generic.current_allocated_bytes",
- &allocated_objects_size);
- DCHECK(res);
-#elif defined(OS_MACOSX) || defined(OS_IOS)
- malloc_statistics_t stats = {0};
- malloc_zone_statistics(nullptr, &stats);
- total_virtual_size = stats.size_allocated;
- allocated_objects_size = stats.size_in_use;
-
- // Resident size is approximated pretty well by stats.max_size_in_use.
- // However, on macOS, freed blocks are both resident and reusable, which is
- // semantically equivalent to deallocated. The implementation of libmalloc
- // will also only hold a fixed number of freed regions before actually
- // starting to deallocate them, so stats.max_size_in_use is also not
- // representative of the peak size. As a result, stats.max_size_in_use is
- // typically somewhere between actually resident [non-reusable] pages, and
- // peak size. This is not very useful, so we just use stats.size_in_use for
- // resident_size, even though it's an underestimate and fails to account for
- // fragmentation. See
- // https://bugs.chromium.org/p/chromium/issues/detail?id=695263#c1.
- resident_size = stats.size_in_use;
-#elif defined(OS_WIN)
- // This is too expensive on Windows, crbug.com/780735.
- if (args.level_of_detail == MemoryDumpLevelOfDetail::DETAILED) {
- WinHeapInfo main_heap_info = {};
- WinHeapMemoryDumpImpl(&main_heap_info);
- total_virtual_size =
- main_heap_info.committed_size + main_heap_info.uncommitted_size;
- // Resident size is approximated with committed heap size. Note that it is
- // possible to do this with better accuracy on windows by intersecting the
- // working set with the virtual memory ranges occuipied by the heap. It's
- // not clear that this is worth it, as it's fairly expensive to do.
- resident_size = main_heap_info.committed_size;
- allocated_objects_size = main_heap_info.allocated_size;
- allocated_objects_count = main_heap_info.block_count;
- }
-#elif defined(OS_FUCHSIA)
-// TODO(fuchsia): Port, see https://crbug.com/706592.
-#else
- struct mallinfo info = mallinfo();
- DCHECK_GE(info.arena + info.hblkhd, info.uordblks);
-
- // In case of Android's jemalloc |arena| is 0 and the outer pages size is
- // reported by |hblkhd|. In case of dlmalloc the total is given by
- // |arena| + |hblkhd|. For more details see link: http://goo.gl/fMR8lF.
- total_virtual_size = info.arena + info.hblkhd;
- resident_size = info.uordblks;
-
- // Total allocated space is given by |uordblks|.
- allocated_objects_size = info.uordblks;
-#endif
-
- MemoryAllocatorDump* outer_dump = pmd->CreateAllocatorDump("malloc");
- outer_dump->AddScalar("virtual_size", MemoryAllocatorDump::kUnitsBytes,
- total_virtual_size);
- outer_dump->AddScalar(MemoryAllocatorDump::kNameSize,
- MemoryAllocatorDump::kUnitsBytes, resident_size);
-
- MemoryAllocatorDump* inner_dump = pmd->CreateAllocatorDump(kAllocatedObjects);
- inner_dump->AddScalar(MemoryAllocatorDump::kNameSize,
- MemoryAllocatorDump::kUnitsBytes,
- allocated_objects_size);
- if (allocated_objects_count != 0) {
- inner_dump->AddScalar(MemoryAllocatorDump::kNameObjectCount,
- MemoryAllocatorDump::kUnitsObjects,
- allocated_objects_count);
- }
-
- if (resident_size > allocated_objects_size) {
- // Explicitly specify why is extra memory resident. In tcmalloc it accounts
- // for free lists and caches. In mac and ios it accounts for the
- // fragmentation and metadata.
- MemoryAllocatorDump* other_dump =
- pmd->CreateAllocatorDump("malloc/metadata_fragmentation_caches");
- other_dump->AddScalar(MemoryAllocatorDump::kNameSize,
- MemoryAllocatorDump::kUnitsBytes,
- resident_size - allocated_objects_size);
- }
- return true;
-}
-
-void MallocDumpProvider::EnableMetrics() {
- base::AutoLock auto_lock(emit_metrics_on_memory_dump_lock_);
- emit_metrics_on_memory_dump_ = true;
-}
-
-void MallocDumpProvider::DisableMetrics() {
- base::AutoLock auto_lock(emit_metrics_on_memory_dump_lock_);
- emit_metrics_on_memory_dump_ = false;
-}
-
-} // namespace trace_event
-} // namespace base
diff --git a/base/trace_event/malloc_dump_provider.h b/base/trace_event/malloc_dump_provider.h
deleted file mode 100644
index 726c382..0000000
--- a/base/trace_event/malloc_dump_provider.h
+++ /dev/null
@@ -1,56 +0,0 @@
-// Copyright 2015 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_MALLOC_DUMP_PROVIDER_H_
-#define BASE_TRACE_EVENT_MALLOC_DUMP_PROVIDER_H_
-
-#include "base/macros.h"
-#include "base/memory/singleton.h"
-#include "base/synchronization/lock.h"
-#include "base/trace_event/memory_dump_provider.h"
-#include "build_config.h"
-
-#if defined(OS_LINUX) || defined(OS_ANDROID) || defined(OS_WIN) || \
- (defined(OS_MACOSX) && !defined(OS_IOS))
-#define MALLOC_MEMORY_TRACING_SUPPORTED
-#endif
-
-namespace base {
-namespace trace_event {
-
-// Dump provider which collects process-wide memory stats.
-class BASE_EXPORT MallocDumpProvider : public MemoryDumpProvider {
- public:
- // Name of the allocated_objects dump. Use this to declare suballocator dumps
- // from other dump providers.
- static const char kAllocatedObjects[];
-
- static MallocDumpProvider* GetInstance();
-
- // MemoryDumpProvider implementation.
- bool OnMemoryDump(const MemoryDumpArgs& args,
- ProcessMemoryDump* pmd) override;
-
- // Used by out-of-process heap-profiling. When malloc is profiled by an
- // external process, that process will be responsible for emitting metrics on
- // behalf of this one. Thus, MallocDumpProvider should not do anything.
- void EnableMetrics();
- void DisableMetrics();
-
- private:
- friend struct DefaultSingletonTraits<MallocDumpProvider>;
-
- MallocDumpProvider();
- ~MallocDumpProvider() override;
-
- bool emit_metrics_on_memory_dump_ = true;
- base::Lock emit_metrics_on_memory_dump_lock_;
-
- DISALLOW_COPY_AND_ASSIGN(MallocDumpProvider);
-};
-
-} // namespace trace_event
-} // namespace base
-
-#endif // BASE_TRACE_EVENT_MALLOC_DUMP_PROVIDER_H_
diff --git a/base/trace_event/memory_allocator_dump.cc b/base/trace_event/memory_allocator_dump.cc
deleted file mode 100644
index 5260a73..0000000
--- a/base/trace_event/memory_allocator_dump.cc
+++ /dev/null
@@ -1,148 +0,0 @@
-// Copyright 2015 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/memory_allocator_dump.h"
-
-#include <string.h>
-
-#include "base/format_macros.h"
-#include "base/memory/ptr_util.h"
-#include "base/strings/stringprintf.h"
-#include "base/trace_event/memory_dump_manager.h"
-#include "base/trace_event/memory_dump_provider.h"
-#include "base/trace_event/process_memory_dump.h"
-#include "base/trace_event/trace_event_argument.h"
-#include "base/values.h"
-
-namespace base {
-namespace trace_event {
-
-const char MemoryAllocatorDump::kNameSize[] = "size";
-const char MemoryAllocatorDump::kNameObjectCount[] = "object_count";
-const char MemoryAllocatorDump::kTypeScalar[] = "scalar";
-const char MemoryAllocatorDump::kTypeString[] = "string";
-const char MemoryAllocatorDump::kUnitsBytes[] = "bytes";
-const char MemoryAllocatorDump::kUnitsObjects[] = "objects";
-
-MemoryAllocatorDump::MemoryAllocatorDump(
- const std::string& absolute_name,
- MemoryDumpLevelOfDetail level_of_detail,
- const MemoryAllocatorDumpGuid& guid)
- : absolute_name_(absolute_name),
- guid_(guid),
- level_of_detail_(level_of_detail),
- flags_(Flags::DEFAULT) {
- // The |absolute_name| cannot be empty.
- DCHECK(!absolute_name.empty());
-
- // The |absolute_name| can contain slash separator, but not leading or
- // trailing ones.
- DCHECK(absolute_name[0] != '/' && *absolute_name.rbegin() != '/');
-}
-
-MemoryAllocatorDump::~MemoryAllocatorDump() = default;
-
-void MemoryAllocatorDump::AddScalar(const char* name,
- const char* units,
- uint64_t value) {
- entries_.emplace_back(name, units, value);
-}
-
-void MemoryAllocatorDump::AddString(const char* name,
- const char* units,
- const std::string& value) {
- // String attributes are disabled in background mode.
- if (level_of_detail_ == MemoryDumpLevelOfDetail::BACKGROUND) {
- NOTREACHED();
- return;
- }
- entries_.emplace_back(name, units, value);
-}
-
-void MemoryAllocatorDump::AsValueInto(TracedValue* value) const {
- std::string string_conversion_buffer;
- value->BeginDictionaryWithCopiedName(absolute_name_);
- value->SetString("guid", guid_.ToString());
- value->BeginDictionary("attrs");
-
- for (const Entry& entry : entries_) {
- value->BeginDictionaryWithCopiedName(entry.name);
- switch (entry.entry_type) {
- case Entry::kUint64:
- SStringPrintf(&string_conversion_buffer, "%" PRIx64,
- entry.value_uint64);
- value->SetString("type", kTypeScalar);
- value->SetString("units", entry.units);
- value->SetString("value", string_conversion_buffer);
- break;
- case Entry::kString:
- value->SetString("type", kTypeString);
- value->SetString("units", entry.units);
- value->SetString("value", entry.value_string);
- break;
- }
- value->EndDictionary();
- }
- value->EndDictionary(); // "attrs": { ... }
- if (flags_)
- value->SetInteger("flags", flags_);
- value->EndDictionary(); // "allocator_name/heap_subheap": { ... }
-}
-
-uint64_t MemoryAllocatorDump::GetSizeInternal() const {
- if (cached_size_.has_value())
- return *cached_size_;
- for (const auto& entry : entries_) {
- if (entry.entry_type == Entry::kUint64 && entry.units == kUnitsBytes &&
- strcmp(entry.name.c_str(), kNameSize) == 0) {
- cached_size_ = entry.value_uint64;
- return entry.value_uint64;
- }
- }
- return 0;
-};
-
-MemoryAllocatorDump::Entry::Entry() : entry_type(kString), value_uint64() {}
-MemoryAllocatorDump::Entry::Entry(MemoryAllocatorDump::Entry&&) noexcept =
- default;
-MemoryAllocatorDump::Entry& MemoryAllocatorDump::Entry::operator=(
- MemoryAllocatorDump::Entry&&) = default;
-MemoryAllocatorDump::Entry::Entry(std::string name,
- std::string units,
- uint64_t value)
- : name(name), units(units), entry_type(kUint64), value_uint64(value) {}
-MemoryAllocatorDump::Entry::Entry(std::string name,
- std::string units,
- std::string value)
- : name(name), units(units), entry_type(kString), value_string(value) {}
-
-bool MemoryAllocatorDump::Entry::operator==(const Entry& rhs) const {
- if (!(name == rhs.name && units == rhs.units && entry_type == rhs.entry_type))
- return false;
- switch (entry_type) {
- case EntryType::kUint64:
- return value_uint64 == rhs.value_uint64;
- case EntryType::kString:
- return value_string == rhs.value_string;
- }
- NOTREACHED();
- return false;
-}
-
-void PrintTo(const MemoryAllocatorDump::Entry& entry, std::ostream* out) {
- switch (entry.entry_type) {
- case MemoryAllocatorDump::Entry::EntryType::kUint64:
- *out << "<Entry(\"" << entry.name << "\", \"" << entry.units << "\", "
- << entry.value_uint64 << ")>";
- return;
- case MemoryAllocatorDump::Entry::EntryType::kString:
- *out << "<Entry(\"" << entry.name << "\", \"" << entry.units << "\", \""
- << entry.value_string << "\")>";
- return;
- }
- NOTREACHED();
-}
-
-} // namespace trace_event
-} // namespace base
diff --git a/base/trace_event/memory_allocator_dump.h b/base/trace_event/memory_allocator_dump.h
deleted file mode 100644
index de38afd..0000000
--- a/base/trace_event/memory_allocator_dump.h
+++ /dev/null
@@ -1,153 +0,0 @@
-// Copyright 2015 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_MEMORY_ALLOCATOR_DUMP_H_
-#define BASE_TRACE_EVENT_MEMORY_ALLOCATOR_DUMP_H_
-
-#include <stdint.h>
-
-#include <memory>
-#include <ostream>
-#include <string>
-
-#include "base/base_export.h"
-#include "base/gtest_prod_util.h"
-#include "base/logging.h"
-#include "base/macros.h"
-#include "base/optional.h"
-#include "base/trace_event/memory_allocator_dump_guid.h"
-#include "base/trace_event/memory_dump_request_args.h"
-#include "base/trace_event/trace_event_argument.h"
-#include "base/unguessable_token.h"
-#include "base/values.h"
-
-namespace base {
-namespace trace_event {
-
-class ProcessMemoryDump;
-class TracedValue;
-
-// Data model for user-land memory allocator dumps.
-class BASE_EXPORT MemoryAllocatorDump {
- public:
- enum Flags {
- DEFAULT = 0,
-
- // A dump marked weak will be discarded by TraceViewer.
- WEAK = 1 << 0,
- };
-
- // In the TraceViewer UI table each MemoryAllocatorDump becomes
- // a row and each Entry generates a column (if it doesn't already
- // exist).
- struct BASE_EXPORT Entry {
- enum EntryType {
- kUint64,
- kString,
- };
-
- // By design name, units and value_string are always coming from
- // indefinitely lived const char* strings, the only reason we copy
- // them into a std::string is to handle Mojo (de)serialization.
- // TODO(hjd): Investigate optimization (e.g. using StringPiece).
- Entry(); // Only for deserialization.
- Entry(std::string name, std::string units, uint64_t value);
- Entry(std::string name, std::string units, std::string value);
- Entry(Entry&& other) noexcept;
- Entry& operator=(Entry&& other);
- bool operator==(const Entry& rhs) const;
-
- std::string name;
- std::string units;
-
- EntryType entry_type;
-
- uint64_t value_uint64;
- std::string value_string;
-
- DISALLOW_COPY_AND_ASSIGN(Entry);
- };
-
- MemoryAllocatorDump(const std::string& absolute_name,
- MemoryDumpLevelOfDetail,
- const MemoryAllocatorDumpGuid&);
- ~MemoryAllocatorDump();
-
- // Standard attribute |name|s for the AddScalar and AddString() methods.
- static const char kNameSize[]; // To represent allocated space.
- static const char kNameObjectCount[]; // To represent number of objects.
-
- // Standard attribute |unit|s for the AddScalar and AddString() methods.
- static const char kUnitsBytes[]; // Unit name to represent bytes.
- static const char kUnitsObjects[]; // Unit name to represent #objects.
-
- // Constants used only internally and by tests.
- static const char kTypeScalar[]; // Type name for scalar attributes.
- static const char kTypeString[]; // Type name for string attributes.
-
- // Setters for scalar attributes. Some examples:
- // - "size" column (all dumps are expected to have at least this one):
- // AddScalar(kNameSize, kUnitsBytes, 1234);
- // - Some extra-column reporting internal details of the subsystem:
- // AddScalar("number_of_freelist_entries", kUnitsObjects, 42)
- // - Other informational column:
- // AddString("kitten", "name", "shadow");
- void AddScalar(const char* name, const char* units, uint64_t value);
- void AddString(const char* name, const char* units, const std::string& value);
-
- // Absolute name, unique within the scope of an entire ProcessMemoryDump.
- const std::string& absolute_name() const { return absolute_name_; }
-
- // Called at trace generation time to populate the TracedValue.
- void AsValueInto(TracedValue* value) const;
-
- // Get the size for this dump.
- // The size is the value set with AddScalar(kNameSize, kUnitsBytes, size);
- // TODO(hjd): this should return an Optional<uint64_t>.
- uint64_t GetSizeInternal() const;
-
- MemoryDumpLevelOfDetail level_of_detail() const { return level_of_detail_; }
-
- // Use enum Flags to set values.
- void set_flags(int flags) { flags_ |= flags; }
- void clear_flags(int flags) { flags_ &= ~flags; }
- int flags() const { return flags_; }
-
- // |guid| is an optional global dump identifier, unique across all processes
- // within the scope of a global dump. It is only required when using the
- // graph APIs (see TODO_method_name) to express retention / suballocation or
- // cross process sharing. See crbug.com/492102 for design docs.
- // Subsequent MemoryAllocatorDump(s) with the same |absolute_name| are
- // expected to have the same guid.
- const MemoryAllocatorDumpGuid& guid() const { return guid_; }
-
- const std::vector<Entry>& entries() const { return entries_; }
-
- // Only for mojo serialization, which can mutate the collection.
- std::vector<Entry>* mutable_entries_for_serialization() const {
- cached_size_.reset(); // The caller can mutate the collection.
-
- // Mojo takes a const input argument even for move-only types that can be
- // mutate while serializing (like this one). Hence the const_cast.
- return const_cast<std::vector<Entry>*>(&entries_);
- }
-
- private:
- const std::string absolute_name_;
- MemoryAllocatorDumpGuid guid_;
- MemoryDumpLevelOfDetail level_of_detail_;
- int flags_; // See enum Flags.
- mutable Optional<uint64_t> cached_size_; // Lazy, for GetSizeInternal().
- std::vector<Entry> entries_;
-
- DISALLOW_COPY_AND_ASSIGN(MemoryAllocatorDump);
-};
-
-// This is required by gtest to print a readable output on test failures.
-void BASE_EXPORT PrintTo(const MemoryAllocatorDump::Entry&, std::ostream*);
-
-} // namespace trace_event
-} // namespace base
-
-#endif // BASE_TRACE_EVENT_MEMORY_ALLOCATOR_DUMP_H_
diff --git a/base/trace_event/memory_allocator_dump_guid.cc b/base/trace_event/memory_allocator_dump_guid.cc
deleted file mode 100644
index 08ac677..0000000
--- a/base/trace_event/memory_allocator_dump_guid.cc
+++ /dev/null
@@ -1,40 +0,0 @@
-// Copyright 2015 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/memory_allocator_dump_guid.h"
-
-#include "base/format_macros.h"
-#include "base/sha1.h"
-#include "base/strings/stringprintf.h"
-
-namespace base {
-namespace trace_event {
-
-namespace {
-
-uint64_t HashString(const std::string& str) {
- uint64_t hash[(kSHA1Length + sizeof(uint64_t) - 1) / sizeof(uint64_t)] = {0};
- SHA1HashBytes(reinterpret_cast<const unsigned char*>(str.data()), str.size(),
- reinterpret_cast<unsigned char*>(hash));
- return hash[0];
-}
-
-} // namespace
-
-MemoryAllocatorDumpGuid::MemoryAllocatorDumpGuid(uint64_t guid) : guid_(guid) {}
-
-MemoryAllocatorDumpGuid::MemoryAllocatorDumpGuid()
- : MemoryAllocatorDumpGuid(0u) {
-}
-
-MemoryAllocatorDumpGuid::MemoryAllocatorDumpGuid(const std::string& guid_str)
- : MemoryAllocatorDumpGuid(HashString(guid_str)) {
-}
-
-std::string MemoryAllocatorDumpGuid::ToString() const {
- return StringPrintf("%" PRIx64, guid_);
-}
-
-} // namespace trace_event
-} // namespace base
diff --git a/base/trace_event/memory_allocator_dump_guid.h b/base/trace_event/memory_allocator_dump_guid.h
deleted file mode 100644
index 2a420a2..0000000
--- a/base/trace_event/memory_allocator_dump_guid.h
+++ /dev/null
@@ -1,55 +0,0 @@
-// Copyright 2015 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_MEMORY_ALLOCATOR_DUMP_GUID_H_
-#define BASE_TRACE_EVENT_MEMORY_ALLOCATOR_DUMP_GUID_H_
-
-#include <stdint.h>
-
-#include <string>
-
-#include "base/base_export.h"
-
-namespace base {
-namespace trace_event {
-
-class BASE_EXPORT MemoryAllocatorDumpGuid {
- public:
- MemoryAllocatorDumpGuid();
- explicit MemoryAllocatorDumpGuid(uint64_t guid);
-
- // Utility ctor to hash a GUID if the caller prefers a string. The caller
- // still has to ensure that |guid_str| is unique, per snapshot, within the
- // global scope of all the traced processes.
- explicit MemoryAllocatorDumpGuid(const std::string& guid_str);
-
- uint64_t ToUint64() const { return guid_; }
-
- // Returns a (hex-encoded) string representation of the guid.
- std::string ToString() const;
-
- bool empty() const { return guid_ == 0u; }
-
- bool operator==(const MemoryAllocatorDumpGuid& other) const {
- return guid_ == other.guid_;
- }
-
- bool operator!=(const MemoryAllocatorDumpGuid& other) const {
- return !(*this == other);
- }
-
- bool operator<(const MemoryAllocatorDumpGuid& other) const {
- return guid_ < other.guid_;
- }
-
- private:
- uint64_t guid_;
-
- // Deliberately copy-able.
-};
-
-} // namespace trace_event
-} // namespace base
-
-#endif // BASE_TRACE_EVENT_MEMORY_ALLOCATOR_DUMP_GUID_H_
diff --git a/base/trace_event/memory_dump_manager.cc b/base/trace_event/memory_dump_manager.cc
deleted file mode 100644
index 60ba1bb..0000000
--- a/base/trace_event/memory_dump_manager.cc
+++ /dev/null
@@ -1,762 +0,0 @@
-// Copyright 2015 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/memory_dump_manager.h"
-
-#include <inttypes.h>
-#include <stdio.h>
-
-#include <algorithm>
-#include <memory>
-#include <utility>
-
-#include "base/base_switches.h"
-#include "base/command_line.h"
-#include "base/debug/alias.h"
-#include "base/debug/stack_trace.h"
-#include "base/debug/thread_heap_usage_tracker.h"
-#include "base/memory/ptr_util.h"
-#include "base/sequenced_task_runner.h"
-#include "base/strings/string_util.h"
-#include "base/third_party/dynamic_annotations/dynamic_annotations.h"
-#include "base/threading/thread.h"
-#include "base/threading/thread_task_runner_handle.h"
-#include "base/trace_event/heap_profiler.h"
-#include "base/trace_event/heap_profiler_allocation_context_tracker.h"
-#include "base/trace_event/heap_profiler_event_filter.h"
-#include "base/trace_event/heap_profiler_serialization_state.h"
-#include "base/trace_event/heap_profiler_stack_frame_deduplicator.h"
-#include "base/trace_event/heap_profiler_type_name_deduplicator.h"
-#include "base/trace_event/malloc_dump_provider.h"
-#include "base/trace_event/memory_dump_provider.h"
-#include "base/trace_event/memory_dump_scheduler.h"
-#include "base/trace_event/memory_infra_background_whitelist.h"
-#include "base/trace_event/memory_peak_detector.h"
-#include "base/trace_event/process_memory_dump.h"
-#include "base/trace_event/trace_event.h"
-#include "base/trace_event/trace_event_argument.h"
-#include "build_config.h"
-
-#if defined(OS_ANDROID)
-#include "base/trace_event/java_heap_dump_provider_android.h"
-
-#endif // defined(OS_ANDROID)
-
-namespace base {
-namespace trace_event {
-
-namespace {
-
-const char* const kTraceEventArgNames[] = {"dumps"};
-const unsigned char kTraceEventArgTypes[] = {TRACE_VALUE_TYPE_CONVERTABLE};
-
-MemoryDumpManager* g_memory_dump_manager_for_testing = nullptr;
-
-// Temporary (until peak detector and scheduler are moved outside of here)
-// trampoline function to match the |request_dump_function| passed to Initialize
-// to the callback expected by MemoryPeakDetector and MemoryDumpScheduler.
-// TODO(primiano): remove this.
-void DoGlobalDumpWithoutCallback(
- MemoryDumpManager::RequestGlobalDumpFunction global_dump_fn,
- MemoryDumpType dump_type,
- MemoryDumpLevelOfDetail level_of_detail) {
- global_dump_fn.Run(dump_type, level_of_detail);
-}
-
-// Proxy class which wraps a ConvertableToTraceFormat owned by the
-// |heap_profiler_serialization_state| into a proxy object that can be added to
-// the trace event log. This is to solve the problem that the
-// HeapProfilerSerializationState is refcounted but the tracing subsystem wants
-// a std::unique_ptr<ConvertableToTraceFormat>.
-template <typename T>
-struct SessionStateConvertableProxy : public ConvertableToTraceFormat {
- using GetterFunctPtr = T* (HeapProfilerSerializationState::*)() const;
-
- SessionStateConvertableProxy(scoped_refptr<HeapProfilerSerializationState>
- heap_profiler_serialization_state,
- GetterFunctPtr getter_function)
- : heap_profiler_serialization_state(heap_profiler_serialization_state),
- getter_function(getter_function) {}
-
- void AppendAsTraceFormat(std::string* out) const override {
- return (heap_profiler_serialization_state.get()->*getter_function)()
- ->AppendAsTraceFormat(out);
- }
-
- void EstimateTraceMemoryOverhead(
- TraceEventMemoryOverhead* overhead) override {
- return (heap_profiler_serialization_state.get()->*getter_function)()
- ->EstimateTraceMemoryOverhead(overhead);
- }
-
- scoped_refptr<HeapProfilerSerializationState>
- heap_profiler_serialization_state;
- GetterFunctPtr const getter_function;
-};
-
-void NotifyHeapProfilingEnabledOnMDPThread(
- scoped_refptr<MemoryDumpProviderInfo> mdpinfo,
- bool profiling_enabled) {
- mdpinfo->dump_provider->OnHeapProfilingEnabled(profiling_enabled);
-}
-
-inline bool ShouldEnableMDPAllocatorHooks(HeapProfilingMode mode) {
- return (mode == kHeapProfilingModePseudo) ||
- (mode == kHeapProfilingModeNative) ||
- (mode == kHeapProfilingModeBackground);
-}
-
-} // namespace
-
-// static
-const char* const MemoryDumpManager::kTraceCategory =
- TRACE_DISABLED_BY_DEFAULT("memory-infra");
-
-// static
-const int MemoryDumpManager::kMaxConsecutiveFailuresCount = 3;
-
-// static
-const uint64_t MemoryDumpManager::kInvalidTracingProcessId = 0;
-
-// static
-const char* const MemoryDumpManager::kSystemAllocatorPoolName =
-#if defined(MALLOC_MEMORY_TRACING_SUPPORTED)
- MallocDumpProvider::kAllocatedObjects;
-#else
- nullptr;
-#endif
-
-// static
-MemoryDumpManager* MemoryDumpManager::GetInstance() {
- if (g_memory_dump_manager_for_testing)
- return g_memory_dump_manager_for_testing;
-
- return Singleton<MemoryDumpManager,
- LeakySingletonTraits<MemoryDumpManager>>::get();
-}
-
-// static
-std::unique_ptr<MemoryDumpManager>
-MemoryDumpManager::CreateInstanceForTesting() {
- DCHECK(!g_memory_dump_manager_for_testing);
- std::unique_ptr<MemoryDumpManager> instance(new MemoryDumpManager());
- g_memory_dump_manager_for_testing = instance.get();
- return instance;
-}
-
-MemoryDumpManager::MemoryDumpManager()
- : is_coordinator_(false),
- tracing_process_id_(kInvalidTracingProcessId),
- dumper_registrations_ignored_for_testing_(false),
- heap_profiling_mode_(kHeapProfilingModeDisabled) {}
-
-MemoryDumpManager::~MemoryDumpManager() {
- Thread* dump_thread = nullptr;
- {
- AutoLock lock(lock_);
- if (dump_thread_) {
- dump_thread = dump_thread_.get();
- }
- }
- if (dump_thread) {
- dump_thread->Stop();
- }
- AutoLock lock(lock_);
- dump_thread_.reset();
- g_memory_dump_manager_for_testing = nullptr;
-}
-
-bool MemoryDumpManager::EnableHeapProfiling(HeapProfilingMode profiling_mode) {
- AutoLock lock(lock_);
- heap_profiling_mode_ = kHeapProfilingModeInvalid;
- return false;
-}
-
-HeapProfilingMode MemoryDumpManager::GetHeapProfilingMode() {
- AutoLock lock(lock_);
- return heap_profiling_mode_;
-}
-
-void MemoryDumpManager::Initialize(
- RequestGlobalDumpFunction request_dump_function,
- bool is_coordinator) {
- {
- AutoLock lock(lock_);
- DCHECK(!request_dump_function.is_null());
- DCHECK(!can_request_global_dumps());
- request_dump_function_ = request_dump_function;
- is_coordinator_ = is_coordinator;
- }
-
-// Enable the core dump providers.
-#if defined(MALLOC_MEMORY_TRACING_SUPPORTED)
- base::trace_event::MemoryDumpProvider::Options options;
- options.supports_heap_profiling = true;
- RegisterDumpProvider(MallocDumpProvider::GetInstance(), "Malloc", nullptr,
- options);
-#endif
-
-#if defined(OS_ANDROID)
- RegisterDumpProvider(JavaHeapDumpProvider::GetInstance(), "JavaHeap",
- nullptr);
-#endif
-
- TRACE_EVENT_WARMUP_CATEGORY(kTraceCategory);
-}
-
-void MemoryDumpManager::RegisterDumpProvider(
- MemoryDumpProvider* mdp,
- const char* name,
- scoped_refptr<SingleThreadTaskRunner> task_runner,
- MemoryDumpProvider::Options options) {
- options.dumps_on_single_thread_task_runner = true;
- RegisterDumpProviderInternal(mdp, name, std::move(task_runner), options);
-}
-
-void MemoryDumpManager::RegisterDumpProvider(
- MemoryDumpProvider* mdp,
- const char* name,
- scoped_refptr<SingleThreadTaskRunner> task_runner) {
- // Set |dumps_on_single_thread_task_runner| to true because all providers
- // without task runner are run on dump thread.
- MemoryDumpProvider::Options options;
- options.dumps_on_single_thread_task_runner = true;
- RegisterDumpProviderInternal(mdp, name, std::move(task_runner), options);
-}
-
-void MemoryDumpManager::RegisterDumpProviderWithSequencedTaskRunner(
- MemoryDumpProvider* mdp,
- const char* name,
- scoped_refptr<SequencedTaskRunner> task_runner,
- MemoryDumpProvider::Options options) {
- DCHECK(task_runner);
- options.dumps_on_single_thread_task_runner = false;
- RegisterDumpProviderInternal(mdp, name, std::move(task_runner), options);
-}
-
-void MemoryDumpManager::RegisterDumpProviderInternal(
- MemoryDumpProvider* mdp,
- const char* name,
- scoped_refptr<SequencedTaskRunner> task_runner,
- const MemoryDumpProvider::Options& options) {
- if (dumper_registrations_ignored_for_testing_)
- return;
-
- // Only a handful of MDPs are required to compute the memory metrics. These
- // have small enough performance overhead that it is resonable to run them
- // in the background while the user is doing other things. Those MDPs are
- // 'whitelisted for background mode'.
- bool whitelisted_for_background_mode = IsMemoryDumpProviderWhitelisted(name);
-
- scoped_refptr<MemoryDumpProviderInfo> mdpinfo =
- new MemoryDumpProviderInfo(mdp, name, std::move(task_runner), options,
- whitelisted_for_background_mode);
-
- if (options.is_fast_polling_supported) {
- DCHECK(!mdpinfo->task_runner) << "MemoryDumpProviders capable of fast "
- "polling must NOT be thread bound.";
- }
-
- {
- AutoLock lock(lock_);
- bool already_registered = !dump_providers_.insert(mdpinfo).second;
- // This actually happens in some tests which don't have a clean tear-down
- // path for RenderThreadImpl::Init().
- if (already_registered)
- return;
-
- if (options.is_fast_polling_supported)
- MemoryPeakDetector::GetInstance()->NotifyMemoryDumpProvidersChanged();
-
- if (ShouldEnableMDPAllocatorHooks(heap_profiling_mode_))
- NotifyHeapProfilingEnabledLocked(mdpinfo, true);
- }
-}
-
-void MemoryDumpManager::UnregisterDumpProvider(MemoryDumpProvider* mdp) {
- UnregisterDumpProviderInternal(mdp, false /* delete_async */);
-}
-
-void MemoryDumpManager::UnregisterAndDeleteDumpProviderSoon(
- std::unique_ptr<MemoryDumpProvider> mdp) {
- UnregisterDumpProviderInternal(mdp.release(), true /* delete_async */);
-}
-
-void MemoryDumpManager::UnregisterDumpProviderInternal(
- MemoryDumpProvider* mdp,
- bool take_mdp_ownership_and_delete_async) {
- std::unique_ptr<MemoryDumpProvider> owned_mdp;
- if (take_mdp_ownership_and_delete_async)
- owned_mdp.reset(mdp);
-
- AutoLock lock(lock_);
-
- auto mdp_iter = dump_providers_.begin();
- for (; mdp_iter != dump_providers_.end(); ++mdp_iter) {
- if ((*mdp_iter)->dump_provider == mdp)
- break;
- }
-
- if (mdp_iter == dump_providers_.end())
- return; // Not registered / already unregistered.
-
- if (take_mdp_ownership_and_delete_async) {
- // The MDP will be deleted whenever the MDPInfo struct will, that is either:
- // - At the end of this function, if no dump is in progress.
- // - In ContinueAsyncProcessDump() when MDPInfo is removed from
- // |pending_dump_providers|.
- // - When the provider is removed from other clients (MemoryPeakDetector).
- DCHECK(!(*mdp_iter)->owned_dump_provider);
- (*mdp_iter)->owned_dump_provider = std::move(owned_mdp);
- } else {
- // If you hit this DCHECK, your dump provider has a bug.
- // Unregistration of a MemoryDumpProvider is safe only if:
- // - The MDP has specified a sequenced task runner affinity AND the
- // unregistration happens on the same task runner. So that the MDP cannot
- // unregister and be in the middle of a OnMemoryDump() at the same time.
- // - The MDP has NOT specified a task runner affinity and its ownership is
- // transferred via UnregisterAndDeleteDumpProviderSoon().
- // In all the other cases, it is not possible to guarantee that the
- // unregistration will not race with OnMemoryDump() calls.
- DCHECK((*mdp_iter)->task_runner &&
- (*mdp_iter)->task_runner->RunsTasksInCurrentSequence())
- << "MemoryDumpProvider \"" << (*mdp_iter)->name << "\" attempted to "
- << "unregister itself in a racy way. Please file a crbug.";
- }
-
- if ((*mdp_iter)->options.is_fast_polling_supported) {
- DCHECK(take_mdp_ownership_and_delete_async);
- MemoryPeakDetector::GetInstance()->NotifyMemoryDumpProvidersChanged();
- }
-
- // The MDPInfo instance can still be referenced by the
- // |ProcessMemoryDumpAsyncState.pending_dump_providers|. For this reason
- // the MDPInfo is flagged as disabled. It will cause InvokeOnMemoryDump()
- // to just skip it, without actually invoking the |mdp|, which might be
- // destroyed by the caller soon after this method returns.
- (*mdp_iter)->disabled = true;
- dump_providers_.erase(mdp_iter);
-}
-
-void MemoryDumpManager::GetDumpProvidersForPolling(
- std::vector<scoped_refptr<MemoryDumpProviderInfo>>* providers) {
- DCHECK(providers->empty());
- AutoLock lock(lock_);
- for (const scoped_refptr<MemoryDumpProviderInfo>& mdp : dump_providers_) {
- if (mdp->options.is_fast_polling_supported)
- providers->push_back(mdp);
- }
-}
-
-bool MemoryDumpManager::IsDumpProviderRegisteredForTesting(
- MemoryDumpProvider* provider) {
- AutoLock lock(lock_);
-
- for (const auto& info : dump_providers_) {
- if (info->dump_provider == provider)
- return true;
- }
- return false;
-}
-
-scoped_refptr<base::SequencedTaskRunner>
-MemoryDumpManager::GetOrCreateBgTaskRunnerLocked() {
- lock_.AssertAcquired();
-
- if (dump_thread_)
- return dump_thread_->task_runner();
-
- dump_thread_ = std::make_unique<Thread>("MemoryInfra");
- bool started = dump_thread_->Start();
- CHECK(started);
-
- return dump_thread_->task_runner();
-}
-
-void MemoryDumpManager::CreateProcessDump(
- const MemoryDumpRequestArgs& args,
- const ProcessMemoryDumpCallback& callback) {
- char guid_str[20];
- sprintf(guid_str, "0x%" PRIx64, args.dump_guid);
- TRACE_EVENT_NESTABLE_ASYNC_BEGIN1(kTraceCategory, "ProcessMemoryDump",
- TRACE_ID_LOCAL(args.dump_guid), "dump_guid",
- TRACE_STR_COPY(guid_str));
-
- // If argument filter is enabled then only background mode dumps should be
- // allowed. In case the trace config passed for background tracing session
- // missed the allowed modes argument, it crashes here instead of creating
- // unexpected dumps.
- if (TraceLog::GetInstance()
- ->GetCurrentTraceConfig()
- .IsArgumentFilterEnabled()) {
- CHECK_EQ(MemoryDumpLevelOfDetail::BACKGROUND, args.level_of_detail);
- }
-
- std::unique_ptr<ProcessMemoryDumpAsyncState> pmd_async_state;
- {
- AutoLock lock(lock_);
-
- // MDM could have been disabled by this point destroying
- // |heap_profiler_serialization_state|. If heap profiling is enabled we
- // require session state so if heap profiling is on and session state is
- // absent we fail the dump immediately. If heap profiler is enabled during
- // the dump, then the dump succeeds since the dump was requested before, and
- // the future process dumps will contain heap dumps.
- if (args.dump_type != MemoryDumpType::SUMMARY_ONLY &&
- ShouldEnableMDPAllocatorHooks(heap_profiling_mode_) &&
- !heap_profiler_serialization_state_) {
- callback.Run(false /* success */, args.dump_guid, nullptr);
- return;
- }
-
- pmd_async_state.reset(new ProcessMemoryDumpAsyncState(
- args, dump_providers_, heap_profiler_serialization_state_, callback,
- GetOrCreateBgTaskRunnerLocked()));
-
- // If enabled, holds back the peak detector resetting its estimation window.
- MemoryPeakDetector::GetInstance()->Throttle();
- }
-
- // Start the process dump. This involves task runner hops as specified by the
- // MemoryDumpProvider(s) in RegisterDumpProvider()).
- ContinueAsyncProcessDump(pmd_async_state.release());
-}
-
-// Invokes OnMemoryDump() on all MDPs that are next in the pending list and run
-// on the current sequenced task runner. If the next MDP does not run in current
-// sequenced task runner, then switches to that task runner and continues. All
-// OnMemoryDump() invocations are linearized. |lock_| is used in these functions
-// purely to ensure consistency w.r.t. (un)registrations of |dump_providers_|.
-void MemoryDumpManager::ContinueAsyncProcessDump(
- ProcessMemoryDumpAsyncState* owned_pmd_async_state) {
- HEAP_PROFILER_SCOPED_IGNORE;
- // Initalizes the ThreadLocalEventBuffer to guarantee that the TRACE_EVENTs
- // in the PostTask below don't end up registering their own dump providers
- // (for discounting trace memory overhead) while holding the |lock_|.
- TraceLog::GetInstance()->InitializeThreadLocalEventBufferIfSupported();
-
- // In theory |owned_pmd_async_state| should be a unique_ptr. The only reason
- // why it isn't is because of the corner case logic of |did_post_task|
- // above, which needs to take back the ownership of the |pmd_async_state| when
- // the PostTask() fails.
- // Unfortunately, PostTask() destroys the unique_ptr arguments upon failure
- // to prevent accidental leaks. Using a unique_ptr would prevent us to to
- // skip the hop and move on. Hence the manual naked -> unique ptr juggling.
- auto pmd_async_state = WrapUnique(owned_pmd_async_state);
- owned_pmd_async_state = nullptr;
-
- while (!pmd_async_state->pending_dump_providers.empty()) {
- // Read MemoryDumpProviderInfo thread safety considerations in
- // memory_dump_manager.h when accessing |mdpinfo| fields.
- MemoryDumpProviderInfo* mdpinfo =
- pmd_async_state->pending_dump_providers.back().get();
-
- // If we are in background mode, we should invoke only the whitelisted
- // providers. Ignore other providers and continue.
- if (pmd_async_state->req_args.level_of_detail ==
- MemoryDumpLevelOfDetail::BACKGROUND &&
- !mdpinfo->whitelisted_for_background_mode) {
- pmd_async_state->pending_dump_providers.pop_back();
- continue;
- }
-
- // If the dump provider did not specify a task runner affinity, dump on
- // |dump_thread_|.
- scoped_refptr<SequencedTaskRunner> task_runner = mdpinfo->task_runner;
- if (!task_runner) {
- DCHECK(mdpinfo->options.dumps_on_single_thread_task_runner);
- task_runner = pmd_async_state->dump_thread_task_runner;
- DCHECK(task_runner);
- }
-
- // If |RunsTasksInCurrentSequence()| is true then no PostTask is
- // required since we are on the right SequencedTaskRunner.
- if (task_runner->RunsTasksInCurrentSequence()) {
- InvokeOnMemoryDump(mdpinfo, pmd_async_state->process_memory_dump.get());
- pmd_async_state->pending_dump_providers.pop_back();
- continue;
- }
-
- bool did_post_task = task_runner->PostTask(
- FROM_HERE,
- BindOnce(&MemoryDumpManager::ContinueAsyncProcessDump, Unretained(this),
- Unretained(pmd_async_state.get())));
-
- if (did_post_task) {
- // Ownership is tranferred to the posted task.
- ignore_result(pmd_async_state.release());
- return;
- }
-
- // PostTask usually fails only if the process or thread is shut down. So,
- // the dump provider is disabled here. But, don't disable unbound dump
- // providers, since the |dump_thread_| is controlled by MDM.
- if (mdpinfo->task_runner) {
- // A locked access is required to R/W |disabled| (for the
- // UnregisterAndDeleteDumpProviderSoon() case).
- AutoLock lock(lock_);
- mdpinfo->disabled = true;
- }
-
- // PostTask failed. Ignore the dump provider and continue.
- pmd_async_state->pending_dump_providers.pop_back();
- }
-
- FinishAsyncProcessDump(std::move(pmd_async_state));
-}
-
-// This function is called on the right task runner for current MDP. It is
-// either the task runner specified by MDP or |dump_thread_task_runner| if the
-// MDP did not specify task runner. Invokes the dump provider's OnMemoryDump()
-// (unless disabled).
-void MemoryDumpManager::InvokeOnMemoryDump(MemoryDumpProviderInfo* mdpinfo,
- ProcessMemoryDump* pmd) {
- HEAP_PROFILER_SCOPED_IGNORE;
- DCHECK(!mdpinfo->task_runner ||
- mdpinfo->task_runner->RunsTasksInCurrentSequence());
-
- TRACE_EVENT1(kTraceCategory, "MemoryDumpManager::InvokeOnMemoryDump",
- "dump_provider.name", mdpinfo->name);
-
- // Do not add any other TRACE_EVENT macro (or function that might have them)
- // below this point. Under some rare circunstances, they can re-initialize
- // and invalide the current ThreadLocalEventBuffer MDP, making the
- // |should_dump| check below susceptible to TOCTTOU bugs
- // (https://crbug.com/763365).
-
- bool is_thread_bound;
- {
- // A locked access is required to R/W |disabled| (for the
- // UnregisterAndDeleteDumpProviderSoon() case).
- AutoLock lock(lock_);
-
- // Unregister the dump provider if it failed too many times consecutively.
- if (!mdpinfo->disabled &&
- mdpinfo->consecutive_failures >= kMaxConsecutiveFailuresCount) {
- mdpinfo->disabled = true;
- DLOG(ERROR) << "Disabling MemoryDumpProvider \"" << mdpinfo->name
- << "\". Dump failed multiple times consecutively.";
- }
- if (mdpinfo->disabled)
- return;
-
- is_thread_bound = mdpinfo->task_runner != nullptr;
- } // AutoLock lock(lock_);
-
- // Invoke the dump provider.
-
- // A stack allocated string with dump provider name is useful to debug
- // crashes while invoking dump after a |dump_provider| is not unregistered
- // in safe way.
- char provider_name_for_debugging[16];
- strncpy(provider_name_for_debugging, mdpinfo->name,
- sizeof(provider_name_for_debugging) - 1);
- provider_name_for_debugging[sizeof(provider_name_for_debugging) - 1] = '\0';
- base::debug::Alias(provider_name_for_debugging);
-
- ANNOTATE_BENIGN_RACE(&mdpinfo->disabled, "best-effort race detection");
- CHECK(!is_thread_bound ||
- !*(static_cast<volatile bool*>(&mdpinfo->disabled)));
- bool dump_successful =
- mdpinfo->dump_provider->OnMemoryDump(pmd->dump_args(), pmd);
- mdpinfo->consecutive_failures =
- dump_successful ? 0 : mdpinfo->consecutive_failures + 1;
-}
-
-void MemoryDumpManager::FinishAsyncProcessDump(
- std::unique_ptr<ProcessMemoryDumpAsyncState> pmd_async_state) {
- HEAP_PROFILER_SCOPED_IGNORE;
- DCHECK(pmd_async_state->pending_dump_providers.empty());
- const uint64_t dump_guid = pmd_async_state->req_args.dump_guid;
- if (!pmd_async_state->callback_task_runner->BelongsToCurrentThread()) {
- scoped_refptr<SingleThreadTaskRunner> callback_task_runner =
- pmd_async_state->callback_task_runner;
- callback_task_runner->PostTask(
- FROM_HERE, BindOnce(&MemoryDumpManager::FinishAsyncProcessDump,
- Unretained(this), std::move(pmd_async_state)));
- return;
- }
-
- TRACE_EVENT0(kTraceCategory, "MemoryDumpManager::FinishAsyncProcessDump");
-
- // In the general case (allocators and edges) the serialization into the trace
- // buffer is handled by the memory-infra service (see tracing_observer.cc).
- // This special case below deals only with serialization of the heap profiler
- // and is temporary given the upcoming work on the out-of-process heap
- // profiler.
- const auto& args = pmd_async_state->req_args;
- if (!pmd_async_state->process_memory_dump->heap_dumps().empty()) {
- std::unique_ptr<TracedValue> traced_value = std::make_unique<TracedValue>();
- pmd_async_state->process_memory_dump->SerializeHeapProfilerDumpsInto(
- traced_value.get());
-
- traced_value->SetString("level_of_detail",
- base::trace_event::MemoryDumpLevelOfDetailToString(
- args.level_of_detail));
- 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),
- base::trace_event::MemoryDumpTypeToString(args.dump_type),
- trace_event_internal::kGlobalScope, args.dump_guid,
- base::kNullProcessId, 1 /* num_args */, kTraceEventArgNames,
- kTraceEventArgTypes, nullptr /* arg_values */, &event_value,
- TRACE_EVENT_FLAG_HAS_ID);
- }
-
- if (!pmd_async_state->callback.is_null()) {
- pmd_async_state->callback.Run(
- true /* success */, dump_guid,
- std::move(pmd_async_state->process_memory_dump));
- pmd_async_state->callback.Reset();
- }
-
- TRACE_EVENT_NESTABLE_ASYNC_END0(kTraceCategory, "ProcessMemoryDump",
- TRACE_ID_LOCAL(dump_guid));
-}
-
-void MemoryDumpManager::SetupForTracing(
- const TraceConfig::MemoryDumpConfig& memory_dump_config) {
- AutoLock lock(lock_);
- heap_profiler_serialization_state_ = new HeapProfilerSerializationState();
- heap_profiler_serialization_state_
- ->set_heap_profiler_breakdown_threshold_bytes(
- memory_dump_config.heap_profiler_options.breakdown_threshold_bytes);
- InitializeHeapProfilerStateIfNeededLocked();
-
- // At this point we must have the ability to request global dumps.
- DCHECK(can_request_global_dumps());
-
- MemoryDumpScheduler::Config periodic_config;
- bool peak_detector_configured = false;
- for (const auto& trigger : memory_dump_config.triggers) {
- if (trigger.trigger_type == MemoryDumpType::PERIODIC_INTERVAL) {
- if (periodic_config.triggers.empty()) {
- periodic_config.callback =
- BindRepeating(&DoGlobalDumpWithoutCallback, request_dump_function_,
- MemoryDumpType::PERIODIC_INTERVAL);
- }
- periodic_config.triggers.push_back(
- {trigger.level_of_detail, trigger.min_time_between_dumps_ms});
- } else if (trigger.trigger_type == MemoryDumpType::PEAK_MEMORY_USAGE) {
- // At most one peak trigger is allowed.
- CHECK(!peak_detector_configured);
- peak_detector_configured = true;
- MemoryPeakDetector::GetInstance()->Setup(
- BindRepeating(&MemoryDumpManager::GetDumpProvidersForPolling,
- Unretained(this)),
- GetOrCreateBgTaskRunnerLocked(),
- BindRepeating(&DoGlobalDumpWithoutCallback, request_dump_function_,
- MemoryDumpType::PEAK_MEMORY_USAGE,
- trigger.level_of_detail));
-
- MemoryPeakDetector::Config peak_config;
- peak_config.polling_interval_ms = 10;
- peak_config.min_time_between_peaks_ms = trigger.min_time_between_dumps_ms;
- peak_config.enable_verbose_poll_tracing =
- trigger.level_of_detail == MemoryDumpLevelOfDetail::DETAILED;
- MemoryPeakDetector::GetInstance()->Start(peak_config);
-
- // When peak detection is enabled, trigger a dump straight away as it
- // gives a good reference point for analyzing the trace.
- if (is_coordinator_) {
- GetOrCreateBgTaskRunnerLocked()->PostTask(
- FROM_HERE,
- BindOnce(&DoGlobalDumpWithoutCallback, request_dump_function_,
- MemoryDumpType::PEAK_MEMORY_USAGE,
- trigger.level_of_detail));
- }
- }
- }
-
- // Only coordinator process triggers periodic memory dumps.
- if (is_coordinator_ && !periodic_config.triggers.empty()) {
- MemoryDumpScheduler::GetInstance()->Start(periodic_config,
- GetOrCreateBgTaskRunnerLocked());
- }
-}
-
-void MemoryDumpManager::TeardownForTracing() {
- // There might be a memory dump in progress while this happens. Therefore,
- // ensure that the MDM state which depends on the tracing enabled / disabled
- // state is always accessed by the dumping methods holding the |lock_|.
- AutoLock lock(lock_);
-
- MemoryDumpScheduler::GetInstance()->Stop();
- MemoryPeakDetector::GetInstance()->TearDown();
- heap_profiler_serialization_state_ = nullptr;
-}
-
-void MemoryDumpManager::InitializeHeapProfilerStateIfNeededLocked() {
- lock_.AssertAcquired();
- if (!ShouldEnableMDPAllocatorHooks(heap_profiling_mode_) ||
- !heap_profiler_serialization_state_ ||
- heap_profiler_serialization_state_->is_initialized()) {
- return;
- }
- // If heap profiling is enabled, the stack frame deduplicator and type name
- // deduplicator will be in use. Add a metadata events to write the frames
- // and type IDs.
- heap_profiler_serialization_state_->SetStackFrameDeduplicator(
- WrapUnique(new StackFrameDeduplicator));
- heap_profiler_serialization_state_->SetTypeNameDeduplicator(
- WrapUnique(new TypeNameDeduplicator));
-
- TRACE_EVENT_API_ADD_METADATA_EVENT(
- TraceLog::GetCategoryGroupEnabled("__metadata"), "stackFrames",
- "stackFrames",
- std::make_unique<SessionStateConvertableProxy<StackFrameDeduplicator>>(
- heap_profiler_serialization_state_,
- &HeapProfilerSerializationState::stack_frame_deduplicator));
-
- TRACE_EVENT_API_ADD_METADATA_EVENT(
- TraceLog::GetCategoryGroupEnabled("__metadata"), "typeNames", "typeNames",
- std::make_unique<SessionStateConvertableProxy<TypeNameDeduplicator>>(
- heap_profiler_serialization_state_,
- &HeapProfilerSerializationState::type_name_deduplicator));
-}
-
-void MemoryDumpManager::NotifyHeapProfilingEnabledLocked(
- scoped_refptr<MemoryDumpProviderInfo> mdpinfo,
- bool enabled) {
- lock_.AssertAcquired();
- if (!mdpinfo->options.supports_heap_profiling)
- return;
-
- const auto& task_runner = mdpinfo->task_runner
- ? mdpinfo->task_runner
- : GetOrCreateBgTaskRunnerLocked();
- // TODO(ssid): Post tasks only for MDPs that support heap profiling.
- task_runner->PostTask(
- FROM_HERE,
- BindOnce(&NotifyHeapProfilingEnabledOnMDPThread, mdpinfo, enabled));
-}
-
-MemoryDumpManager::ProcessMemoryDumpAsyncState::ProcessMemoryDumpAsyncState(
- MemoryDumpRequestArgs req_args,
- const MemoryDumpProviderInfo::OrderedSet& dump_providers,
- scoped_refptr<HeapProfilerSerializationState>
- heap_profiler_serialization_state_in,
- ProcessMemoryDumpCallback callback,
- scoped_refptr<SequencedTaskRunner> dump_thread_task_runner)
- : req_args(req_args),
- heap_profiler_serialization_state(
- std::move(heap_profiler_serialization_state_in)),
- callback(callback),
- callback_task_runner(ThreadTaskRunnerHandle::Get()),
- dump_thread_task_runner(std::move(dump_thread_task_runner)) {
- pending_dump_providers.reserve(dump_providers.size());
- pending_dump_providers.assign(dump_providers.rbegin(), dump_providers.rend());
- MemoryDumpArgs args = {req_args.level_of_detail, req_args.dump_guid};
- process_memory_dump = std::make_unique<ProcessMemoryDump>(
- heap_profiler_serialization_state, args);
-}
-
-MemoryDumpManager::ProcessMemoryDumpAsyncState::~ProcessMemoryDumpAsyncState() =
- default;
-
-} // namespace trace_event
-} // namespace base
diff --git a/base/trace_event/memory_dump_manager.h b/base/trace_event/memory_dump_manager.h
deleted file mode 100644
index 072a7d6..0000000
--- a/base/trace_event/memory_dump_manager.h
+++ /dev/null
@@ -1,320 +0,0 @@
-// Copyright 2015 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_MEMORY_DUMP_MANAGER_H_
-#define BASE_TRACE_EVENT_MEMORY_DUMP_MANAGER_H_
-
-#include <stdint.h>
-
-#include <map>
-#include <memory>
-#include <unordered_set>
-#include <vector>
-
-#include "base/atomicops.h"
-#include "base/containers/hash_tables.h"
-#include "base/macros.h"
-#include "base/memory/ref_counted.h"
-#include "base/memory/singleton.h"
-#include "base/synchronization/lock.h"
-#include "base/trace_event/memory_allocator_dump.h"
-#include "base/trace_event/memory_dump_provider_info.h"
-#include "base/trace_event/memory_dump_request_args.h"
-#include "base/trace_event/process_memory_dump.h"
-#include "base/trace_event/trace_event.h"
-
-namespace base {
-
-class SequencedTaskRunner;
-class SingleThreadTaskRunner;
-class Thread;
-
-namespace trace_event {
-
-class MemoryDumpProvider;
-class HeapProfilerSerializationState;
-
-enum HeapProfilingMode {
- kHeapProfilingModeDisabled,
- kHeapProfilingModeTaskProfiler, // Per task counters for allocs and frees.
- kHeapProfilingModeBackground, // Pseudo stacks without default filtering.
- kHeapProfilingModePseudo, // Pseudo stacks with default filtering categories.
- kHeapProfilingModeNative, // Native stacks
- kHeapProfilingModeInvalid // Disabled permanently or unsupported.
-};
-
-// This is the interface exposed to the rest of the codebase to deal with
-// memory tracing. The main entry point for clients is represented by
-// RequestDumpPoint(). The extension by Un(RegisterDumpProvider).
-class BASE_EXPORT MemoryDumpManager {
- public:
- using RequestGlobalDumpFunction =
- RepeatingCallback<void(MemoryDumpType, MemoryDumpLevelOfDetail)>;
-
- static const char* const kTraceCategory;
-
- // This value is returned as the tracing id of the child processes by
- // GetTracingProcessId() when tracing is not enabled.
- static const uint64_t kInvalidTracingProcessId;
-
- static MemoryDumpManager* GetInstance();
- static std::unique_ptr<MemoryDumpManager> CreateInstanceForTesting();
-
- // Invoked once per process to listen to trace begin / end events.
- // Initialization can happen after (Un)RegisterMemoryDumpProvider() calls
- // and the MemoryDumpManager guarantees to support this.
- // On the other side, the MemoryDumpManager will not be fully operational
- // (any CreateProcessDump() will return a failure) until initialized.
- // Arguments:
- // is_coordinator: True when current process coordinates the periodic dump
- // triggering.
- // request_dump_function: Function to invoke a global dump. Global dump
- // involves embedder-specific behaviors like multiprocess handshaking.
- // TODO(primiano): this is only required to trigger global dumps from
- // the scheduler and the peak detector. Should be removed once they are
- // both moved out of base.
- void Initialize(RequestGlobalDumpFunction request_dump_function,
- bool is_coordinator);
-
- // (Un)Registers a MemoryDumpProvider instance.
- // Args:
- // - mdp: the MemoryDumpProvider instance to be registered. MemoryDumpManager
- // does NOT take memory ownership of |mdp|, which is expected to either
- // be a singleton or unregister itself.
- // - name: a friendly name (duplicates allowed). Used for debugging and
- // run-time profiling of memory-infra internals. Must be a long-lived
- // C string.
- // - task_runner: either a SingleThreadTaskRunner or SequencedTaskRunner. All
- // the calls to |mdp| will be run on the given |task_runner|. If passed
- // null |mdp| should be able to handle calls on arbitrary threads.
- // - options: extra optional arguments. See memory_dump_provider.h.
- void RegisterDumpProvider(MemoryDumpProvider* mdp,
- const char* name,
- scoped_refptr<SingleThreadTaskRunner> task_runner);
- void RegisterDumpProvider(MemoryDumpProvider* mdp,
- const char* name,
- scoped_refptr<SingleThreadTaskRunner> task_runner,
- MemoryDumpProvider::Options options);
- void RegisterDumpProviderWithSequencedTaskRunner(
- MemoryDumpProvider* mdp,
- const char* name,
- scoped_refptr<SequencedTaskRunner> task_runner,
- MemoryDumpProvider::Options options);
- void UnregisterDumpProvider(MemoryDumpProvider* mdp);
-
- // Unregisters an unbound dump provider and takes care about its deletion
- // asynchronously. Can be used only for for dump providers with no
- // task-runner affinity.
- // This method takes ownership of the dump provider and guarantees that:
- // - The |mdp| will be deleted at some point in the near future.
- // - Its deletion will not happen concurrently with the OnMemoryDump() call.
- // Note that OnMemoryDump() and PollFastMemoryTotal() calls can still happen
- // after this method returns.
- void UnregisterAndDeleteDumpProviderSoon(
- std::unique_ptr<MemoryDumpProvider> mdp);
-
- // Prepare MemoryDumpManager for CreateProcessDump() calls for tracing-related
- // modes (i.e. |level_of_detail| != SUMMARY_ONLY).
- // Also initializes the peak detector, scheduler and heap profiler with the
- // given config.
- void SetupForTracing(const TraceConfig::MemoryDumpConfig&);
-
- // Tear-down tracing related state.
- // Non-tracing modes (e.g. SUMMARY_ONLY) will continue to work.
- void TeardownForTracing();
-
- // Creates a memory dump for the current process and appends it to the trace.
- // |callback| will be invoked asynchronously upon completion on the same
- // thread on which CreateProcessDump() was called. This method should only be
- // used by the memory-infra service while creating a global memory dump.
- void CreateProcessDump(const MemoryDumpRequestArgs& args,
- const ProcessMemoryDumpCallback& callback);
-
- // Enable heap profiling with specified |profiling_mode|.
- // Use kHeapProfilingModeDisabled to disable, but it can't be re-enabled then.
- // Returns true if mode has been *changed* to the desired |profiling_mode|.
- bool EnableHeapProfiling(HeapProfilingMode profiling_mode);
- HeapProfilingMode GetHeapProfilingMode();
-
- // Lets tests see if a dump provider is registered.
- bool IsDumpProviderRegisteredForTesting(MemoryDumpProvider*);
-
- const scoped_refptr<HeapProfilerSerializationState>&
- heap_profiler_serialization_state_for_testing() const {
- return heap_profiler_serialization_state_;
- }
-
- // Returns a unique id for identifying the processes. The id can be
- // retrieved by child processes only when tracing is enabled. This is
- // intended to express cross-process sharing of memory dumps on the
- // child-process side, without having to know its own child process id.
- uint64_t GetTracingProcessId() const { return tracing_process_id_; }
- void set_tracing_process_id(uint64_t tracing_process_id) {
- tracing_process_id_ = tracing_process_id;
- }
-
- // Returns the name for a the allocated_objects dump. Use this to declare
- // suballocator dumps from other dump providers.
- // It will return nullptr if there is no dump provider for the system
- // allocator registered (which is currently the case for Mac OS).
- const char* system_allocator_pool_name() const {
- return kSystemAllocatorPoolName;
- };
-
- // When set to true, calling |RegisterMemoryDumpProvider| is a no-op.
- void set_dumper_registrations_ignored_for_testing(bool ignored) {
- dumper_registrations_ignored_for_testing_ = ignored;
- }
-
- private:
- friend std::default_delete<MemoryDumpManager>; // For the testing instance.
- friend struct DefaultSingletonTraits<MemoryDumpManager>;
- friend class MemoryDumpManagerTest;
- FRIEND_TEST_ALL_PREFIXES(MemoryDumpManagerTest,
- NoStackOverflowWithTooManyMDPs);
-
- // Holds the state of a process memory dump that needs to be carried over
- // across task runners in order to fulfill an asynchronous CreateProcessDump()
- // request. At any time exactly one task runner owns a
- // ProcessMemoryDumpAsyncState.
- struct ProcessMemoryDumpAsyncState {
- ProcessMemoryDumpAsyncState(
- MemoryDumpRequestArgs req_args,
- const MemoryDumpProviderInfo::OrderedSet& dump_providers,
- scoped_refptr<HeapProfilerSerializationState>
- heap_profiler_serialization_state,
- ProcessMemoryDumpCallback callback,
- scoped_refptr<SequencedTaskRunner> dump_thread_task_runner);
- ~ProcessMemoryDumpAsyncState();
-
- // A ProcessMemoryDump to collect data from MemoryDumpProviders.
- std::unique_ptr<ProcessMemoryDump> process_memory_dump;
-
- // The arguments passed to the initial CreateProcessDump() request.
- const MemoryDumpRequestArgs req_args;
-
- // An ordered sequence of dump providers that have to be invoked to complete
- // the dump. This is a copy of |dump_providers_| at the beginning of a dump
- // and becomes empty at the end, when all dump providers have been invoked.
- std::vector<scoped_refptr<MemoryDumpProviderInfo>> pending_dump_providers;
-
- // The HeapProfilerSerializationState object, which is shared by all
- // the ProcessMemoryDump and MemoryAllocatorDump instances through all the
- // tracing session lifetime.
- scoped_refptr<HeapProfilerSerializationState>
- heap_profiler_serialization_state;
-
- // Callback passed to the initial call to CreateProcessDump().
- ProcessMemoryDumpCallback callback;
-
- // The thread on which FinishAsyncProcessDump() (and hence |callback|)
- // should be invoked. This is the thread on which the initial
- // CreateProcessDump() request was called.
- const scoped_refptr<SingleThreadTaskRunner> callback_task_runner;
-
- // The thread on which unbound dump providers should be invoked.
- // This is essentially |dump_thread_|.task_runner() but needs to be kept
- // as a separate variable as it needs to be accessed by arbitrary dumpers'
- // threads outside of the lock_ to avoid races when disabling tracing.
- // It is immutable for all the duration of a tracing session.
- const scoped_refptr<SequencedTaskRunner> dump_thread_task_runner;
-
- private:
- DISALLOW_COPY_AND_ASSIGN(ProcessMemoryDumpAsyncState);
- };
-
- static const int kMaxConsecutiveFailuresCount;
- static const char* const kSystemAllocatorPoolName;
-
- MemoryDumpManager();
- virtual ~MemoryDumpManager();
-
- static void SetInstanceForTesting(MemoryDumpManager* instance);
-
- // Lazily initializes dump_thread_ and returns its TaskRunner.
- scoped_refptr<base::SequencedTaskRunner> GetOrCreateBgTaskRunnerLocked();
-
- // Calls InvokeOnMemoryDump() for the each MDP that belongs to the current
- // task runner and switches to the task runner of the next MDP. Handles
- // failures in MDP and thread hops, and always calls FinishAsyncProcessDump()
- // at the end.
- void ContinueAsyncProcessDump(
- ProcessMemoryDumpAsyncState* owned_pmd_async_state);
-
- // Invokes OnMemoryDump() of the given MDP. Should be called on the MDP task
- // runner.
- void InvokeOnMemoryDump(MemoryDumpProviderInfo* mdpinfo,
- ProcessMemoryDump* pmd);
-
- void FinishAsyncProcessDump(
- std::unique_ptr<ProcessMemoryDumpAsyncState> pmd_async_state);
-
- // Helper for RegierDumpProvider* functions.
- void RegisterDumpProviderInternal(
- MemoryDumpProvider* mdp,
- const char* name,
- scoped_refptr<SequencedTaskRunner> task_runner,
- const MemoryDumpProvider::Options& options);
-
- // Helper for the public UnregisterDumpProvider* functions.
- void UnregisterDumpProviderInternal(MemoryDumpProvider* mdp,
- bool take_mdp_ownership_and_delete_async);
-
- // Fills the passed vector with the subset of dump providers which were
- // registered with is_fast_polling_supported == true.
- void GetDumpProvidersForPolling(
- std::vector<scoped_refptr<MemoryDumpProviderInfo>>*);
-
- // Initialize |heap_profiler_serialization_state_| when tracing and heap
- // profiler are enabled.
- void InitializeHeapProfilerStateIfNeededLocked();
-
- // Sends OnHeapProfilingEnabled() notifcation to mdp ensuring OnMemoryDump()
- // is not called at the same time.
- void NotifyHeapProfilingEnabledLocked(
- scoped_refptr<MemoryDumpProviderInfo> mdpinfo,
- bool enabled);
-
- bool can_request_global_dumps() const {
- return !request_dump_function_.is_null();
- }
-
- // An ordered set of registered MemoryDumpProviderInfo(s), sorted by task
- // runner affinity (MDPs belonging to the same task runners are adjacent).
- MemoryDumpProviderInfo::OrderedSet dump_providers_;
-
- // Shared among all the PMDs to keep state scoped to the tracing session.
- scoped_refptr<HeapProfilerSerializationState>
- heap_profiler_serialization_state_;
-
- // Function provided by the embedder to handle global dump requests.
- RequestGlobalDumpFunction request_dump_function_;
-
- // True when current process coordinates the periodic dump triggering.
- bool is_coordinator_;
-
- // Protects from concurrent accesses to the local state, eg: to guard against
- // disabling logging while dumping on another thread.
- Lock lock_;
-
- // Thread used for MemoryDumpProviders which don't specify a task runner
- // affinity.
- std::unique_ptr<Thread> dump_thread_;
-
- // The unique id of the child process. This is created only for tracing and is
- // expected to be valid only when tracing is enabled.
- uint64_t tracing_process_id_;
-
- // When true, calling |RegisterMemoryDumpProvider| is a no-op.
- bool dumper_registrations_ignored_for_testing_;
-
- HeapProfilingMode heap_profiling_mode_;
-
- DISALLOW_COPY_AND_ASSIGN(MemoryDumpManager);
-};
-
-} // namespace trace_event
-} // namespace base
-
-#endif // BASE_TRACE_EVENT_MEMORY_DUMP_MANAGER_H_
diff --git a/base/trace_event/memory_dump_manager_test_utils.h b/base/trace_event/memory_dump_manager_test_utils.h
deleted file mode 100644
index 413017f..0000000
--- a/base/trace_event/memory_dump_manager_test_utils.h
+++ /dev/null
@@ -1,38 +0,0 @@
-// Copyright 2017 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_MEMORY_DUMP_MANAGER_TEST_UTILS_H_
-#define BASE_TRACE_EVENT_MEMORY_DUMP_MANAGER_TEST_UTILS_H_
-
-#include "base/bind.h"
-#include "base/trace_event/memory_dump_manager.h"
-#include "base/trace_event/memory_dump_request_args.h"
-
-namespace base {
-namespace trace_event {
-
-void RequestGlobalDumpForInProcessTesting(
- base::trace_event::MemoryDumpType dump_type,
- base::trace_event::MemoryDumpLevelOfDetail level_of_detail) {
- MemoryDumpRequestArgs local_args = {0 /* dump_guid */, dump_type,
- level_of_detail};
- MemoryDumpManager::GetInstance()->CreateProcessDump(
- local_args, ProcessMemoryDumpCallback());
-};
-
-// Short circuits the RequestGlobalDumpFunction() to CreateProcessDump(),
-// effectively allowing to use both in unittests with the same behavior.
-// Unittests are in-process only and don't require all the multi-process
-// dump handshaking (which would require bits outside of base).
-void InitializeMemoryDumpManagerForInProcessTesting(bool is_coordinator) {
- MemoryDumpManager* instance = MemoryDumpManager::GetInstance();
- instance->set_dumper_registrations_ignored_for_testing(true);
- instance->Initialize(BindRepeating(&RequestGlobalDumpForInProcessTesting),
- is_coordinator);
-}
-
-} // namespace trace_event
-} // namespace base
-
-#endif // BASE_TRACE_EVENT_MEMORY_DUMP_MANAGER_TEST_UTILS_H_
diff --git a/base/trace_event/memory_dump_provider.h b/base/trace_event/memory_dump_provider.h
deleted file mode 100644
index b458bfb..0000000
--- a/base/trace_event/memory_dump_provider.h
+++ /dev/null
@@ -1,81 +0,0 @@
-// Copyright 2015 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_MEMORY_DUMP_PROVIDER_H_
-#define BASE_TRACE_EVENT_MEMORY_DUMP_PROVIDER_H_
-
-#include "base/base_export.h"
-#include "base/macros.h"
-#include "base/process/process_handle.h"
-#include "base/trace_event/memory_dump_request_args.h"
-
-namespace base {
-namespace trace_event {
-
-class ProcessMemoryDump;
-
-// The contract interface that memory dump providers must implement.
-class BASE_EXPORT MemoryDumpProvider {
- public:
- // Optional arguments for MemoryDumpManager::RegisterDumpProvider().
- struct Options {
- Options()
- : dumps_on_single_thread_task_runner(false),
- is_fast_polling_supported(false),
- supports_heap_profiling(false) {}
-
- // |dumps_on_single_thread_task_runner| is true if the dump provider runs on
- // a SingleThreadTaskRunner, which is usually the case. It is faster to run
- // all providers that run on the same thread together without thread hops.
- bool dumps_on_single_thread_task_runner;
-
- // Set to true if the dump provider implementation supports high frequency
- // polling. Only providers running without task runner affinity are
- // supported.
- bool is_fast_polling_supported;
-
- // Set to true when the dump provider supports heap profiling. MDM sends
- // OnHeapProfiling() notifications only if this is set to true.
- bool supports_heap_profiling;
- };
-
- virtual ~MemoryDumpProvider() = default;
-
- // Called by the MemoryDumpManager when generating memory dumps.
- // The |args| specify if the embedder should generate light/heavy dumps on
- // dump requests. The embedder should return true if the |pmd| was
- // successfully populated, false if something went wrong and the dump should
- // be considered invalid.
- // (Note, the MemoryDumpManager has a fail-safe logic which will disable the
- // MemoryDumpProvider for the entire trace session if it fails consistently).
- virtual bool OnMemoryDump(const MemoryDumpArgs& args,
- ProcessMemoryDump* pmd) = 0;
-
- // Called by the MemoryDumpManager when an allocator should start or stop
- // collecting extensive allocation data, if supported. Called only when
- // |supports_heap_profiling| is set to true.
- virtual void OnHeapProfilingEnabled(bool enabled) {}
-
- // Quickly record the total memory usage in |memory_total|. This method will
- // be called only when the dump provider registration has
- // |is_fast_polling_supported| set to true. This method is used for polling at
- // high frequency for detecting peaks. See comment on
- // |is_fast_polling_supported| option if you need to override this method.
- virtual void PollFastMemoryTotal(uint64_t* memory_total) {}
-
- // Indicates that fast memory polling is not going to be used in the near
- // future and the MDP can tear down any resource kept around for fast memory
- // polling.
- virtual void SuspendFastMemoryPolling() {}
-
- protected:
- MemoryDumpProvider() = default;
-
- DISALLOW_COPY_AND_ASSIGN(MemoryDumpProvider);
-};
-
-} // namespace trace_event
-} // namespace base
-
-#endif // BASE_TRACE_EVENT_MEMORY_DUMP_PROVIDER_H_
diff --git a/base/trace_event/memory_dump_provider_info.cc b/base/trace_event/memory_dump_provider_info.cc
deleted file mode 100644
index 3220476..0000000
--- a/base/trace_event/memory_dump_provider_info.cc
+++ /dev/null
@@ -1,43 +0,0 @@
-// Copyright 2017 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/memory_dump_provider_info.h"
-
-#include <tuple>
-
-#include "base/sequenced_task_runner.h"
-
-namespace base {
-namespace trace_event {
-
-MemoryDumpProviderInfo::MemoryDumpProviderInfo(
- MemoryDumpProvider* dump_provider,
- const char* name,
- scoped_refptr<SequencedTaskRunner> task_runner,
- const MemoryDumpProvider::Options& options,
- bool whitelisted_for_background_mode)
- : dump_provider(dump_provider),
- options(options),
- name(name),
- task_runner(std::move(task_runner)),
- whitelisted_for_background_mode(whitelisted_for_background_mode),
- consecutive_failures(0),
- disabled(false) {}
-
-MemoryDumpProviderInfo::~MemoryDumpProviderInfo() = default;
-
-bool MemoryDumpProviderInfo::Comparator::operator()(
- const scoped_refptr<MemoryDumpProviderInfo>& a,
- const scoped_refptr<MemoryDumpProviderInfo>& b) const {
- if (!a || !b)
- return a.get() < b.get();
- // Ensure that unbound providers (task_runner == nullptr) always run last.
- // Rationale: some unbound dump providers are known to be slow, keep them last
- // to avoid skewing timings of the other dump providers.
- return std::tie(a->task_runner, a->dump_provider) >
- std::tie(b->task_runner, b->dump_provider);
-}
-
-} // namespace trace_event
-} // namespace base
diff --git a/base/trace_event/memory_dump_provider_info.h b/base/trace_event/memory_dump_provider_info.h
deleted file mode 100644
index f0ea1e6..0000000
--- a/base/trace_event/memory_dump_provider_info.h
+++ /dev/null
@@ -1,108 +0,0 @@
-// Copyright 2017 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_MEMORY_DUMP_PROVIDER_INFO_H_
-#define BASE_TRACE_EVENT_MEMORY_DUMP_PROVIDER_INFO_H_
-
-#include <memory>
-#include <set>
-
-#include "base/base_export.h"
-#include "base/memory/ref_counted.h"
-#include "base/trace_event/memory_dump_provider.h"
-
-namespace base {
-
-class SequencedTaskRunner;
-
-namespace trace_event {
-
-// Wraps a MemoryDumpProvider (MDP), which is registered via
-// MemoryDumpManager(MDM)::RegisterDumpProvider(), holding the extra information
-// required to deal with it (which task runner it should be invoked onto,
-// whether it has been disabled, etc.)
-// More importantly, having a refptr to this object guarantees that a MDP that
-// is not thread-bound (hence which can only be unregistered via
-// MDM::UnregisterAndDeleteDumpProviderSoon()) will stay alive as long as the
-// refptr is held.
-//
-// Lifetime:
-// At any time, there is at most one instance of this class for each instance
-// of a given MemoryDumpProvider, but there might be several scoped_refptr
-// holding onto each of this. Specifically:
-// - In nominal conditions, there is a refptr for each registered MDP in the
-// MDM's |dump_providers_| list.
-// - In most cases, the only refptr (in the |dump_providers_| list) is destroyed
-// by MDM::UnregisterDumpProvider().
-// - However, when MDM starts a dump, the list of refptrs is copied into the
-// ProcessMemoryDumpAsyncState. That list is pruned as MDP(s) are invoked.
-// - If UnregisterDumpProvider() is called on a non-thread-bound MDP while a
-// dump is in progress, the extar extra of the handle is destroyed in
-// MDM::SetupNextMemoryDump() or MDM::InvokeOnMemoryDump(), when the copy
-// inside ProcessMemoryDumpAsyncState is erase()-d.
-// - The PeakDetector can keep extra refptrs when enabled.
-struct BASE_EXPORT MemoryDumpProviderInfo
- : public RefCountedThreadSafe<MemoryDumpProviderInfo> {
- public:
- // Define a total order based on the |task_runner| affinity, so that MDPs
- // belonging to the same SequencedTaskRunner are adjacent in the set.
- struct Comparator {
- bool operator()(const scoped_refptr<MemoryDumpProviderInfo>& a,
- const scoped_refptr<MemoryDumpProviderInfo>& b) const;
- };
- using OrderedSet =
- std::set<scoped_refptr<MemoryDumpProviderInfo>, Comparator>;
-
- MemoryDumpProviderInfo(MemoryDumpProvider* dump_provider,
- const char* name,
- scoped_refptr<SequencedTaskRunner> task_runner,
- const MemoryDumpProvider::Options& options,
- bool whitelisted_for_background_mode);
-
- // It is safe to access the const fields below from any thread as they are
- // never mutated.
-
- MemoryDumpProvider* const dump_provider;
-
- // The |options| arg passed to MDM::RegisterDumpProvider().
- const MemoryDumpProvider::Options options;
-
- // Human readable name, not unique (distinct MDP instances might have the same
- // name). Used for debugging, testing and whitelisting for BACKGROUND mode.
- const char* const name;
-
- // The task runner on which the MDP::OnMemoryDump call should be posted onto.
- // Can be nullptr, in which case the MDP will be invoked on a background
- // thread handled by MDM.
- const scoped_refptr<SequencedTaskRunner> task_runner;
-
- // True if the dump provider is whitelisted for background mode.
- const bool whitelisted_for_background_mode;
-
- // These fields below, instead, are not thread safe and can be mutated only:
- // - On the |task_runner|, when not null (i.e. for thread-bound MDPS).
- // - By the MDM's background thread (or in any other way that guarantees
- // sequencing) for non-thread-bound MDPs.
-
- // Used to transfer ownership for UnregisterAndDeleteDumpProviderSoon().
- // nullptr in all other cases.
- std::unique_ptr<MemoryDumpProvider> owned_dump_provider;
-
- // For fail-safe logic (auto-disable failing MDPs).
- int consecutive_failures;
-
- // Flagged either by the auto-disable logic or during unregistration.
- bool disabled;
-
- private:
- friend class base::RefCountedThreadSafe<MemoryDumpProviderInfo>;
- ~MemoryDumpProviderInfo();
-
- DISALLOW_COPY_AND_ASSIGN(MemoryDumpProviderInfo);
-};
-
-} // namespace trace_event
-} // namespace base
-
-#endif // BASE_TRACE_EVENT_MEMORY_DUMP_PROVIDER_INFO_H_
diff --git a/base/trace_event/memory_dump_request_args.cc b/base/trace_event/memory_dump_request_args.cc
deleted file mode 100644
index 3cb9cab..0000000
--- a/base/trace_event/memory_dump_request_args.cc
+++ /dev/null
@@ -1,68 +0,0 @@
-// Copyright 2015 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/memory_dump_request_args.h"
-
-#include "base/logging.h"
-
-namespace base {
-namespace trace_event {
-
-// static
-const char* MemoryDumpTypeToString(const MemoryDumpType& dump_type) {
- switch (dump_type) {
- case MemoryDumpType::PERIODIC_INTERVAL:
- return "periodic_interval";
- case MemoryDumpType::EXPLICITLY_TRIGGERED:
- return "explicitly_triggered";
- case MemoryDumpType::PEAK_MEMORY_USAGE:
- return "peak_memory_usage";
- case MemoryDumpType::SUMMARY_ONLY:
- return "summary_only";
- }
- NOTREACHED();
- return "unknown";
-}
-
-MemoryDumpType StringToMemoryDumpType(const std::string& str) {
- if (str == "periodic_interval")
- return MemoryDumpType::PERIODIC_INTERVAL;
- if (str == "explicitly_triggered")
- return MemoryDumpType::EXPLICITLY_TRIGGERED;
- if (str == "peak_memory_usage")
- return MemoryDumpType::PEAK_MEMORY_USAGE;
- if (str == "summary_only")
- return MemoryDumpType::SUMMARY_ONLY;
- NOTREACHED();
- return MemoryDumpType::LAST;
-}
-
-const char* MemoryDumpLevelOfDetailToString(
- const MemoryDumpLevelOfDetail& level_of_detail) {
- switch (level_of_detail) {
- case MemoryDumpLevelOfDetail::BACKGROUND:
- return "background";
- case MemoryDumpLevelOfDetail::LIGHT:
- return "light";
- case MemoryDumpLevelOfDetail::DETAILED:
- return "detailed";
- }
- NOTREACHED();
- return "unknown";
-}
-
-MemoryDumpLevelOfDetail StringToMemoryDumpLevelOfDetail(
- const std::string& str) {
- if (str == "background")
- return MemoryDumpLevelOfDetail::BACKGROUND;
- if (str == "light")
- return MemoryDumpLevelOfDetail::LIGHT;
- if (str == "detailed")
- return MemoryDumpLevelOfDetail::DETAILED;
- NOTREACHED();
- return MemoryDumpLevelOfDetail::LAST;
-}
-
-} // namespace trace_event
-} // namespace base
diff --git a/base/trace_event/memory_dump_request_args.h b/base/trace_event/memory_dump_request_args.h
deleted file mode 100644
index 41bc99b..0000000
--- a/base/trace_event/memory_dump_request_args.h
+++ /dev/null
@@ -1,102 +0,0 @@
-// Copyright 2015 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_MEMORY_DUMP_REQUEST_ARGS_H_
-#define BASE_TRACE_EVENT_MEMORY_DUMP_REQUEST_ARGS_H_
-
-// This file defines the types and structs used to issue memory dump requests.
-// These are also used in the IPCs for coordinating inter-process memory dumps.
-
-#include <stdint.h>
-#include <map>
-#include <memory>
-#include <string>
-
-#include "base/base_export.h"
-#include "base/callback.h"
-#include "base/optional.h"
-#include "base/process/process_handle.h"
-
-namespace base {
-namespace trace_event {
-
-class ProcessMemoryDump;
-
-// Captures the reason why a memory dump is being requested. This is to allow
-// selective enabling of dumps, filtering and post-processing. Keep this
-// consistent with memory_instrumentation.mojo and
-// memory_instrumentation_struct_traits.{h,cc}
-enum class MemoryDumpType {
- PERIODIC_INTERVAL, // Dumping memory at periodic intervals.
- EXPLICITLY_TRIGGERED, // Non maskable dump request.
- PEAK_MEMORY_USAGE, // Dumping memory at detected peak total memory usage.
- SUMMARY_ONLY, // Calculate just the summary & don't add to the trace.
- LAST = SUMMARY_ONLY
-};
-
-// Tells the MemoryDumpProvider(s) how much detailed their dumps should be.
-// Keep this consistent with memory_instrumentation.mojo and
-// memory_instrumentation_struct_traits.{h,cc}
-enum class MemoryDumpLevelOfDetail : uint32_t {
- FIRST,
-
- // For background tracing mode. The dump time is quick, and typically just the
- // totals are expected. Suballocations need not be specified. Dump name must
- // contain only pre-defined strings and string arguments cannot be added.
- BACKGROUND = FIRST,
-
- // For the levels below, MemoryDumpProvider instances must guarantee that the
- // total size reported in the root node is consistent. Only the granularity of
- // the child MemoryAllocatorDump(s) differs with the levels.
-
- // Few entries, typically a fixed number, per dump.
- LIGHT,
-
- // Unrestricted amount of entries per dump.
- DETAILED,
-
- LAST = DETAILED
-};
-
-// Keep this consistent with memory_instrumentation.mojo and
-// memory_instrumentation_struct_traits.{h,cc}
-struct BASE_EXPORT MemoryDumpRequestArgs {
- // Globally unique identifier. In multi-process dumps, all processes issue a
- // local dump with the same guid. This allows the trace importers to
- // reconstruct the global dump.
- uint64_t dump_guid;
-
- MemoryDumpType dump_type;
- MemoryDumpLevelOfDetail level_of_detail;
-};
-
-// Args for ProcessMemoryDump and passed to OnMemoryDump calls for memory dump
-// providers. Dump providers are expected to read the args for creating dumps.
-struct MemoryDumpArgs {
- // Specifies how detailed the dumps should be.
- MemoryDumpLevelOfDetail level_of_detail;
-
- // Globally unique identifier. In multi-process dumps, all processes issue a
- // local dump with the same guid. This allows the trace importers to
- // reconstruct the global dump.
- uint64_t dump_guid;
-};
-
-using ProcessMemoryDumpCallback = Callback<
- void(bool success, uint64_t dump_guid, std::unique_ptr<ProcessMemoryDump>)>;
-
-BASE_EXPORT const char* MemoryDumpTypeToString(const MemoryDumpType& dump_type);
-
-BASE_EXPORT MemoryDumpType StringToMemoryDumpType(const std::string& str);
-
-BASE_EXPORT const char* MemoryDumpLevelOfDetailToString(
- const MemoryDumpLevelOfDetail& level_of_detail);
-
-BASE_EXPORT MemoryDumpLevelOfDetail
-StringToMemoryDumpLevelOfDetail(const std::string& str);
-
-} // namespace trace_event
-} // namespace base
-
-#endif // BASE_TRACE_EVENT_MEMORY_DUMP_REQUEST_ARGS_H_
diff --git a/base/trace_event/memory_dump_scheduler.cc b/base/trace_event/memory_dump_scheduler.cc
deleted file mode 100644
index 8b03f5c..0000000
--- a/base/trace_event/memory_dump_scheduler.cc
+++ /dev/null
@@ -1,118 +0,0 @@
-// Copyright 2017 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/memory_dump_scheduler.h"
-
-#include <algorithm>
-#include <limits>
-
-#include "base/bind.h"
-#include "base/logging.h"
-#include "base/threading/sequenced_task_runner_handle.h"
-
-namespace base {
-namespace trace_event {
-
-// static
-MemoryDumpScheduler* MemoryDumpScheduler::GetInstance() {
- static MemoryDumpScheduler* instance = new MemoryDumpScheduler();
- return instance;
-}
-
-MemoryDumpScheduler::MemoryDumpScheduler() : period_ms_(0), generation_(0) {}
-MemoryDumpScheduler::~MemoryDumpScheduler() {
- // Hit only in tests. Check that tests don't leave without stopping.
- DCHECK(!is_enabled_for_testing());
-}
-
-void MemoryDumpScheduler::Start(
- MemoryDumpScheduler::Config config,
- scoped_refptr<SequencedTaskRunner> task_runner) {
- DCHECK(!task_runner_);
- task_runner_ = task_runner;
- task_runner->PostTask(FROM_HERE, BindOnce(&MemoryDumpScheduler::StartInternal,
- Unretained(this), config));
-}
-
-void MemoryDumpScheduler::Stop() {
- if (!task_runner_)
- return;
- task_runner_->PostTask(FROM_HERE, BindOnce(&MemoryDumpScheduler::StopInternal,
- Unretained(this)));
- task_runner_ = nullptr;
-}
-
-void MemoryDumpScheduler::StartInternal(MemoryDumpScheduler::Config config) {
- uint32_t light_dump_period_ms = 0;
- uint32_t heavy_dump_period_ms = 0;
- uint32_t min_period_ms = std::numeric_limits<uint32_t>::max();
- for (const Config::Trigger& trigger : config.triggers) {
- DCHECK_GT(trigger.period_ms, 0u);
- switch (trigger.level_of_detail) {
- case MemoryDumpLevelOfDetail::BACKGROUND:
- break;
- case MemoryDumpLevelOfDetail::LIGHT:
- DCHECK_EQ(0u, light_dump_period_ms);
- light_dump_period_ms = trigger.period_ms;
- break;
- case MemoryDumpLevelOfDetail::DETAILED:
- DCHECK_EQ(0u, heavy_dump_period_ms);
- heavy_dump_period_ms = trigger.period_ms;
- break;
- }
- min_period_ms = std::min(min_period_ms, trigger.period_ms);
- }
-
- DCHECK_EQ(0u, light_dump_period_ms % min_period_ms);
- DCHECK_EQ(0u, heavy_dump_period_ms % min_period_ms);
- DCHECK(!config.callback.is_null());
- callback_ = config.callback;
- period_ms_ = min_period_ms;
- tick_count_ = 0;
- light_dump_rate_ = light_dump_period_ms / min_period_ms;
- heavy_dump_rate_ = heavy_dump_period_ms / min_period_ms;
-
- // Trigger the first dump after 200ms.
- // TODO(lalitm): this is a tempoarary hack to delay the first scheduled dump
- // so that the child processes get tracing enabled notification via IPC.
- // See crbug.com/770151.
- SequencedTaskRunnerHandle::Get()->PostDelayedTask(
- FROM_HERE,
- BindOnce(&MemoryDumpScheduler::Tick, Unretained(this), ++generation_),
- TimeDelta::FromMilliseconds(200));
-}
-
-void MemoryDumpScheduler::StopInternal() {
- period_ms_ = 0;
- generation_++;
- callback_.Reset();
-}
-
-void MemoryDumpScheduler::Tick(uint32_t expected_generation) {
- if (period_ms_ == 0 || generation_ != expected_generation)
- return;
-
- MemoryDumpLevelOfDetail level_of_detail = MemoryDumpLevelOfDetail::BACKGROUND;
- if (light_dump_rate_ > 0 && tick_count_ % light_dump_rate_ == 0)
- level_of_detail = MemoryDumpLevelOfDetail::LIGHT;
- if (heavy_dump_rate_ > 0 && tick_count_ % heavy_dump_rate_ == 0)
- level_of_detail = MemoryDumpLevelOfDetail::DETAILED;
- tick_count_++;
-
- callback_.Run(level_of_detail);
-
- SequencedTaskRunnerHandle::Get()->PostDelayedTask(
- FROM_HERE,
- BindOnce(&MemoryDumpScheduler::Tick, Unretained(this),
- expected_generation),
- TimeDelta::FromMilliseconds(period_ms_));
-}
-
-MemoryDumpScheduler::Config::Config() = default;
-MemoryDumpScheduler::Config::~Config() = default;
-MemoryDumpScheduler::Config::Config(const MemoryDumpScheduler::Config&) =
- default;
-
-} // namespace trace_event
-} // namespace base
diff --git a/base/trace_event/memory_dump_scheduler.h b/base/trace_event/memory_dump_scheduler.h
deleted file mode 100644
index 21334f0..0000000
--- a/base/trace_event/memory_dump_scheduler.h
+++ /dev/null
@@ -1,76 +0,0 @@
-// Copyright 2017 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_MEMORY_DUMP_SCHEDULER_H
-#define BASE_TRACE_EVENT_MEMORY_DUMP_SCHEDULER_H
-
-#include <stdint.h>
-
-#include <vector>
-
-#include "base/base_export.h"
-#include "base/callback.h"
-#include "base/memory/ref_counted.h"
-#include "base/trace_event/memory_dump_request_args.h"
-
-namespace base {
-class SequencedTaskRunner;
-
-namespace trace_event {
-
-// Schedules global dump requests based on the triggers added. The methods of
-// this class are NOT thread safe and the client has to take care of invoking
-// all the methods of the class safely.
-class BASE_EXPORT MemoryDumpScheduler {
- public:
- using PeriodicCallback = RepeatingCallback<void(MemoryDumpLevelOfDetail)>;
-
- // Passed to Start().
- struct BASE_EXPORT Config {
- struct Trigger {
- MemoryDumpLevelOfDetail level_of_detail;
- uint32_t period_ms;
- };
-
- Config();
- Config(const Config&);
- ~Config();
-
- std::vector<Trigger> triggers;
- PeriodicCallback callback;
- };
-
- static MemoryDumpScheduler* GetInstance();
-
- void Start(Config, scoped_refptr<SequencedTaskRunner> task_runner);
- void Stop();
- bool is_enabled_for_testing() const { return bool(task_runner_); }
-
- private:
- friend class MemoryDumpSchedulerTest;
- MemoryDumpScheduler();
- ~MemoryDumpScheduler();
-
- void StartInternal(Config);
- void StopInternal();
- void Tick(uint32_t expected_generation);
-
- // Accessed only by the public methods (never from the task runner itself).
- scoped_refptr<SequencedTaskRunner> task_runner_;
-
- // These fields instead are only accessed from within the task runner.
- uint32_t period_ms_; // 0 == disabled.
- uint32_t generation_; // Used to invalidate outstanding tasks after Stop().
- uint32_t tick_count_;
- uint32_t light_dump_rate_;
- uint32_t heavy_dump_rate_;
- PeriodicCallback callback_;
-
- DISALLOW_COPY_AND_ASSIGN(MemoryDumpScheduler);
-};
-
-} // namespace trace_event
-} // namespace base
-
-#endif // BASE_TRACE_EVENT_MEMORY_DUMP_SCHEDULER_H
diff --git a/base/trace_event/memory_infra_background_whitelist.cc b/base/trace_event/memory_infra_background_whitelist.cc
deleted file mode 100644
index 0e69c7c..0000000
--- a/base/trace_event/memory_infra_background_whitelist.cc
+++ /dev/null
@@ -1,386 +0,0 @@
-// Copyright 2016 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/memory_infra_background_whitelist.h"
-
-#include <ctype.h>
-#include <string.h>
-
-#include <string>
-
-#include "base/strings/string_util.h"
-
-namespace base {
-namespace trace_event {
-namespace {
-
-// The names of dump providers whitelisted for background tracing. Dump
-// providers can be added here only if the background mode dump has very
-// little processor and memory overhead.
-// TODO(ssid): Some dump providers do not create ownership edges on background
-// dump. So, the effective size will not be correct.
-const char* const kDumpProviderWhitelist[] = {
- "android::ResourceManagerImpl",
- "AutocompleteController",
- "BlinkGC",
- "BlinkObjectCounters",
- "BlobStorageContext",
- "ClientDiscardableSharedMemoryManager",
- "DOMStorage",
- "DownloadService",
- "DiscardableSharedMemoryManager",
- "gpu::BufferManager",
- "gpu::RenderbufferManager",
- "gpu::TextureManager",
- "FontCaches",
- "HistoryReport",
- "IPCChannel",
- "IndexedDBBackingStore",
- "InMemoryURLIndex",
- "JavaHeap",
- "LevelDB",
- "LeveldbValueStore",
- "LocalStorage",
- "Malloc",
- "MemoryCache",
- "MojoHandleTable",
- "MojoLevelDB",
- "MojoMessages",
- "PartitionAlloc",
- "ProcessMemoryMetrics",
- "RenderProcessHost",
- "SharedMemoryTracker",
- "Skia",
- "Sql",
- "URLRequestContext",
- "V8Isolate",
- "SyncDirectory",
- "TabRestoreServiceHelper",
- nullptr // End of list marker.
-};
-
-// A list of string names that are allowed for the memory allocator dumps in
-// background mode.
-const char* const kAllocatorDumpNameWhitelist[] = {
- "blink_gc",
- "blink_gc/allocated_objects",
- "blink_objects/AudioHandler",
- "blink_objects/Document",
- "blink_objects/Frame",
- "blink_objects/JSEventListener",
- "blink_objects/LayoutObject",
- "blink_objects/MediaKeySession",
- "blink_objects/MediaKeys",
- "blink_objects/Node",
- "blink_objects/Resource",
- "blink_objects/RTCPeerConnection",
- "blink_objects/ScriptPromise",
- "blink_objects/PausableObject",
- "blink_objects/V8PerContextData",
- "blink_objects/WorkerGlobalScope",
- "blink_objects/UACSSResource",
- "blink_objects/ResourceFetcher",
- "components/download/controller_0x?",
- "discardable",
- "discardable/child_0x?",
- "extensions/value_store/Extensions.Database.Open.Settings/0x?",
- "extensions/value_store/Extensions.Database.Open.Rules/0x?",
- "extensions/value_store/Extensions.Database.Open.State/0x?",
- "extensions/value_store/Extensions.Database.Open/0x?",
- "extensions/value_store/Extensions.Database.Restore/0x?",
- "extensions/value_store/Extensions.Database.Value.Restore/0x?",
- "font_caches/font_platform_data_cache",
- "font_caches/shape_caches",
- "gpu/gl/buffers/share_group_0x?",
- "gpu/gl/renderbuffers/share_group_0x?",
- "gpu/gl/textures/share_group_0x?",
- "history/delta_file_service/leveldb_0x?",
- "history/usage_reports_buffer/leveldb_0x?",
- "java_heap",
- "java_heap/allocated_objects",
- "leveldatabase",
- "leveldatabase/block_cache/browser",
- "leveldatabase/block_cache/in_memory",
- "leveldatabase/block_cache/unified",
- "leveldatabase/block_cache/web",
- "leveldatabase/db_0x?",
- "leveldatabase/db_0x?/block_cache",
- "leveldatabase/memenv_0x?",
- "malloc",
- "malloc/allocated_objects",
- "malloc/metadata_fragmentation_caches",
- "mojo",
- "mojo/data_pipe_consumer",
- "mojo/data_pipe_producer",
- "mojo/messages",
- "mojo/message_pipe",
- "mojo/platform_handle",
- "mojo/queued_ipc_channel_message/0x?",
- "mojo/render_process_host/0x?",
- "mojo/shared_buffer",
- "mojo/unknown",
- "mojo/watcher",
- "net/http_network_session_0x?",
- "net/http_network_session_0x?/quic_stream_factory",
- "net/http_network_session_0x?/socket_pool",
- "net/http_network_session_0x?/spdy_session_pool",
- "net/http_network_session_0x?/stream_factory",
- "net/ssl_session_cache",
- "net/url_request_context",
- "net/url_request_context/app_request",
- "net/url_request_context/app_request/0x?",
- "net/url_request_context/app_request/0x?/cookie_monster",
- "net/url_request_context/app_request/0x?/cookie_monster/cookies",
- "net/url_request_context/app_request/0x?/cookie_monster/"
- "tasks_pending_global",
- "net/url_request_context/app_request/0x?/cookie_monster/"
- "tasks_pending_for_key",
- "net/url_request_context/app_request/0x?/http_cache",
- "net/url_request_context/app_request/0x?/http_cache/memory_backend",
- "net/url_request_context/app_request/0x?/http_cache/simple_backend",
- "net/url_request_context/app_request/0x?/http_network_session",
- "net/url_request_context/extensions",
- "net/url_request_context/extensions/0x?",
- "net/url_request_context/extensions/0x?/cookie_monster",
- "net/url_request_context/extensions/0x?/cookie_monster/cookies",
- "net/url_request_context/extensions/0x?/cookie_monster/"
- "tasks_pending_global",
- "net/url_request_context/extensions/0x?/cookie_monster/"
- "tasks_pending_for_key",
- "net/url_request_context/extensions/0x?/http_cache",
- "net/url_request_context/extensions/0x?/http_cache/memory_backend",
- "net/url_request_context/extensions/0x?/http_cache/simple_backend",
- "net/url_request_context/extensions/0x?/http_network_session",
- "net/url_request_context/isolated_media",
- "net/url_request_context/isolated_media/0x?",
- "net/url_request_context/isolated_media/0x?/cookie_monster",
- "net/url_request_context/isolated_media/0x?/cookie_monster/cookies",
- "net/url_request_context/isolated_media/0x?/cookie_monster/"
- "tasks_pending_global",
- "net/url_request_context/isolated_media/0x?/cookie_monster/"
- "tasks_pending_for_key",
- "net/url_request_context/isolated_media/0x?/http_cache",
- "net/url_request_context/isolated_media/0x?/http_cache/memory_backend",
- "net/url_request_context/isolated_media/0x?/http_cache/simple_backend",
- "net/url_request_context/isolated_media/0x?/http_network_session",
- "net/url_request_context/main",
- "net/url_request_context/main/0x?",
- "net/url_request_context/main/0x?/cookie_monster",
- "net/url_request_context/main/0x?/cookie_monster/cookies",
- "net/url_request_context/main/0x?/cookie_monster/tasks_pending_global",
- "net/url_request_context/main/0x?/cookie_monster/tasks_pending_for_key",
- "net/url_request_context/main/0x?/http_cache",
- "net/url_request_context/main/0x?/http_cache/memory_backend",
- "net/url_request_context/main/0x?/http_cache/simple_backend",
- "net/url_request_context/main/0x?/http_network_session",
- "net/url_request_context/main_media",
- "net/url_request_context/main_media/0x?",
- "net/url_request_context/main_media/0x?/cookie_monster",
- "net/url_request_context/main_media/0x?/cookie_monster/cookies",
- "net/url_request_context/main_media/0x?/cookie_monster/"
- "tasks_pending_global",
- "net/url_request_context/main_media/0x?/cookie_monster/"
- "tasks_pending_for_key",
- "net/url_request_context/main_media/0x?/http_cache",
- "net/url_request_context/main_media/0x?/http_cache/memory_backend",
- "net/url_request_context/main_media/0x?/http_cache/simple_backend",
- "net/url_request_context/main_media/0x?/http_network_session",
- "net/url_request_context/proxy",
- "net/url_request_context/proxy/0x?",
- "net/url_request_context/proxy/0x?/cookie_monster",
- "net/url_request_context/proxy/0x?/cookie_monster/cookies",
- "net/url_request_context/proxy/0x?/cookie_monster/tasks_pending_global",
- "net/url_request_context/proxy/0x?/cookie_monster/tasks_pending_for_key",
- "net/url_request_context/proxy/0x?/http_cache",
- "net/url_request_context/proxy/0x?/http_cache/memory_backend",
- "net/url_request_context/proxy/0x?/http_cache/simple_backend",
- "net/url_request_context/proxy/0x?/http_network_session",
- "net/url_request_context/safe_browsing",
- "net/url_request_context/safe_browsing/0x?",
- "net/url_request_context/safe_browsing/0x?/cookie_monster",
- "net/url_request_context/safe_browsing/0x?/cookie_monster/cookies",
- "net/url_request_context/safe_browsing/0x?/cookie_monster/"
- "tasks_pending_global",
- "net/url_request_context/safe_browsing/0x?/cookie_monster/"
- "tasks_pending_for_key",
- "net/url_request_context/safe_browsing/0x?/http_cache",
- "net/url_request_context/safe_browsing/0x?/http_cache/memory_backend",
- "net/url_request_context/safe_browsing/0x?/http_cache/simple_backend",
- "net/url_request_context/safe_browsing/0x?/http_network_session",
- "net/url_request_context/system",
- "net/url_request_context/system/0x?",
- "net/url_request_context/system/0x?/cookie_monster",
- "net/url_request_context/system/0x?/cookie_monster/cookies",
- "net/url_request_context/system/0x?/cookie_monster/tasks_pending_global",
- "net/url_request_context/system/0x?/cookie_monster/tasks_pending_for_key",
- "net/url_request_context/system/0x?/http_cache",
- "net/url_request_context/system/0x?/http_cache/memory_backend",
- "net/url_request_context/system/0x?/http_cache/simple_backend",
- "net/url_request_context/system/0x?/http_network_session",
- "net/url_request_context/unknown",
- "net/url_request_context/unknown/0x?",
- "net/url_request_context/unknown/0x?/cookie_monster",
- "net/url_request_context/unknown/0x?/cookie_monster/cookies",
- "net/url_request_context/unknown/0x?/cookie_monster/tasks_pending_global",
- "net/url_request_context/unknown/0x?/cookie_monster/tasks_pending_for_key",
- "net/url_request_context/unknown/0x?/http_cache",
- "net/url_request_context/unknown/0x?/http_cache/memory_backend",
- "net/url_request_context/unknown/0x?/http_cache/simple_backend",
- "net/url_request_context/unknown/0x?/http_network_session",
- "omnibox/autocomplete_controller/0x?",
- "omnibox/in_memory_url_index/0x?",
- "web_cache/Image_resources",
- "web_cache/CSS stylesheet_resources",
- "web_cache/Script_resources",
- "web_cache/XSL stylesheet_resources",
- "web_cache/Font_resources",
- "web_cache/Other_resources",
- "partition_alloc/allocated_objects",
- "partition_alloc/partitions",
- "partition_alloc/partitions/array_buffer",
- "partition_alloc/partitions/buffer",
- "partition_alloc/partitions/fast_malloc",
- "partition_alloc/partitions/layout",
- "skia/sk_glyph_cache",
- "skia/sk_resource_cache",
- "sqlite",
- "ui/resource_manager_0x?/default_resource/0x?",
- "ui/resource_manager_0x?/tinted_resource",
- "v8/isolate_0x?/contexts/detached_context",
- "v8/isolate_0x?/contexts/native_context",
- "v8/isolate_0x?/heap_spaces",
- "v8/isolate_0x?/heap_spaces/code_space",
- "v8/isolate_0x?/heap_spaces/large_object_space",
- "v8/isolate_0x?/heap_spaces/map_space",
- "v8/isolate_0x?/heap_spaces/new_space",
- "v8/isolate_0x?/heap_spaces/old_space",
- "v8/isolate_0x?/heap_spaces/read_only_space",
- "v8/isolate_0x?/malloc",
- "v8/isolate_0x?/zapped_for_debug",
- "site_storage/blob_storage/0x?",
- "site_storage/index_db/db_0x?",
- "site_storage/index_db/memenv_0x?",
- "site_storage/localstorage/0x?/cache_size",
- "site_storage/localstorage/0x?/leveldb",
- "site_storage/session_storage/0x?",
- "site_storage/session_storage/0x?/cache_size",
- "sync/0x?/kernel",
- "sync/0x?/store",
- "sync/0x?/model_type/APP",
- "sync/0x?/model_type/APP_LIST",
- "sync/0x?/model_type/APP_NOTIFICATION",
- "sync/0x?/model_type/APP_SETTING",
- "sync/0x?/model_type/ARC_PACKAGE",
- "sync/0x?/model_type/ARTICLE",
- "sync/0x?/model_type/AUTOFILL",
- "sync/0x?/model_type/AUTOFILL_PROFILE",
- "sync/0x?/model_type/AUTOFILL_WALLET",
- "sync/0x?/model_type/BOOKMARK",
- "sync/0x?/model_type/DEVICE_INFO",
- "sync/0x?/model_type/DICTIONARY",
- "sync/0x?/model_type/EXPERIMENTS",
- "sync/0x?/model_type/EXTENSION",
- "sync/0x?/model_type/EXTENSION_SETTING",
- "sync/0x?/model_type/FAVICON_IMAGE",
- "sync/0x?/model_type/FAVICON_TRACKING",
- "sync/0x?/model_type/HISTORY_DELETE_DIRECTIVE",
- "sync/0x?/model_type/MANAGED_USER",
- "sync/0x?/model_type/MANAGED_USER_SETTING",
- "sync/0x?/model_type/MANAGED_USER_SHARED_SETTING",
- "sync/0x?/model_type/MANAGED_USER_WHITELIST",
- "sync/0x?/model_type/NIGORI",
- "sync/0x?/model_type/PASSWORD",
- "sync/0x?/model_type/PREFERENCE",
- "sync/0x?/model_type/PRINTER",
- "sync/0x?/model_type/PRIORITY_PREFERENCE",
- "sync/0x?/model_type/READING_LIST",
- "sync/0x?/model_type/SEARCH_ENGINE",
- "sync/0x?/model_type/SESSION",
- "sync/0x?/model_type/SYNCED_NOTIFICATION",
- "sync/0x?/model_type/SYNCED_NOTIFICATION_APP_INFO",
- "sync/0x?/model_type/THEME",
- "sync/0x?/model_type/TYPED_URL",
- "sync/0x?/model_type/USER_EVENT",
- "sync/0x?/model_type/WALLET_METADATA",
- "sync/0x?/model_type/WIFI_CREDENTIAL",
- "tab_restore/service_helper_0x?/entries",
- "tab_restore/service_helper_0x?/entries/tab_0x?",
- "tab_restore/service_helper_0x?/entries/window_0x?",
- "tracing/heap_profiler_blink_gc/AllocationRegister",
- "tracing/heap_profiler_malloc/AllocationRegister",
- "tracing/heap_profiler_partition_alloc/AllocationRegister",
- nullptr // End of list marker.
-};
-
-const char* const* g_dump_provider_whitelist = kDumpProviderWhitelist;
-const char* const* g_allocator_dump_name_whitelist =
- kAllocatorDumpNameWhitelist;
-
-bool IsMemoryDumpProviderInList(const char* mdp_name, const char* const* list) {
- for (size_t i = 0; list[i] != nullptr; ++i) {
- if (strcmp(mdp_name, list[i]) == 0)
- return true;
- }
- return false;
-}
-
-} // namespace
-
-bool IsMemoryDumpProviderWhitelisted(const char* mdp_name) {
- return IsMemoryDumpProviderInList(mdp_name, g_dump_provider_whitelist);
-}
-
-bool IsMemoryAllocatorDumpNameWhitelisted(const std::string& name) {
- // Global dumps are explicitly whitelisted for background use.
- if (base::StartsWith(name, "global/", CompareCase::SENSITIVE)) {
- for (size_t i = strlen("global/"); i < name.size(); i++)
- if (!base::IsHexDigit(name[i]))
- return false;
- return true;
- }
-
- if (base::StartsWith(name, "shared_memory/", CompareCase::SENSITIVE)) {
- for (size_t i = strlen("shared_memory/"); i < name.size(); i++)
- if (!base::IsHexDigit(name[i]))
- return false;
- return true;
- }
-
- // Remove special characters, numbers (including hexadecimal which are marked
- // by '0x') from the given string.
- const size_t length = name.size();
- std::string stripped_str;
- stripped_str.reserve(length);
- bool parsing_hex = false;
- for (size_t i = 0; i < length; ++i) {
- if (parsing_hex && isxdigit(name[i]))
- continue;
- parsing_hex = false;
- if (i + 1 < length && name[i] == '0' && name[i + 1] == 'x') {
- parsing_hex = true;
- stripped_str.append("0x?");
- ++i;
- } else {
- stripped_str.push_back(name[i]);
- }
- }
-
- for (size_t i = 0; g_allocator_dump_name_whitelist[i] != nullptr; ++i) {
- if (stripped_str == g_allocator_dump_name_whitelist[i]) {
- return true;
- }
- }
- return false;
-}
-
-void SetDumpProviderWhitelistForTesting(const char* const* list) {
- g_dump_provider_whitelist = list;
-}
-
-void SetAllocatorDumpNameWhitelistForTesting(const char* const* list) {
- g_allocator_dump_name_whitelist = list;
-}
-
-} // namespace trace_event
-} // namespace base
diff --git a/base/trace_event/memory_infra_background_whitelist.h b/base/trace_event/memory_infra_background_whitelist.h
deleted file mode 100644
index b8d704a..0000000
--- a/base/trace_event/memory_infra_background_whitelist.h
+++ /dev/null
@@ -1,33 +0,0 @@
-// Copyright 2016 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_MEMORY_INFRA_BACKGROUND_WHITELIST_H_
-#define BASE_TRACE_EVENT_MEMORY_INFRA_BACKGROUND_WHITELIST_H_
-
-// This file contains the whitelists for background mode to limit the tracing
-// overhead and remove sensitive information from traces.
-
-#include <string>
-
-#include "base/base_export.h"
-
-namespace base {
-namespace trace_event {
-
-// Checks if the given |mdp_name| is in the whitelist.
-bool BASE_EXPORT IsMemoryDumpProviderWhitelisted(const char* mdp_name);
-
-// Checks if the given |name| matches any of the whitelisted patterns.
-bool BASE_EXPORT IsMemoryAllocatorDumpNameWhitelisted(const std::string& name);
-
-// The whitelist is replaced with the given list for tests. The last element of
-// the list must be nullptr.
-void BASE_EXPORT SetDumpProviderWhitelistForTesting(const char* const* list);
-void BASE_EXPORT
-SetAllocatorDumpNameWhitelistForTesting(const char* const* list);
-
-} // namespace trace_event
-} // namespace base
-
-#endif // BASE_TRACE_EVENT_MEMORY_INFRA_BACKGROUND_WHITELIST_H_
diff --git a/base/trace_event/memory_peak_detector.cc b/base/trace_event/memory_peak_detector.cc
deleted file mode 100644
index 5f2ea91..0000000
--- a/base/trace_event/memory_peak_detector.cc
+++ /dev/null
@@ -1,288 +0,0 @@
-// Copyright 2017 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/memory_peak_detector.h"
-
-#include <algorithm>
-
-#include "base/bind.h"
-#include "base/logging.h"
-#include "base/sys_info.h"
-#include "base/threading/sequenced_task_runner_handle.h"
-#include "base/time/time.h"
-#include "base/trace_event/memory_dump_manager.h"
-#include "base/trace_event/memory_dump_provider_info.h"
-#include "base/trace_event/trace_event.h"
-#include "build_config.h"
-
-namespace base {
-namespace trace_event {
-
-// static
-MemoryPeakDetector* MemoryPeakDetector::GetInstance() {
- static MemoryPeakDetector* instance = new MemoryPeakDetector();
- return instance;
-}
-
-MemoryPeakDetector::MemoryPeakDetector()
- : generation_(0),
- state_(NOT_INITIALIZED),
- poll_tasks_count_for_testing_(0) {}
-
-MemoryPeakDetector::~MemoryPeakDetector() {
- // This is hit only in tests, in which case the test is expected to TearDown()
- // cleanly and not leave the peak detector running.
- DCHECK_EQ(NOT_INITIALIZED, state_);
-}
-
-void MemoryPeakDetector::Setup(
- const GetDumpProvidersFunction& get_dump_providers_function,
- const scoped_refptr<SequencedTaskRunner>& task_runner,
- const OnPeakDetectedCallback& on_peak_detected_callback) {
- DCHECK(!get_dump_providers_function.is_null());
- DCHECK(task_runner);
- DCHECK(!on_peak_detected_callback.is_null());
- DCHECK(state_ == NOT_INITIALIZED || state_ == DISABLED);
- DCHECK(dump_providers_.empty());
- get_dump_providers_function_ = get_dump_providers_function;
- task_runner_ = task_runner;
- on_peak_detected_callback_ = on_peak_detected_callback;
- state_ = DISABLED;
- config_ = {};
- ResetPollHistory();
-
- static_threshold_bytes_ = 0;
-#if !defined(OS_NACL)
- // Set threshold to 1% of total system memory.
- static_threshold_bytes_ =
- static_cast<uint64_t>(SysInfo::AmountOfPhysicalMemory()) / 100;
-#endif
- // Fallback, mostly for test environments where AmountOfPhysicalMemory() is
- // broken.
- static_threshold_bytes_ =
- std::max(static_threshold_bytes_, static_cast<uint64_t>(5 * 1024 * 1024));
-}
-
-void MemoryPeakDetector::TearDown() {
- if (task_runner_) {
- task_runner_->PostTask(
- FROM_HERE,
- BindOnce(&MemoryPeakDetector::TearDownInternal, Unretained(this)));
- }
- task_runner_ = nullptr;
-}
-
-void MemoryPeakDetector::Start(MemoryPeakDetector::Config config) {
- if (!config.polling_interval_ms) {
- NOTREACHED();
- return;
- }
- task_runner_->PostTask(FROM_HERE, BindOnce(&MemoryPeakDetector::StartInternal,
- Unretained(this), config));
-}
-
-void MemoryPeakDetector::Stop() {
- task_runner_->PostTask(
- FROM_HERE, BindOnce(&MemoryPeakDetector::StopInternal, Unretained(this)));
-}
-
-void MemoryPeakDetector::Throttle() {
- if (!task_runner_)
- return; // Can be called before Setup().
- task_runner_->PostTask(
- FROM_HERE, BindOnce(&MemoryPeakDetector::ResetPollHistory,
- Unretained(this), true /* keep_last_sample */));
-}
-
-void MemoryPeakDetector::NotifyMemoryDumpProvidersChanged() {
- if (!task_runner_)
- return; // Can be called before Setup().
- task_runner_->PostTask(
- FROM_HERE,
- BindOnce(&MemoryPeakDetector::ReloadDumpProvidersAndStartPollingIfNeeded,
- Unretained(this)));
-}
-
-void MemoryPeakDetector::StartInternal(MemoryPeakDetector::Config config) {
- DCHECK_EQ(DISABLED, state_);
- state_ = ENABLED;
- config_ = config;
- ResetPollHistory();
-
- // If there are any dump providers available,
- // NotifyMemoryDumpProvidersChanged will fetch them and start the polling.
- // Otherwise this will remain in the ENABLED state and the actual polling
- // will start on the next call to
- // ReloadDumpProvidersAndStartPollingIfNeeded().
- // Depending on the sandbox model, it is possible that no polling-capable
- // dump providers will be ever available.
- ReloadDumpProvidersAndStartPollingIfNeeded();
-}
-
-void MemoryPeakDetector::StopInternal() {
- DCHECK_NE(NOT_INITIALIZED, state_);
- state_ = DISABLED;
- ++generation_;
- for (const scoped_refptr<MemoryDumpProviderInfo>& mdp_info : dump_providers_)
- mdp_info->dump_provider->SuspendFastMemoryPolling();
- dump_providers_.clear();
-}
-
-void MemoryPeakDetector::TearDownInternal() {
- StopInternal();
- get_dump_providers_function_.Reset();
- on_peak_detected_callback_.Reset();
- state_ = NOT_INITIALIZED;
-}
-
-void MemoryPeakDetector::ReloadDumpProvidersAndStartPollingIfNeeded() {
- if (state_ == DISABLED || state_ == NOT_INITIALIZED)
- return; // Start() will re-fetch the MDP list later.
-
- DCHECK((state_ == RUNNING && !dump_providers_.empty()) ||
- (state_ == ENABLED && dump_providers_.empty()));
-
- dump_providers_.clear();
-
- // This is really MemoryDumpManager::GetDumpProvidersForPolling, % testing.
- get_dump_providers_function_.Run(&dump_providers_);
-
- if (state_ == ENABLED && !dump_providers_.empty()) {
- // It's now time to start polling for realz.
- state_ = RUNNING;
- task_runner_->PostTask(
- FROM_HERE, BindOnce(&MemoryPeakDetector::PollMemoryAndDetectPeak,
- Unretained(this), ++generation_));
- } else if (state_ == RUNNING && dump_providers_.empty()) {
- // Will cause the next PollMemoryAndDetectPeak() task to early return.
- state_ = ENABLED;
- ++generation_;
- }
-}
-
-void MemoryPeakDetector::PollMemoryAndDetectPeak(uint32_t expected_generation) {
- if (state_ != RUNNING || generation_ != expected_generation)
- return;
-
- // We should never end up in a situation where state_ == RUNNING but all dump
- // providers are gone.
- DCHECK(!dump_providers_.empty());
-
- poll_tasks_count_for_testing_++;
- uint64_t polled_mem_bytes = 0;
- for (const scoped_refptr<MemoryDumpProviderInfo>& mdp_info :
- dump_providers_) {
- DCHECK(mdp_info->options.is_fast_polling_supported);
- uint64_t value = 0;
- mdp_info->dump_provider->PollFastMemoryTotal(&value);
- polled_mem_bytes += value;
- }
- if (config_.enable_verbose_poll_tracing) {
- TRACE_COUNTER1(MemoryDumpManager::kTraceCategory, "PolledMemoryMB",
- polled_mem_bytes / 1024 / 1024);
- }
-
- // Peak detection logic. Design doc: https://goo.gl/0kOU4A .
- bool is_peak = false;
- if (skip_polls_ > 0) {
- skip_polls_--;
- } else if (last_dump_memory_total_ == 0) {
- last_dump_memory_total_ = polled_mem_bytes;
- } else if (polled_mem_bytes > 0) {
- int64_t diff_from_last_dump = polled_mem_bytes - last_dump_memory_total_;
-
- DCHECK_GT(static_threshold_bytes_, 0u);
- is_peak =
- diff_from_last_dump > static_cast<int64_t>(static_threshold_bytes_);
-
- if (!is_peak)
- is_peak = DetectPeakUsingSlidingWindowStddev(polled_mem_bytes);
- }
-
- DCHECK_GT(config_.polling_interval_ms, 0u);
- SequencedTaskRunnerHandle::Get()->PostDelayedTask(
- FROM_HERE,
- BindOnce(&MemoryPeakDetector::PollMemoryAndDetectPeak, Unretained(this),
- expected_generation),
- TimeDelta::FromMilliseconds(config_.polling_interval_ms));
-
- if (!is_peak)
- return;
- TRACE_EVENT_INSTANT1(MemoryDumpManager::kTraceCategory,
- "Peak memory detected", TRACE_EVENT_SCOPE_PROCESS,
- "PolledMemoryMB", polled_mem_bytes / 1024 / 1024);
- ResetPollHistory(true /* keep_last_sample */);
- last_dump_memory_total_ = polled_mem_bytes;
- on_peak_detected_callback_.Run();
-}
-
-bool MemoryPeakDetector::DetectPeakUsingSlidingWindowStddev(
- uint64_t polled_mem_bytes) {
- DCHECK(polled_mem_bytes);
- samples_bytes_[samples_index_] = polled_mem_bytes;
- samples_index_ = (samples_index_ + 1) % kSlidingWindowNumSamples;
- float mean = 0;
- for (uint32_t i = 0; i < kSlidingWindowNumSamples; ++i) {
- if (samples_bytes_[i] == 0)
- return false; // Not enough samples to detect peaks.
- mean += samples_bytes_[i];
- }
- mean /= kSlidingWindowNumSamples;
- float variance = 0;
- for (uint32_t i = 0; i < kSlidingWindowNumSamples; ++i) {
- const float deviation = samples_bytes_[i] - mean;
- variance += deviation * deviation;
- }
- variance /= kSlidingWindowNumSamples;
-
- // If stddev is less than 0.2% then we consider that the process is inactive.
- if (variance < (mean / 500) * (mean / 500))
- return false;
-
- // (mean + 3.69 * stddev) corresponds to a value that is higher than current
- // sample with 99.99% probability.
- const float cur_sample_deviation = polled_mem_bytes - mean;
- return cur_sample_deviation * cur_sample_deviation > (3.69 * 3.69 * variance);
-}
-
-void MemoryPeakDetector::ResetPollHistory(bool keep_last_sample) {
- // TODO(primiano,ssid): this logic should probably be revisited. In the case
- // of Android, the browser process sees the total of all processes memory in
- // the same peak detector instance. Perhaps the best thing to do here is to
- // keep the window of samples around and just bump the skip_polls_.
- last_dump_memory_total_ = 0;
- if (keep_last_sample) {
- const uint32_t prev_index =
- samples_index_ > 0 ? samples_index_ - 1 : kSlidingWindowNumSamples - 1;
- last_dump_memory_total_ = samples_bytes_[prev_index];
- }
- memset(samples_bytes_, 0, sizeof(samples_bytes_));
- samples_index_ = 0;
- skip_polls_ = 0;
- if (config_.polling_interval_ms > 0) {
- skip_polls_ =
- (config_.min_time_between_peaks_ms + config_.polling_interval_ms - 1) /
- config_.polling_interval_ms;
- }
-}
-
-void MemoryPeakDetector::SetStaticThresholdForTesting(
- uint64_t static_threshold_bytes) {
- DCHECK_EQ(DISABLED, state_);
- static_threshold_bytes_ = static_threshold_bytes;
-}
-
-MemoryPeakDetector::MemoryPeakDetector::Config::Config()
- : Config(0, 0, false) {}
-
-MemoryPeakDetector::MemoryPeakDetector::Config::Config(
- uint32_t polling_interval_ms,
- uint32_t min_time_between_peaks_ms,
- bool enable_verbose_poll_tracing)
- : polling_interval_ms(polling_interval_ms),
- min_time_between_peaks_ms(min_time_between_peaks_ms),
- enable_verbose_poll_tracing(enable_verbose_poll_tracing) {}
-
-} // namespace trace_event
-} // namespace base
diff --git a/base/trace_event/memory_peak_detector.h b/base/trace_event/memory_peak_detector.h
deleted file mode 100644
index bbe205b..0000000
--- a/base/trace_event/memory_peak_detector.h
+++ /dev/null
@@ -1,184 +0,0 @@
-// Copyright 2017 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_MEMORY_PEAK_DETECTOR_H_
-#define BASE_TRACE_EVENT_MEMORY_PEAK_DETECTOR_H_
-
-#include <stdint.h>
-
-#include <memory>
-#include <vector>
-
-#include "base/base_export.h"
-#include "base/callback.h"
-#include "base/macros.h"
-#include "base/memory/ref_counted.h"
-
-namespace base {
-
-class SequencedTaskRunner;
-
-namespace trace_event {
-
-struct MemoryDumpProviderInfo;
-
-// Detects temporally local memory peaks. Peak detection is based on
-// continuously querying memory usage using MemoryDumpprovider(s) that support
-// fast polling (e.g., ProcessMetricsDumpProvider which under the hoods reads
-// /proc/PID/statm on Linux) and using a combination of:
-// - An static threshold (currently 1% of total system memory).
-// - Sliding window stddev analysis.
-// Design doc: https://goo.gl/0kOU4A .
-// This class is NOT thread-safe, the caller has to ensure linearization of
-// the calls to the public methods. In any case, the public methods do NOT have
-// to be called from the |task_runner| on which the polling tasks run.
-class BASE_EXPORT MemoryPeakDetector {
- public:
- using OnPeakDetectedCallback = RepeatingClosure;
- using DumpProvidersList = std::vector<scoped_refptr<MemoryDumpProviderInfo>>;
- using GetDumpProvidersFunction = RepeatingCallback<void(DumpProvidersList*)>;
-
- enum State {
- NOT_INITIALIZED = 0, // Before Setup()
- DISABLED, // Before Start() or after Stop().
- ENABLED, // After Start() but no dump_providers_ are available.
- RUNNING // After Start(). The PollMemoryAndDetectPeak() task is scheduled.
- };
-
- // Peak detector configuration, passed to Start().
- struct BASE_EXPORT Config {
- Config();
- Config(uint32_t polling_interval_ms,
- uint32_t min_time_between_peaks_ms,
- bool enable_verbose_poll_tracing);
-
- // The rate at which memory will be polled. Polls will happen on the task
- // runner passed to Setup().
- uint32_t polling_interval_ms;
-
- // Two consecutive peak detection callbacks will happen at least
- // |min_time_between_peaks_ms| apart from each other.
- uint32_t min_time_between_peaks_ms;
-
- // When enabled causes a TRACE_COUNTER event to be injected in the trace
- // for each poll (if tracing is enabled).
- bool enable_verbose_poll_tracing;
- };
-
- static MemoryPeakDetector* GetInstance();
-
- // Configures the peak detector, binding the polling tasks on the given
- // thread. Setup() can be called several times, provided that: (1) Stop()
- // is called; (2a) the previous task_runner is flushed or (2b) the task_runner
- // remains the same.
- // GetDumpProvidersFunction: is the function that will be invoked to get
- // an updated list of polling-capable dump providers. This is really just
- // MemoryDumpManager::GetDumpProvidersForPolling, but this extra level of
- // indirection allows easier testing.
- // SequencedTaskRunner: the task runner where PollMemoryAndDetectPeak() will
- // be periodically called.
- // OnPeakDetectedCallback: a callback that will be invoked on the
- // given task runner when a memory peak is detected.
- void Setup(const GetDumpProvidersFunction&,
- const scoped_refptr<SequencedTaskRunner>&,
- const OnPeakDetectedCallback&);
-
- // Releases the |task_runner_| and the bound callbacks.
- void TearDown();
-
- // This posts a task onto the passed task runner which refreshes the list of
- // dump providers via the GetDumpProvidersFunction. If at least one dump
- // provider is available, this starts immediately polling on the task runner.
- // If not, the detector remains in the ENABLED state and will start polling
- // automatically (i.e. without requiring another call to Start()) on the
- // next call to NotifyMemoryDumpProvidersChanged().
- void Start(Config);
-
- // Stops the polling on the task runner (if was active at all). This doesn't
- // wait for the task runner to drain pending tasks, so it is possible that
- // a polling will happen concurrently (or in the immediate future) with the
- // Stop() call. It is responsibility of the caller to drain or synchronize
- // with the task runner.
- void Stop();
-
- // If Start()-ed, prevents that a peak callback is triggered before the next
- // |min_time_between_peaks_ms|. No-op if the peak detector is not enabled.
- void Throttle();
-
- // Used by MemoryDumpManager to notify that the list of polling-capable dump
- // providers has changed. The peak detector will reload the list on the next
- // polling task. This function can be called before Setup(), in which
- // case will be just a no-op.
- void NotifyMemoryDumpProvidersChanged();
-
- void SetStaticThresholdForTesting(uint64_t static_threshold_bytes);
-
- private:
- friend class MemoryPeakDetectorTest;
-
- static constexpr uint32_t kSlidingWindowNumSamples = 50;
-
- MemoryPeakDetector();
- ~MemoryPeakDetector();
-
- // All these methods are always called on the |task_runner_|.
- void StartInternal(Config);
- void StopInternal();
- void TearDownInternal();
- void ReloadDumpProvidersAndStartPollingIfNeeded();
- void PollMemoryAndDetectPeak(uint32_t expected_generation);
- bool DetectPeakUsingSlidingWindowStddev(uint64_t last_sample_bytes);
- void ResetPollHistory(bool keep_last_sample = false);
-
- // It is safe to call these testing methods only on the |task_runner_|.
- State state_for_testing() const { return state_; }
- uint32_t poll_tasks_count_for_testing() const {
- return poll_tasks_count_for_testing_;
- }
-
- // The task runner where all the internal calls are posted onto. This field
- // must be NOT be accessed by the tasks posted on the |task_runner_| because
- // there might still be outstanding tasks on the |task_runner_| while this
- // refptr is reset. This can only be safely accessed by the public methods
- // above, which the client of this class is supposed to call sequentially.
- scoped_refptr<SequencedTaskRunner> task_runner_;
-
- // After the Setup() call, the fields below, must be accessed only from
- // the |task_runner_|.
-
- // Bound function to get an updated list of polling-capable dump providers.
- GetDumpProvidersFunction get_dump_providers_function_;
-
- // The callback to invoke when peaks are detected.
- OnPeakDetectedCallback on_peak_detected_callback_;
-
- // List of polling-aware dump providers to invoke upon each poll.
- DumpProvidersList dump_providers_;
-
- // The generation is incremented every time the |state_| is changed and causes
- // PollMemoryAndDetectPeak() to early out if the posted task doesn't match the
- // most recent |generation_|. This allows to drop on the floor outstanding
- // PostDelayedTask that refer to an old sequence that was later Stop()-ed or
- // disabled because of NotifyMemoryDumpProvidersChanged().
- uint32_t generation_;
-
- State state_;
-
- // Config passed to Start(), only valid when |state_| = {ENABLED, RUNNING}.
- Config config_;
-
- uint64_t static_threshold_bytes_;
- uint32_t skip_polls_;
- uint64_t last_dump_memory_total_;
- uint64_t samples_bytes_[kSlidingWindowNumSamples];
- uint32_t samples_index_;
- uint32_t poll_tasks_count_for_testing_;
-
- DISALLOW_COPY_AND_ASSIGN(MemoryPeakDetector);
-};
-
-} // namespace trace_event
-} // namespace base
-
-#endif // BASE_TRACE_EVENT_MEMORY_PEAK_DETECTOR_H_
diff --git a/base/trace_event/memory_usage_estimator.cc b/base/trace_event/memory_usage_estimator.cc
deleted file mode 100644
index c769d5b..0000000
--- a/base/trace_event/memory_usage_estimator.cc
+++ /dev/null
@@ -1,14 +0,0 @@
-// Copyright 2016 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/memory_usage_estimator.h"
-
-namespace base {
-namespace trace_event {
-
-template size_t EstimateMemoryUsage(const std::string&);
-template size_t EstimateMemoryUsage(const string16&);
-
-} // namespace trace_event
-} // namespace base
diff --git a/base/trace_event/memory_usage_estimator.h b/base/trace_event/memory_usage_estimator.h
deleted file mode 100644
index 214c64a..0000000
--- a/base/trace_event/memory_usage_estimator.h
+++ /dev/null
@@ -1,654 +0,0 @@
-// Copyright 2016 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_MEMORY_USAGE_ESTIMATOR_H_
-#define BASE_TRACE_EVENT_MEMORY_USAGE_ESTIMATOR_H_
-
-#include <stdint.h>
-
-#include <array>
-#include <deque>
-#include <list>
-#include <map>
-#include <memory>
-#include <queue>
-#include <set>
-#include <stack>
-#include <string>
-#include <type_traits>
-#include <unordered_map>
-#include <unordered_set>
-#include <vector>
-
-#include "base/base_export.h"
-#include "base/containers/circular_deque.h"
-#include "base/containers/flat_map.h"
-#include "base/containers/flat_set.h"
-#include "base/containers/linked_list.h"
-#include "base/containers/mru_cache.h"
-#include "base/containers/queue.h"
-#include "base/stl_util.h"
-#include "base/strings/string16.h"
-#include "base/template_util.h"
-
-// Composable memory usage estimators.
-//
-// This file defines set of EstimateMemoryUsage(object) functions that return
-// approximate memory usage of their argument.
-//
-// The ultimate goal is to make memory usage estimation for a class simply a
-// matter of aggregating EstimateMemoryUsage() results over all fields.
-//
-// That is achieved via composability: if EstimateMemoryUsage() is defined
-// for T then EstimateMemoryUsage() is also defined for any combination of
-// containers holding T (e.g. std::map<int, std::vector<T>>).
-//
-// There are two ways of defining EstimateMemoryUsage() for a type:
-//
-// 1. As a global function 'size_t EstimateMemoryUsage(T)' in
-// in base::trace_event namespace.
-//
-// 2. As 'size_t T::EstimateMemoryUsage() const' method. In this case
-// EstimateMemoryUsage(T) function in base::trace_event namespace is
-// provided automatically.
-//
-// Here is an example implementation:
-//
-// size_t foo::bar::MyClass::EstimateMemoryUsage() const {
-// return base::trace_event::EstimateMemoryUsage(name_) +
-// base::trace_event::EstimateMemoryUsage(id_) +
-// base::trace_event::EstimateMemoryUsage(items_);
-// }
-//
-// The approach is simple: first call EstimateMemoryUsage() on all members,
-// then recursively fix compilation errors that are caused by types not
-// implementing EstimateMemoryUsage().
-
-namespace base {
-namespace trace_event {
-
-// Declarations
-
-// If T declares 'EstimateMemoryUsage() const' member function, then
-// global function EstimateMemoryUsage(T) is available, and just calls
-// the member function.
-template <class T>
-auto EstimateMemoryUsage(const T& object)
- -> decltype(object.EstimateMemoryUsage());
-
-// String
-
-template <class C, class T, class A>
-size_t EstimateMemoryUsage(const std::basic_string<C, T, A>& string);
-
-// Arrays
-
-template <class T, size_t N>
-size_t EstimateMemoryUsage(const std::array<T, N>& array);
-
-template <class T, size_t N>
-size_t EstimateMemoryUsage(T (&array)[N]);
-
-template <class T>
-size_t EstimateMemoryUsage(const T* array, size_t array_length);
-
-// std::unique_ptr
-
-template <class T, class D>
-size_t EstimateMemoryUsage(const std::unique_ptr<T, D>& ptr);
-
-template <class T, class D>
-size_t EstimateMemoryUsage(const std::unique_ptr<T[], D>& array,
- size_t array_length);
-
-// std::shared_ptr
-
-template <class T>
-size_t EstimateMemoryUsage(const std::shared_ptr<T>& ptr);
-
-// Containers
-
-template <class F, class S>
-size_t EstimateMemoryUsage(const std::pair<F, S>& pair);
-
-template <class T, class A>
-size_t EstimateMemoryUsage(const std::vector<T, A>& vector);
-
-template <class T, class A>
-size_t EstimateMemoryUsage(const std::list<T, A>& list);
-
-template <class T>
-size_t EstimateMemoryUsage(const base::LinkedList<T>& list);
-
-template <class T, class C, class A>
-size_t EstimateMemoryUsage(const std::set<T, C, A>& set);
-
-template <class T, class C, class A>
-size_t EstimateMemoryUsage(const std::multiset<T, C, A>& set);
-
-template <class K, class V, class C, class A>
-size_t EstimateMemoryUsage(const std::map<K, V, C, A>& map);
-
-template <class K, class V, class C, class A>
-size_t EstimateMemoryUsage(const std::multimap<K, V, C, A>& map);
-
-template <class T, class H, class KE, class A>
-size_t EstimateMemoryUsage(const std::unordered_set<T, H, KE, A>& set);
-
-template <class T, class H, class KE, class A>
-size_t EstimateMemoryUsage(const std::unordered_multiset<T, H, KE, A>& set);
-
-template <class K, class V, class H, class KE, class A>
-size_t EstimateMemoryUsage(const std::unordered_map<K, V, H, KE, A>& map);
-
-template <class K, class V, class H, class KE, class A>
-size_t EstimateMemoryUsage(const std::unordered_multimap<K, V, H, KE, A>& map);
-
-template <class T, class A>
-size_t EstimateMemoryUsage(const std::deque<T, A>& deque);
-
-template <class T, class C>
-size_t EstimateMemoryUsage(const std::queue<T, C>& queue);
-
-template <class T, class C>
-size_t EstimateMemoryUsage(const std::priority_queue<T, C>& queue);
-
-template <class T, class C>
-size_t EstimateMemoryUsage(const std::stack<T, C>& stack);
-
-template <class T>
-size_t EstimateMemoryUsage(const base::circular_deque<T>& deque);
-
-template <class T, class C>
-size_t EstimateMemoryUsage(const base::flat_set<T, C>& set);
-
-template <class K, class V, class C>
-size_t EstimateMemoryUsage(const base::flat_map<K, V, C>& map);
-
-template <class Key,
- class Payload,
- class HashOrComp,
- template <typename, typename, typename> class Map>
-size_t EstimateMemoryUsage(const MRUCacheBase<Key, Payload, HashOrComp, Map>&);
-
-// TODO(dskiba):
-// std::forward_list
-
-// Definitions
-
-namespace internal {
-
-// HasEMU<T>::value is true iff EstimateMemoryUsage(T) is available.
-// (This is the default version, which is false.)
-template <class T, class X = void>
-struct HasEMU : std::false_type {};
-
-// This HasEMU specialization is only picked up if there exists function
-// EstimateMemoryUsage(const T&) that returns size_t. Simpler ways to
-// achieve this don't work on MSVC.
-template <class T>
-struct HasEMU<
- T,
- typename std::enable_if<std::is_same<
- size_t,
- decltype(EstimateMemoryUsage(std::declval<const T&>()))>::value>::type>
- : std::true_type {};
-
-// EMUCaller<T> does three things:
-// 1. Defines Call() method that calls EstimateMemoryUsage(T) if it's
-// available.
-// 2. If EstimateMemoryUsage(T) is not available, but T has trivial dtor
-// (i.e. it's POD, integer, pointer, enum, etc.) then it defines Call()
-// method that returns 0. This is useful for containers, which allocate
-// memory regardless of T (also for cases like std::map<int, MyClass>).
-// 3. Finally, if EstimateMemoryUsage(T) is not available, then it triggers
-// a static_assert with a helpful message. That cuts numbers of errors
-// considerably - if you just call EstimateMemoryUsage(T) but it's not
-// available for T, then compiler will helpfully list *all* possible
-// variants of it, with an explanation for each.
-template <class T, class X = void>
-struct EMUCaller {
- // std::is_same<> below makes static_assert depend on T, in order to
- // prevent it from asserting regardless instantiation.
- static_assert(std::is_same<T, std::false_type>::value,
- "Neither global function 'size_t EstimateMemoryUsage(T)' "
- "nor member function 'size_t T::EstimateMemoryUsage() const' "
- "is defined for the type.");
-
- static size_t Call(const T&) { return 0; }
-};
-
-template <class T>
-struct EMUCaller<T, typename std::enable_if<HasEMU<T>::value>::type> {
- static size_t Call(const T& value) { return EstimateMemoryUsage(value); }
-};
-
-template <template <class...> class Container, class I, class = void>
-struct IsComplexIteratorForContainer : std::false_type {};
-
-template <template <class...> class Container, class I>
-struct IsComplexIteratorForContainer<
- Container,
- I,
- std::enable_if_t<!std::is_pointer<I>::value &&
- base::internal::is_iterator<I>::value>> {
- using value_type = typename std::iterator_traits<I>::value_type;
- using container_type = Container<value_type>;
-
- // We use enum instead of static constexpr bool, beause we don't have inline
- // variables until c++17.
- //
- // The downside is - value is not of type bool.
- enum : bool {
- value =
- std::is_same<typename container_type::iterator, I>::value ||
- std::is_same<typename container_type::const_iterator, I>::value ||
- std::is_same<typename container_type::reverse_iterator, I>::value ||
- std::is_same<typename container_type::const_reverse_iterator, I>::value,
- };
-};
-
-template <class I, template <class...> class... Containers>
-constexpr bool OneOfContainersComplexIterators() {
- // We are forced to create a temporary variable to workaround a compilation
- // error in msvs.
- const bool all_tests[] = {
- IsComplexIteratorForContainer<Containers, I>::value...};
- for (bool test : all_tests)
- if (test)
- return true;
- return false;
-}
-
-// std::array has an extra required template argument. We curry it.
-template <class T>
-using array_test_helper = std::array<T, 1>;
-
-template <class I>
-constexpr bool IsStandardContainerComplexIterator() {
- // TODO(dyaroshev): deal with maps iterators if there is a need.
- // It requires to parse pairs into keys and values.
- // TODO(dyaroshev): deal with unordered containers: they do not have reverse
- // iterators.
- return OneOfContainersComplexIterators<
- I, array_test_helper, std::vector, std::deque,
- /*std::forward_list,*/ std::list, std::set, std::multiset>();
-}
-
-// Work around MSVS bug. For some reason constexpr function doesn't work.
-// However variable template does.
-template <typename T>
-constexpr bool IsKnownNonAllocatingType_v =
- std::is_trivially_destructible<T>::value ||
- IsStandardContainerComplexIterator<T>();
-
-template <class T>
-struct EMUCaller<
- T,
- std::enable_if_t<!HasEMU<T>::value && IsKnownNonAllocatingType_v<T>>> {
- static size_t Call(const T& value) { return 0; }
-};
-
-} // namespace internal
-
-// Proxy that deducts T and calls EMUCaller<T>.
-// To be used by EstimateMemoryUsage() implementations for containers.
-template <class T>
-size_t EstimateItemMemoryUsage(const T& value) {
- return internal::EMUCaller<T>::Call(value);
-}
-
-template <class I>
-size_t EstimateIterableMemoryUsage(const I& iterable) {
- size_t memory_usage = 0;
- for (const auto& item : iterable) {
- memory_usage += EstimateItemMemoryUsage(item);
- }
- return memory_usage;
-}
-
-// Global EstimateMemoryUsage(T) that just calls T::EstimateMemoryUsage().
-template <class T>
-auto EstimateMemoryUsage(const T& object)
- -> decltype(object.EstimateMemoryUsage()) {
- static_assert(
- std::is_same<decltype(object.EstimateMemoryUsage()), size_t>::value,
- "'T::EstimateMemoryUsage() const' must return size_t.");
- return object.EstimateMemoryUsage();
-}
-
-// String
-
-template <class C, class T, class A>
-size_t EstimateMemoryUsage(const std::basic_string<C, T, A>& string) {
- using string_type = std::basic_string<C, T, A>;
- using value_type = typename string_type::value_type;
- // C++11 doesn't leave much room for implementors - std::string can
- // use short string optimization, but that's about it. We detect SSO
- // by checking that c_str() points inside |string|.
- const uint8_t* cstr = reinterpret_cast<const uint8_t*>(string.c_str());
- const uint8_t* inline_cstr = reinterpret_cast<const uint8_t*>(&string);
- if (cstr >= inline_cstr && cstr < inline_cstr + sizeof(string)) {
- // SSO string
- return 0;
- }
- return (string.capacity() + 1) * sizeof(value_type);
-}
-
-// Use explicit instantiations from the .cc file (reduces bloat).
-extern template BASE_EXPORT size_t EstimateMemoryUsage(const std::string&);
-extern template BASE_EXPORT size_t EstimateMemoryUsage(const string16&);
-
-// Arrays
-
-template <class T, size_t N>
-size_t EstimateMemoryUsage(const std::array<T, N>& array) {
- return EstimateIterableMemoryUsage(array);
-}
-
-template <class T, size_t N>
-size_t EstimateMemoryUsage(T (&array)[N]) {
- return EstimateIterableMemoryUsage(array);
-}
-
-template <class T>
-size_t EstimateMemoryUsage(const T* array, size_t array_length) {
- size_t memory_usage = sizeof(T) * array_length;
- for (size_t i = 0; i != array_length; ++i) {
- memory_usage += EstimateItemMemoryUsage(array[i]);
- }
- return memory_usage;
-}
-
-// std::unique_ptr
-
-template <class T, class D>
-size_t EstimateMemoryUsage(const std::unique_ptr<T, D>& ptr) {
- return ptr ? (sizeof(T) + EstimateItemMemoryUsage(*ptr)) : 0;
-}
-
-template <class T, class D>
-size_t EstimateMemoryUsage(const std::unique_ptr<T[], D>& array,
- size_t array_length) {
- return EstimateMemoryUsage(array.get(), array_length);
-}
-
-// std::shared_ptr
-
-template <class T>
-size_t EstimateMemoryUsage(const std::shared_ptr<T>& ptr) {
- auto use_count = ptr.use_count();
- if (use_count == 0) {
- return 0;
- }
- // Model shared_ptr after libc++,
- // see __shared_ptr_pointer from include/memory
- struct SharedPointer {
- void* vtbl;
- long shared_owners;
- long shared_weak_owners;
- T* value;
- };
- // If object of size S shared N > S times we prefer to (potentially)
- // overestimate than to return 0.
- return sizeof(SharedPointer) +
- (EstimateItemMemoryUsage(*ptr) + (use_count - 1)) / use_count;
-}
-
-// std::pair
-
-template <class F, class S>
-size_t EstimateMemoryUsage(const std::pair<F, S>& pair) {
- return EstimateItemMemoryUsage(pair.first) +
- EstimateItemMemoryUsage(pair.second);
-}
-
-// std::vector
-
-template <class T, class A>
-size_t EstimateMemoryUsage(const std::vector<T, A>& vector) {
- return sizeof(T) * vector.capacity() + EstimateIterableMemoryUsage(vector);
-}
-
-// std::list
-
-template <class T, class A>
-size_t EstimateMemoryUsage(const std::list<T, A>& list) {
- using value_type = typename std::list<T, A>::value_type;
- struct Node {
- Node* prev;
- Node* next;
- value_type value;
- };
- return sizeof(Node) * list.size() +
- EstimateIterableMemoryUsage(list);
-}
-
-template <class T>
-size_t EstimateMemoryUsage(const base::LinkedList<T>& list) {
- size_t memory_usage = 0u;
- for (base::LinkNode<T>* node = list.head(); node != list.end();
- node = node->next()) {
- // Since we increment by calling node = node->next() we know that node
- // isn't nullptr.
- memory_usage += EstimateMemoryUsage(*node->value()) + sizeof(T);
- }
- return memory_usage;
-}
-
-// Tree containers
-
-template <class V>
-size_t EstimateTreeMemoryUsage(size_t size) {
- // Tree containers are modeled after libc++
- // (__tree_node from include/__tree)
- struct Node {
- Node* left;
- Node* right;
- Node* parent;
- bool is_black;
- V value;
- };
- return sizeof(Node) * size;
-}
-
-template <class T, class C, class A>
-size_t EstimateMemoryUsage(const std::set<T, C, A>& set) {
- using value_type = typename std::set<T, C, A>::value_type;
- return EstimateTreeMemoryUsage<value_type>(set.size()) +
- EstimateIterableMemoryUsage(set);
-}
-
-template <class T, class C, class A>
-size_t EstimateMemoryUsage(const std::multiset<T, C, A>& set) {
- using value_type = typename std::multiset<T, C, A>::value_type;
- return EstimateTreeMemoryUsage<value_type>(set.size()) +
- EstimateIterableMemoryUsage(set);
-}
-
-template <class K, class V, class C, class A>
-size_t EstimateMemoryUsage(const std::map<K, V, C, A>& map) {
- using value_type = typename std::map<K, V, C, A>::value_type;
- return EstimateTreeMemoryUsage<value_type>(map.size()) +
- EstimateIterableMemoryUsage(map);
-}
-
-template <class K, class V, class C, class A>
-size_t EstimateMemoryUsage(const std::multimap<K, V, C, A>& map) {
- using value_type = typename std::multimap<K, V, C, A>::value_type;
- return EstimateTreeMemoryUsage<value_type>(map.size()) +
- EstimateIterableMemoryUsage(map);
-}
-
-// HashMap containers
-
-namespace internal {
-
-// While hashtable containers model doesn't depend on STL implementation, one
-// detail still crept in: bucket_count. It's used in size estimation, but its
-// value after inserting N items is not predictable.
-// This function is specialized by unittests to return constant value, thus
-// excluding bucket_count from testing.
-template <class V>
-size_t HashMapBucketCountForTesting(size_t bucket_count) {
- return bucket_count;
-}
-
-template <class MruCacheType>
-size_t DoEstimateMemoryUsageForMruCache(const MruCacheType& mru_cache) {
- return EstimateMemoryUsage(mru_cache.ordering_) +
- EstimateMemoryUsage(mru_cache.index_);
-}
-
-} // namespace internal
-
-template <class V>
-size_t EstimateHashMapMemoryUsage(size_t bucket_count, size_t size) {
- // Hashtable containers are modeled after libc++
- // (__hash_node from include/__hash_table)
- struct Node {
- void* next;
- size_t hash;
- V value;
- };
- using Bucket = void*;
- bucket_count = internal::HashMapBucketCountForTesting<V>(bucket_count);
- return sizeof(Bucket) * bucket_count + sizeof(Node) * size;
-}
-
-template <class K, class H, class KE, class A>
-size_t EstimateMemoryUsage(const std::unordered_set<K, H, KE, A>& set) {
- using value_type = typename std::unordered_set<K, H, KE, A>::value_type;
- return EstimateHashMapMemoryUsage<value_type>(set.bucket_count(),
- set.size()) +
- EstimateIterableMemoryUsage(set);
-}
-
-template <class K, class H, class KE, class A>
-size_t EstimateMemoryUsage(const std::unordered_multiset<K, H, KE, A>& set) {
- using value_type = typename std::unordered_multiset<K, H, KE, A>::value_type;
- return EstimateHashMapMemoryUsage<value_type>(set.bucket_count(),
- set.size()) +
- EstimateIterableMemoryUsage(set);
-}
-
-template <class K, class V, class H, class KE, class A>
-size_t EstimateMemoryUsage(const std::unordered_map<K, V, H, KE, A>& map) {
- using value_type = typename std::unordered_map<K, V, H, KE, A>::value_type;
- return EstimateHashMapMemoryUsage<value_type>(map.bucket_count(),
- map.size()) +
- EstimateIterableMemoryUsage(map);
-}
-
-template <class K, class V, class H, class KE, class A>
-size_t EstimateMemoryUsage(const std::unordered_multimap<K, V, H, KE, A>& map) {
- using value_type =
- typename std::unordered_multimap<K, V, H, KE, A>::value_type;
- return EstimateHashMapMemoryUsage<value_type>(map.bucket_count(),
- map.size()) +
- EstimateIterableMemoryUsage(map);
-}
-
-// std::deque
-
-template <class T, class A>
-size_t EstimateMemoryUsage(const std::deque<T, A>& deque) {
-// Since std::deque implementations are wildly different
-// (see crbug.com/674287), we can't have one "good enough"
-// way to estimate.
-
-// kBlockSize - minimum size of a block, in bytes
-// kMinBlockLength - number of elements in a block
-// if sizeof(T) > kBlockSize
-#if defined(_LIBCPP_VERSION)
- size_t kBlockSize = 4096;
- size_t kMinBlockLength = 16;
-#elif defined(__GLIBCXX__)
- size_t kBlockSize = 512;
- size_t kMinBlockLength = 1;
-#elif defined(_MSC_VER)
- size_t kBlockSize = 16;
- size_t kMinBlockLength = 1;
-#else
- size_t kBlockSize = 0;
- size_t kMinBlockLength = 1;
-#endif
-
- size_t block_length =
- (sizeof(T) > kBlockSize) ? kMinBlockLength : kBlockSize / sizeof(T);
-
- size_t blocks = (deque.size() + block_length - 1) / block_length;
-
-#if defined(__GLIBCXX__)
- // libstdc++: deque always has at least one block
- if (!blocks)
- blocks = 1;
-#endif
-
-#if defined(_LIBCPP_VERSION)
- // libc++: deque keeps at most two blocks when it shrinks,
- // so even if the size is zero, deque might be holding up
- // to 4096 * 2 bytes. One way to know whether deque has
- // ever allocated (and hence has 1 or 2 blocks) is to check
- // iterator's pointer. Non-zero value means that deque has
- // at least one block.
- if (!blocks && deque.begin().operator->())
- blocks = 1;
-#endif
-
- return (blocks * block_length * sizeof(T)) +
- EstimateIterableMemoryUsage(deque);
-}
-
-// Container adapters
-
-template <class T, class C>
-size_t EstimateMemoryUsage(const std::queue<T, C>& queue) {
- return EstimateMemoryUsage(GetUnderlyingContainer(queue));
-}
-
-template <class T, class C>
-size_t EstimateMemoryUsage(const std::priority_queue<T, C>& queue) {
- return EstimateMemoryUsage(GetUnderlyingContainer(queue));
-}
-
-template <class T, class C>
-size_t EstimateMemoryUsage(const std::stack<T, C>& stack) {
- return EstimateMemoryUsage(GetUnderlyingContainer(stack));
-}
-
-// base::circular_deque
-
-template <class T>
-size_t EstimateMemoryUsage(const base::circular_deque<T>& deque) {
- return sizeof(T) * deque.capacity() + EstimateIterableMemoryUsage(deque);
-}
-
-// Flat containers
-
-template <class T, class C>
-size_t EstimateMemoryUsage(const base::flat_set<T, C>& set) {
- using value_type = typename base::flat_set<T, C>::value_type;
- return sizeof(value_type) * set.capacity() + EstimateIterableMemoryUsage(set);
-}
-
-template <class K, class V, class C>
-size_t EstimateMemoryUsage(const base::flat_map<K, V, C>& map) {
- using value_type = typename base::flat_map<K, V, C>::value_type;
- return sizeof(value_type) * map.capacity() + EstimateIterableMemoryUsage(map);
-}
-
-template <class Key,
- class Payload,
- class HashOrComp,
- template <typename, typename, typename> class Map>
-size_t EstimateMemoryUsage(
- const MRUCacheBase<Key, Payload, HashOrComp, Map>& mru_cache) {
- return internal::DoEstimateMemoryUsageForMruCache(mru_cache);
-}
-
-} // namespace trace_event
-} // namespace base
-
-#endif // BASE_TRACE_EVENT_MEMORY_USAGE_ESTIMATOR_H_
diff --git a/base/trace_event/process_memory_dump.cc b/base/trace_event/process_memory_dump.cc
deleted file mode 100644
index d565b47..0000000
--- a/base/trace_event/process_memory_dump.cc
+++ /dev/null
@@ -1,545 +0,0 @@
-// Copyright 2015 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/process_memory_dump.h"
-
-#include <errno.h>
-
-#include <vector>
-
-#include "base/memory/ptr_util.h"
-#include "base/memory/shared_memory_tracker.h"
-#include "base/process/process_metrics.h"
-#include "base/strings/stringprintf.h"
-#include "base/trace_event/heap_profiler_heap_dump_writer.h"
-#include "base/trace_event/heap_profiler_serialization_state.h"
-#include "base/trace_event/memory_infra_background_whitelist.h"
-#include "base/trace_event/trace_event_argument.h"
-#include "base/unguessable_token.h"
-#include "build_config.h"
-
-#if defined(OS_IOS)
-#include <mach/vm_page_size.h>
-#endif
-
-#if defined(OS_POSIX) || defined(OS_FUCHSIA)
-#include <sys/mman.h>
-#endif
-
-#if defined(OS_WIN)
-#include <windows.h> // Must be in front of other Windows header files
-
-#include <Psapi.h>
-#endif
-
-namespace base {
-namespace trace_event {
-
-namespace {
-
-const char kEdgeTypeOwnership[] = "ownership";
-
-std::string GetSharedGlobalAllocatorDumpName(
- const MemoryAllocatorDumpGuid& guid) {
- return "global/" + guid.ToString();
-}
-
-#if defined(COUNT_RESIDENT_BYTES_SUPPORTED)
-size_t GetSystemPageCount(size_t mapped_size, size_t page_size) {
- return (mapped_size + page_size - 1) / page_size;
-}
-#endif
-
-UnguessableToken GetTokenForCurrentProcess() {
- static UnguessableToken instance = UnguessableToken::Create();
- return instance;
-}
-
-} // namespace
-
-// static
-bool ProcessMemoryDump::is_black_hole_non_fatal_for_testing_ = false;
-
-#if defined(COUNT_RESIDENT_BYTES_SUPPORTED)
-// static
-size_t ProcessMemoryDump::GetSystemPageSize() {
-#if defined(OS_IOS)
- // On iOS, getpagesize() returns the user page sizes, but for allocating
- // arrays for mincore(), kernel page sizes is needed. Use vm_kernel_page_size
- // as recommended by Apple, https://forums.developer.apple.com/thread/47532/.
- // Refer to http://crbug.com/542671 and Apple rdar://23651782
- return vm_kernel_page_size;
-#else
- return base::GetPageSize();
-#endif // defined(OS_IOS)
-}
-
-// static
-size_t ProcessMemoryDump::CountResidentBytes(void* start_address,
- size_t mapped_size) {
- const size_t page_size = GetSystemPageSize();
- const uintptr_t start_pointer = reinterpret_cast<uintptr_t>(start_address);
- DCHECK_EQ(0u, start_pointer % page_size);
-
- size_t offset = 0;
- size_t total_resident_pages = 0;
- bool failure = false;
-
- // An array as large as number of pages in memory segment needs to be passed
- // to the query function. To avoid allocating a large array, the given block
- // of memory is split into chunks of size |kMaxChunkSize|.
- const size_t kMaxChunkSize = 8 * 1024 * 1024;
- size_t max_vec_size =
- GetSystemPageCount(std::min(mapped_size, kMaxChunkSize), page_size);
-#if defined(OS_WIN)
- std::unique_ptr<PSAPI_WORKING_SET_EX_INFORMATION[]> vec(
- new PSAPI_WORKING_SET_EX_INFORMATION[max_vec_size]);
-#elif defined(OS_MACOSX)
- std::unique_ptr<char[]> vec(new char[max_vec_size]);
-#elif defined(OS_POSIX) || defined(OS_FUCHSIA)
- std::unique_ptr<unsigned char[]> vec(new unsigned char[max_vec_size]);
-#endif
-
- while (offset < mapped_size) {
- uintptr_t chunk_start = (start_pointer + offset);
- const size_t chunk_size = std::min(mapped_size - offset, kMaxChunkSize);
- const size_t page_count = GetSystemPageCount(chunk_size, page_size);
- size_t resident_page_count = 0;
-#if defined(OS_WIN)
- for (size_t i = 0; i < page_count; i++) {
- vec[i].VirtualAddress =
- reinterpret_cast<void*>(chunk_start + i * page_size);
- }
- DWORD vec_size = static_cast<DWORD>(
- page_count * sizeof(PSAPI_WORKING_SET_EX_INFORMATION));
- failure = !QueryWorkingSetEx(GetCurrentProcess(), vec.get(), vec_size);
-
- for (size_t i = 0; i < page_count; i++)
- resident_page_count += vec[i].VirtualAttributes.Valid;
-#elif defined(OS_FUCHSIA)
- // TODO(fuchsia): Port, see https://crbug.com/706592.
- ALLOW_UNUSED_LOCAL(chunk_start);
- ALLOW_UNUSED_LOCAL(page_count);
-#elif defined(OS_MACOSX)
- // mincore in MAC does not fail with EAGAIN.
- failure =
- !!mincore(reinterpret_cast<void*>(chunk_start), chunk_size, vec.get());
- for (size_t i = 0; i < page_count; i++)
- resident_page_count += vec[i] & MINCORE_INCORE ? 1 : 0;
-#elif defined(OS_POSIX)
- int error_counter = 0;
- int result = 0;
- // HANDLE_EINTR tries for 100 times. So following the same pattern.
- do {
- result =
-#if defined(OS_AIX)
- mincore(reinterpret_cast<char*>(chunk_start), chunk_size,
- reinterpret_cast<char*>(vec.get()));
-#else
- mincore(reinterpret_cast<void*>(chunk_start), chunk_size, vec.get());
-#endif
- } while (result == -1 && errno == EAGAIN && error_counter++ < 100);
- failure = !!result;
-
- for (size_t i = 0; i < page_count; i++)
- resident_page_count += vec[i] & 1;
-#endif
-
- if (failure)
- break;
-
- total_resident_pages += resident_page_count * page_size;
- offset += kMaxChunkSize;
- }
-
- DCHECK(!failure);
- if (failure) {
- total_resident_pages = 0;
- LOG(ERROR) << "CountResidentBytes failed. The resident size is invalid";
- }
- return total_resident_pages;
-}
-
-// static
-base::Optional<size_t> ProcessMemoryDump::CountResidentBytesInSharedMemory(
- void* start_address,
- size_t mapped_size) {
-#if defined(OS_MACOSX) && !defined(OS_IOS)
- // On macOS, use mach_vm_region instead of mincore for performance
- // (crbug.com/742042).
- mach_vm_size_t dummy_size = 0;
- mach_vm_address_t address =
- reinterpret_cast<mach_vm_address_t>(start_address);
- vm_region_top_info_data_t info;
- MachVMRegionResult result =
- GetTopInfo(mach_task_self(), &dummy_size, &address, &info);
- if (result == MachVMRegionResult::Error) {
- LOG(ERROR) << "CountResidentBytesInSharedMemory failed. The resident size "
- "is invalid";
- return base::Optional<size_t>();
- }
-
- size_t resident_pages =
- info.private_pages_resident + info.shared_pages_resident;
-
- // On macOS, measurements for private memory footprint overcount by
- // faulted pages in anonymous shared memory. To discount for this, we touch
- // all the resident pages in anonymous shared memory here, thus making them
- // faulted as well. This relies on two assumptions:
- //
- // 1) Consumers use shared memory from front to back. Thus, if there are
- // (N) resident pages, those pages represent the first N * PAGE_SIZE bytes in
- // the shared memory region.
- //
- // 2) This logic is run shortly before the logic that calculates
- // phys_footprint, thus ensuring that the discrepancy between faulted and
- // resident pages is minimal.
- //
- // The performance penalty is expected to be small.
- //
- // * Most of the time, we expect the pages to already be resident and faulted,
- // thus incurring a cache penalty read hit [since we read from each resident
- // page].
- //
- // * Rarely, we expect the pages to be resident but not faulted, resulting in
- // soft faults + cache penalty.
- //
- // * If assumption (1) is invalid, this will potentially fault some
- // previously non-resident pages, thus increasing memory usage, without fixing
- // the accounting.
- //
- // Sanity check in case the mapped size is less than the total size of the
- // region.
- size_t pages_to_fault =
- std::min(resident_pages, (mapped_size + PAGE_SIZE - 1) / PAGE_SIZE);
-
- volatile char* base_address = static_cast<char*>(start_address);
- for (size_t i = 0; i < pages_to_fault; ++i) {
- // Reading from a volatile is a visible side-effect for the purposes of
- // optimization. This guarantees that the optimizer will not kill this line.
- base_address[i * PAGE_SIZE];
- }
-
- return resident_pages * PAGE_SIZE;
-#else
- return CountResidentBytes(start_address, mapped_size);
-#endif // defined(OS_MACOSX) && !defined(OS_IOS)
-}
-
-#endif // defined(COUNT_RESIDENT_BYTES_SUPPORTED)
-
-ProcessMemoryDump::ProcessMemoryDump(
- scoped_refptr<HeapProfilerSerializationState>
- heap_profiler_serialization_state,
- const MemoryDumpArgs& dump_args)
- : process_token_(GetTokenForCurrentProcess()),
- heap_profiler_serialization_state_(
- std::move(heap_profiler_serialization_state)),
- dump_args_(dump_args) {}
-
-ProcessMemoryDump::~ProcessMemoryDump() = default;
-ProcessMemoryDump::ProcessMemoryDump(ProcessMemoryDump&& other) = default;
-ProcessMemoryDump& ProcessMemoryDump::operator=(ProcessMemoryDump&& other) =
- default;
-
-MemoryAllocatorDump* ProcessMemoryDump::CreateAllocatorDump(
- const std::string& absolute_name) {
- return AddAllocatorDumpInternal(std::make_unique<MemoryAllocatorDump>(
- absolute_name, dump_args_.level_of_detail, GetDumpId(absolute_name)));
-}
-
-MemoryAllocatorDump* ProcessMemoryDump::CreateAllocatorDump(
- const std::string& absolute_name,
- const MemoryAllocatorDumpGuid& guid) {
- return AddAllocatorDumpInternal(std::make_unique<MemoryAllocatorDump>(
- absolute_name, dump_args_.level_of_detail, guid));
-}
-
-MemoryAllocatorDump* ProcessMemoryDump::AddAllocatorDumpInternal(
- std::unique_ptr<MemoryAllocatorDump> mad) {
- // In background mode return the black hole dump, if invalid dump name is
- // given.
- if (dump_args_.level_of_detail == MemoryDumpLevelOfDetail::BACKGROUND &&
- !IsMemoryAllocatorDumpNameWhitelisted(mad->absolute_name())) {
- return GetBlackHoleMad();
- }
-
- auto insertion_result = allocator_dumps_.insert(
- std::make_pair(mad->absolute_name(), std::move(mad)));
- MemoryAllocatorDump* inserted_mad = insertion_result.first->second.get();
- DCHECK(insertion_result.second) << "Duplicate name: "
- << inserted_mad->absolute_name();
- return inserted_mad;
-}
-
-MemoryAllocatorDump* ProcessMemoryDump::GetAllocatorDump(
- const std::string& absolute_name) const {
- auto it = allocator_dumps_.find(absolute_name);
- if (it != allocator_dumps_.end())
- return it->second.get();
- if (black_hole_mad_)
- return black_hole_mad_.get();
- return nullptr;
-}
-
-MemoryAllocatorDump* ProcessMemoryDump::GetOrCreateAllocatorDump(
- const std::string& absolute_name) {
- MemoryAllocatorDump* mad = GetAllocatorDump(absolute_name);
- return mad ? mad : CreateAllocatorDump(absolute_name);
-}
-
-MemoryAllocatorDump* ProcessMemoryDump::CreateSharedGlobalAllocatorDump(
- const MemoryAllocatorDumpGuid& guid) {
- // A shared allocator dump can be shared within a process and the guid could
- // have been created already.
- MemoryAllocatorDump* mad = GetSharedGlobalAllocatorDump(guid);
- if (mad && mad != black_hole_mad_.get()) {
- // The weak flag is cleared because this method should create a non-weak
- // dump.
- mad->clear_flags(MemoryAllocatorDump::Flags::WEAK);
- return mad;
- }
- return CreateAllocatorDump(GetSharedGlobalAllocatorDumpName(guid), guid);
-}
-
-MemoryAllocatorDump* ProcessMemoryDump::CreateWeakSharedGlobalAllocatorDump(
- const MemoryAllocatorDumpGuid& guid) {
- MemoryAllocatorDump* mad = GetSharedGlobalAllocatorDump(guid);
- if (mad && mad != black_hole_mad_.get())
- return mad;
- mad = CreateAllocatorDump(GetSharedGlobalAllocatorDumpName(guid), guid);
- mad->set_flags(MemoryAllocatorDump::Flags::WEAK);
- return mad;
-}
-
-MemoryAllocatorDump* ProcessMemoryDump::GetSharedGlobalAllocatorDump(
- const MemoryAllocatorDumpGuid& guid) const {
- return GetAllocatorDump(GetSharedGlobalAllocatorDumpName(guid));
-}
-
-void ProcessMemoryDump::DumpHeapUsage(
- const std::unordered_map<base::trace_event::AllocationContext,
- base::trace_event::AllocationMetrics>&
- metrics_by_context,
- base::trace_event::TraceEventMemoryOverhead& overhead,
- const char* allocator_name) {
- // The heap profiler serialization state can be null here if heap profiler was
- // enabled when a process dump is in progress.
- if (heap_profiler_serialization_state() && !metrics_by_context.empty()) {
- DCHECK_EQ(0ul, heap_dumps_.count(allocator_name));
- std::unique_ptr<TracedValue> heap_dump = ExportHeapDump(
- metrics_by_context, *heap_profiler_serialization_state());
- heap_dumps_[allocator_name] = std::move(heap_dump);
- }
-
- std::string base_name = base::StringPrintf("tracing/heap_profiler_%s",
- allocator_name);
- overhead.DumpInto(base_name.c_str(), this);
-}
-
-void ProcessMemoryDump::SetAllocatorDumpsForSerialization(
- std::vector<std::unique_ptr<MemoryAllocatorDump>> dumps) {
- DCHECK(allocator_dumps_.empty());
- for (std::unique_ptr<MemoryAllocatorDump>& dump : dumps)
- AddAllocatorDumpInternal(std::move(dump));
-}
-
-std::vector<ProcessMemoryDump::MemoryAllocatorDumpEdge>
-ProcessMemoryDump::GetAllEdgesForSerialization() const {
- std::vector<MemoryAllocatorDumpEdge> edges;
- edges.reserve(allocator_dumps_edges_.size());
- for (const auto& it : allocator_dumps_edges_)
- edges.push_back(it.second);
- return edges;
-}
-
-void ProcessMemoryDump::SetAllEdgesForSerialization(
- const std::vector<ProcessMemoryDump::MemoryAllocatorDumpEdge>& edges) {
- DCHECK(allocator_dumps_edges_.empty());
- for (const MemoryAllocatorDumpEdge& edge : edges) {
- auto it_and_inserted = allocator_dumps_edges_.emplace(edge.source, edge);
- DCHECK(it_and_inserted.second);
- }
-}
-
-void ProcessMemoryDump::Clear() {
- allocator_dumps_.clear();
- allocator_dumps_edges_.clear();
- heap_dumps_.clear();
-}
-
-void ProcessMemoryDump::TakeAllDumpsFrom(ProcessMemoryDump* other) {
- // Moves the ownership of all MemoryAllocatorDump(s) contained in |other|
- // into this ProcessMemoryDump, checking for duplicates.
- for (auto& it : other->allocator_dumps_)
- AddAllocatorDumpInternal(std::move(it.second));
- other->allocator_dumps_.clear();
-
- // Move all the edges.
- allocator_dumps_edges_.insert(other->allocator_dumps_edges_.begin(),
- other->allocator_dumps_edges_.end());
- other->allocator_dumps_edges_.clear();
-
- for (auto& it : other->heap_dumps_) {
- DCHECK_EQ(0ul, heap_dumps_.count(it.first));
- heap_dumps_.insert(std::make_pair(it.first, std::move(it.second)));
- }
- other->heap_dumps_.clear();
-}
-
-void ProcessMemoryDump::SerializeAllocatorDumpsInto(TracedValue* value) const {
- if (allocator_dumps_.size() > 0) {
- value->BeginDictionary("allocators");
- for (const auto& allocator_dump_it : allocator_dumps_)
- allocator_dump_it.second->AsValueInto(value);
- value->EndDictionary();
- }
-
- value->BeginArray("allocators_graph");
- for (const auto& it : allocator_dumps_edges_) {
- const MemoryAllocatorDumpEdge& edge = it.second;
- value->BeginDictionary();
- value->SetString("source", edge.source.ToString());
- value->SetString("target", edge.target.ToString());
- value->SetInteger("importance", edge.importance);
- value->SetString("type", kEdgeTypeOwnership);
- value->EndDictionary();
- }
- value->EndArray();
-}
-
-void ProcessMemoryDump::SerializeHeapProfilerDumpsInto(
- TracedValue* value) const {
- if (heap_dumps_.size() == 0)
- return;
- value->BeginDictionary("heaps");
- for (const auto& name_and_dump : heap_dumps_)
- value->SetValueWithCopiedName(name_and_dump.first, *name_and_dump.second);
- value->EndDictionary(); // "heaps"
-}
-
-void ProcessMemoryDump::AddOwnershipEdge(const MemoryAllocatorDumpGuid& source,
- const MemoryAllocatorDumpGuid& target,
- int importance) {
- // This will either override an existing edge or create a new one.
- auto it = allocator_dumps_edges_.find(source);
- int max_importance = importance;
- if (it != allocator_dumps_edges_.end()) {
- DCHECK_EQ(target.ToUint64(), it->second.target.ToUint64());
- max_importance = std::max(importance, it->second.importance);
- }
- allocator_dumps_edges_[source] = {source, target, max_importance,
- false /* overridable */};
-}
-
-void ProcessMemoryDump::AddOwnershipEdge(
- const MemoryAllocatorDumpGuid& source,
- const MemoryAllocatorDumpGuid& target) {
- AddOwnershipEdge(source, target, 0 /* importance */);
-}
-
-void ProcessMemoryDump::AddOverridableOwnershipEdge(
- const MemoryAllocatorDumpGuid& source,
- const MemoryAllocatorDumpGuid& target,
- int importance) {
- if (allocator_dumps_edges_.count(source) == 0) {
- allocator_dumps_edges_[source] = {source, target, importance,
- true /* overridable */};
- } else {
- // An edge between the source and target already exits. So, do nothing here
- // since the new overridable edge is implicitly overridden by a strong edge
- // which was created earlier.
- DCHECK(!allocator_dumps_edges_[source].overridable);
- }
-}
-
-void ProcessMemoryDump::CreateSharedMemoryOwnershipEdge(
- const MemoryAllocatorDumpGuid& client_local_dump_guid,
- const UnguessableToken& shared_memory_guid,
- int importance) {
- CreateSharedMemoryOwnershipEdgeInternal(client_local_dump_guid,
- shared_memory_guid, importance,
- false /*is_weak*/);
-}
-
-void ProcessMemoryDump::CreateWeakSharedMemoryOwnershipEdge(
- const MemoryAllocatorDumpGuid& client_local_dump_guid,
- const UnguessableToken& shared_memory_guid,
- int importance) {
- CreateSharedMemoryOwnershipEdgeInternal(
- client_local_dump_guid, shared_memory_guid, importance, true /*is_weak*/);
-}
-
-void ProcessMemoryDump::CreateSharedMemoryOwnershipEdgeInternal(
- const MemoryAllocatorDumpGuid& client_local_dump_guid,
- const UnguessableToken& shared_memory_guid,
- int importance,
- bool is_weak) {
- DCHECK(!shared_memory_guid.is_empty());
- // New model where the global dumps created by SharedMemoryTracker are used
- // for the clients.
-
- // The guid of the local dump created by SharedMemoryTracker for the memory
- // segment.
- auto local_shm_guid =
- GetDumpId(SharedMemoryTracker::GetDumpNameForTracing(shared_memory_guid));
-
- // The dump guid of the global dump created by the tracker for the memory
- // segment.
- auto global_shm_guid =
- SharedMemoryTracker::GetGlobalDumpIdForTracing(shared_memory_guid);
-
- // Create an edge between local dump of the client and the local dump of the
- // SharedMemoryTracker. Do not need to create the dumps here since the tracker
- // would create them. The importance is also required here for the case of
- // single process mode.
- AddOwnershipEdge(client_local_dump_guid, local_shm_guid, importance);
-
- // TODO(ssid): Handle the case of weak dumps here. This needs a new function
- // GetOrCreaetGlobalDump() in PMD since we need to change the behavior of the
- // created global dump.
- // Create an edge that overrides the edge created by SharedMemoryTracker.
- AddOwnershipEdge(local_shm_guid, global_shm_guid, importance);
-}
-
-void ProcessMemoryDump::AddSuballocation(const MemoryAllocatorDumpGuid& source,
- const std::string& target_node_name) {
- // Do not create new dumps for suballocations in background mode.
- if (dump_args_.level_of_detail == MemoryDumpLevelOfDetail::BACKGROUND)
- return;
-
- std::string child_mad_name = target_node_name + "/__" + source.ToString();
- MemoryAllocatorDump* target_child_mad = CreateAllocatorDump(child_mad_name);
- AddOwnershipEdge(source, target_child_mad->guid());
-}
-
-MemoryAllocatorDump* ProcessMemoryDump::GetBlackHoleMad() {
- DCHECK(is_black_hole_non_fatal_for_testing_);
- if (!black_hole_mad_) {
- std::string name = "discarded";
- black_hole_mad_.reset(new MemoryAllocatorDump(
- name, dump_args_.level_of_detail, GetDumpId(name)));
- }
- return black_hole_mad_.get();
-}
-
-MemoryAllocatorDumpGuid ProcessMemoryDump::GetDumpId(
- const std::string& absolute_name) {
- return MemoryAllocatorDumpGuid(StringPrintf(
- "%s:%s", process_token().ToString().c_str(), absolute_name.c_str()));
-}
-
-bool ProcessMemoryDump::MemoryAllocatorDumpEdge::operator==(
- const MemoryAllocatorDumpEdge& other) const {
- return source == other.source && target == other.target &&
- importance == other.importance && overridable == other.overridable;
-}
-
-bool ProcessMemoryDump::MemoryAllocatorDumpEdge::operator!=(
- const MemoryAllocatorDumpEdge& other) const {
- return !(*this == other);
-}
-
-} // namespace trace_event
-} // namespace base
diff --git a/base/trace_event/process_memory_dump.h b/base/trace_event/process_memory_dump.h
deleted file mode 100644
index b2ce66f..0000000
--- a/base/trace_event/process_memory_dump.h
+++ /dev/null
@@ -1,304 +0,0 @@
-// Copyright 2015 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_PROCESS_MEMORY_DUMP_H_
-#define BASE_TRACE_EVENT_PROCESS_MEMORY_DUMP_H_
-
-#include <stddef.h>
-
-#include <map>
-#include <unordered_map>
-#include <vector>
-
-#include "base/base_export.h"
-#include "base/macros.h"
-#include "base/memory/ref_counted.h"
-#include "base/trace_event/heap_profiler_serialization_state.h"
-#include "base/trace_event/memory_allocator_dump.h"
-#include "base/trace_event/memory_allocator_dump_guid.h"
-#include "base/trace_event/memory_dump_request_args.h"
-#include "build_config.h"
-
-// Define COUNT_RESIDENT_BYTES_SUPPORTED if platform supports counting of the
-// resident memory.
-#if !defined(OS_NACL)
-#define COUNT_RESIDENT_BYTES_SUPPORTED
-#endif
-
-namespace base {
-
-class SharedMemory;
-class UnguessableToken;
-
-namespace trace_event {
-
-class HeapProfilerSerializationState;
-class TracedValue;
-
-// ProcessMemoryDump is as a strongly typed container which holds the dumps
-// produced by the MemoryDumpProvider(s) for a specific process.
-class BASE_EXPORT ProcessMemoryDump {
- public:
- struct BASE_EXPORT MemoryAllocatorDumpEdge {
- bool operator==(const MemoryAllocatorDumpEdge&) const;
- bool operator!=(const MemoryAllocatorDumpEdge&) const;
-
- MemoryAllocatorDumpGuid source;
- MemoryAllocatorDumpGuid target;
- int importance = 0;
- bool overridable = false;
- };
-
- // Maps allocator dumps absolute names (allocator_name/heap/subheap) to
- // MemoryAllocatorDump instances.
- using AllocatorDumpsMap =
- std::map<std::string, std::unique_ptr<MemoryAllocatorDump>>;
-
- using HeapDumpsMap = std::map<std::string, std::unique_ptr<TracedValue>>;
-
- // Stores allocator dump edges indexed by source allocator dump GUID.
- using AllocatorDumpEdgesMap =
- std::map<MemoryAllocatorDumpGuid, MemoryAllocatorDumpEdge>;
-
-#if defined(COUNT_RESIDENT_BYTES_SUPPORTED)
- // Returns the number of bytes in a kernel memory page. Some platforms may
- // have a different value for kernel page sizes from user page sizes. It is
- // important to use kernel memory page sizes for resident bytes calculation.
- // In most cases, the two are the same.
- static size_t GetSystemPageSize();
-
- // Returns the total bytes resident for a virtual address range, with given
- // |start_address| and |mapped_size|. |mapped_size| is specified in bytes. The
- // value returned is valid only if the given range is currently mmapped by the
- // process. The |start_address| must be page-aligned.
- static size_t CountResidentBytes(void* start_address, size_t mapped_size);
-
- // The same as above, but the given mapped range should belong to the
- // shared_memory's mapped region.
- static base::Optional<size_t> CountResidentBytesInSharedMemory(
- void* start_address,
- size_t mapped_size);
-#endif
-
- ProcessMemoryDump(scoped_refptr<HeapProfilerSerializationState>
- heap_profiler_serialization_state,
- const MemoryDumpArgs& dump_args);
- ProcessMemoryDump(ProcessMemoryDump&&);
- ~ProcessMemoryDump();
-
- ProcessMemoryDump& operator=(ProcessMemoryDump&&);
-
- // Creates a new MemoryAllocatorDump with the given name and returns the
- // empty object back to the caller.
- // Arguments:
- // absolute_name: a name that uniquely identifies allocator dumps produced
- // by this provider. It is possible to specify nesting by using a
- // path-like string (e.g., v8/isolate1/heap1, v8/isolate1/heap2).
- // Leading or trailing slashes are not allowed.
- // guid: an optional identifier, unique among all processes within the
- // scope of a global dump. This is only relevant when using
- // AddOwnershipEdge() to express memory sharing. If omitted,
- // it will be automatically generated.
- // ProcessMemoryDump handles the memory ownership of its MemoryAllocatorDumps.
- MemoryAllocatorDump* CreateAllocatorDump(const std::string& absolute_name);
- MemoryAllocatorDump* CreateAllocatorDump(const std::string& absolute_name,
- const MemoryAllocatorDumpGuid& guid);
-
- // Looks up a MemoryAllocatorDump given its allocator and heap names, or
- // nullptr if not found.
- MemoryAllocatorDump* GetAllocatorDump(const std::string& absolute_name) const;
-
- // Do NOT use this method. All dump providers should use
- // CreateAllocatorDump(). Tries to create a new MemoryAllocatorDump only if it
- // doesn't already exist. Creating multiple dumps with same name using
- // GetOrCreateAllocatorDump() would override the existing scalars in MAD and
- // cause misreporting. This method is used only in rare cases multiple
- // components create allocator dumps with same name and only one of them adds
- // size.
- MemoryAllocatorDump* GetOrCreateAllocatorDump(
- const std::string& absolute_name);
-
- // Creates a shared MemoryAllocatorDump, to express cross-process sharing.
- // Shared allocator dumps are allowed to have duplicate guids within the
- // global scope, in order to reference the same dump from multiple processes.
- // See the design doc goo.gl/keU6Bf for reference usage patterns.
- MemoryAllocatorDump* CreateSharedGlobalAllocatorDump(
- const MemoryAllocatorDumpGuid& guid);
-
- // Creates a shared MemoryAllocatorDump as CreateSharedGlobalAllocatorDump,
- // but with a WEAK flag. A weak dump will be discarded unless a non-weak dump
- // is created using CreateSharedGlobalAllocatorDump by at least one process.
- // The WEAK flag does not apply if a non-weak dump with the same GUID already
- // exists or is created later. All owners and children of the discarded dump
- // will also be discarded transitively.
- MemoryAllocatorDump* CreateWeakSharedGlobalAllocatorDump(
- const MemoryAllocatorDumpGuid& guid);
-
- // Looks up a shared MemoryAllocatorDump given its guid.
- MemoryAllocatorDump* GetSharedGlobalAllocatorDump(
- const MemoryAllocatorDumpGuid& guid) const;
-
- // Returns the map of the MemoryAllocatorDumps added to this dump.
- const AllocatorDumpsMap& allocator_dumps() const { return allocator_dumps_; }
-
- AllocatorDumpsMap* mutable_allocator_dumps_for_serialization() const {
- // Mojo takes a const input argument even for move-only types that can be
- // mutate while serializing (like this one). Hence the const_cast.
- return const_cast<AllocatorDumpsMap*>(&allocator_dumps_);
- }
- void SetAllocatorDumpsForSerialization(
- std::vector<std::unique_ptr<MemoryAllocatorDump>>);
-
- // Only for mojo serialization.
- std::vector<MemoryAllocatorDumpEdge> GetAllEdgesForSerialization() const;
- void SetAllEdgesForSerialization(const std::vector<MemoryAllocatorDumpEdge>&);
-
- // Dumps heap usage with |allocator_name|.
- void DumpHeapUsage(
- const std::unordered_map<base::trace_event::AllocationContext,
- base::trace_event::AllocationMetrics>&
- metrics_by_context,
- base::trace_event::TraceEventMemoryOverhead& overhead,
- const char* allocator_name);
-
- // Adds an ownership relationship between two MemoryAllocatorDump(s) with the
- // semantics: |source| owns |target|, and has the effect of attributing
- // the memory usage of |target| to |source|. |importance| is optional and
- // relevant only for the cases of co-ownership, where it acts as a z-index:
- // the owner with the highest importance will be attributed |target|'s memory.
- // If an edge is present, its importance will not be updated unless
- // |importance| is larger.
- void AddOwnershipEdge(const MemoryAllocatorDumpGuid& source,
- const MemoryAllocatorDumpGuid& target,
- int importance);
- void AddOwnershipEdge(const MemoryAllocatorDumpGuid& source,
- const MemoryAllocatorDumpGuid& target);
-
- // Adds edges that can be overriden by a later or earlier call to
- // AddOwnershipEdge() with the same source and target with a different
- // |importance| value.
- void AddOverridableOwnershipEdge(const MemoryAllocatorDumpGuid& source,
- const MemoryAllocatorDumpGuid& target,
- int importance);
-
- // Creates ownership edges for memory backed by base::SharedMemory. Handles
- // the case of cross process sharing and importnace of ownership for the case
- // with and without the base::SharedMemory dump provider. The new version
- // should just use global dumps created by SharedMemoryTracker and this
- // function handles the transition until we get SharedMemory IDs through mojo
- // channel crbug.com/713763. The weak version creates a weak global dump.
- // |client_local_dump_guid| The guid of the local dump created by the client
- // of base::SharedMemory.
- // |shared_memory_guid| The ID of the base::SharedMemory that is assigned
- // globally, used to create global dump edges in the new model.
- // |importance| Importance of the global dump edges to say if the current
- // process owns the memory segment.
- void CreateSharedMemoryOwnershipEdge(
- const MemoryAllocatorDumpGuid& client_local_dump_guid,
- const UnguessableToken& shared_memory_guid,
- int importance);
- void CreateWeakSharedMemoryOwnershipEdge(
- const MemoryAllocatorDumpGuid& client_local_dump_guid,
- const UnguessableToken& shared_memory_guid,
- int importance);
-
- const AllocatorDumpEdgesMap& allocator_dumps_edges() const {
- return allocator_dumps_edges_;
- }
-
- // Utility method to add a suballocation relationship with the following
- // semantics: |source| is suballocated from |target_node_name|.
- // This creates a child node of |target_node_name| and adds an ownership edge
- // between |source| and the new child node. As a result, the UI will not
- // account the memory of |source| in the target node.
- void AddSuballocation(const MemoryAllocatorDumpGuid& source,
- const std::string& target_node_name);
-
- const scoped_refptr<HeapProfilerSerializationState>&
- heap_profiler_serialization_state() const {
- return heap_profiler_serialization_state_;
- }
-
- // Removes all the MemoryAllocatorDump(s) contained in this instance. This
- // ProcessMemoryDump can be safely reused as if it was new once this returns.
- void Clear();
-
- // Merges all MemoryAllocatorDump(s) contained in |other| inside this
- // ProcessMemoryDump, transferring their ownership to this instance.
- // |other| will be an empty ProcessMemoryDump after this method returns.
- // This is to allow dump providers to pre-populate ProcessMemoryDump instances
- // and later move their contents into the ProcessMemoryDump passed as argument
- // of the MemoryDumpProvider::OnMemoryDump(ProcessMemoryDump*) callback.
- void TakeAllDumpsFrom(ProcessMemoryDump* other);
-
- // Populate the traced value with information about the memory allocator
- // dumps.
- void SerializeAllocatorDumpsInto(TracedValue* value) const;
-
- // Populate the traced value with information about the heap profiler.
- void SerializeHeapProfilerDumpsInto(TracedValue* value) const;
-
- const HeapDumpsMap& heap_dumps() const { return heap_dumps_; }
-
- const MemoryDumpArgs& dump_args() const { return dump_args_; }
-
- private:
- FRIEND_TEST_ALL_PREFIXES(ProcessMemoryDumpTest, BackgroundModeTest);
- FRIEND_TEST_ALL_PREFIXES(ProcessMemoryDumpTest, SharedMemoryOwnershipTest);
- FRIEND_TEST_ALL_PREFIXES(ProcessMemoryDumpTest, GuidsTest);
-
- MemoryAllocatorDump* AddAllocatorDumpInternal(
- std::unique_ptr<MemoryAllocatorDump> mad);
-
- // A per-process token, valid throughout all the lifetime of the current
- // process, used to disambiguate dumps with the same name generated in
- // different processes.
- const UnguessableToken& process_token() const { return process_token_; }
- void set_process_token_for_testing(UnguessableToken token) {
- process_token_ = token;
- };
-
- // Returns the Guid of the dump for the given |absolute_name| for
- // for the given process' token. |process_token| is used to disambiguate GUIDs
- // derived from the same name under different processes.
- MemoryAllocatorDumpGuid GetDumpId(const std::string& absolute_name);
-
- void CreateSharedMemoryOwnershipEdgeInternal(
- const MemoryAllocatorDumpGuid& client_local_dump_guid,
- const UnguessableToken& shared_memory_guid,
- int importance,
- bool is_weak);
-
- MemoryAllocatorDump* GetBlackHoleMad();
-
- UnguessableToken process_token_;
- AllocatorDumpsMap allocator_dumps_;
- HeapDumpsMap heap_dumps_;
-
- // State shared among all PMDs instances created in a given trace session.
- scoped_refptr<HeapProfilerSerializationState>
- heap_profiler_serialization_state_;
-
- // Keeps track of relationships between MemoryAllocatorDump(s).
- AllocatorDumpEdgesMap allocator_dumps_edges_;
-
- // Level of detail of the current dump.
- MemoryDumpArgs dump_args_;
-
- // This allocator dump is returned when an invalid dump is created in
- // background mode. The attributes of the dump are ignored and not added to
- // the trace.
- std::unique_ptr<MemoryAllocatorDump> black_hole_mad_;
-
- // When set to true, the DCHECK(s) for invalid dump creations on the
- // background mode are disabled for testing.
- static bool is_black_hole_non_fatal_for_testing_;
-
- DISALLOW_COPY_AND_ASSIGN(ProcessMemoryDump);
-};
-
-} // namespace trace_event
-} // namespace base
-
-#endif // BASE_TRACE_EVENT_PROCESS_MEMORY_DUMP_H_
diff --git a/base/trace_event/trace_buffer.cc b/base/trace_event/trace_buffer.cc
deleted file mode 100644
index 8de470f..0000000
--- a/base/trace_event/trace_buffer.cc
+++ /dev/null
@@ -1,347 +0,0 @@
-// Copyright 2015 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_buffer.h"
-
-#include <memory>
-#include <utility>
-#include <vector>
-
-#include "base/macros.h"
-#include "base/trace_event/heap_profiler.h"
-#include "base/trace_event/trace_event_impl.h"
-
-namespace base {
-namespace trace_event {
-
-namespace {
-
-class TraceBufferRingBuffer : public TraceBuffer {
- public:
- TraceBufferRingBuffer(size_t max_chunks)
- : max_chunks_(max_chunks),
- recyclable_chunks_queue_(new size_t[queue_capacity()]),
- queue_head_(0),
- queue_tail_(max_chunks),
- current_iteration_index_(0),
- current_chunk_seq_(1) {
- chunks_.reserve(max_chunks);
- for (size_t i = 0; i < max_chunks; ++i)
- recyclable_chunks_queue_[i] = i;
- }
-
- std::unique_ptr<TraceBufferChunk> GetChunk(size_t* index) override {
- HEAP_PROFILER_SCOPED_IGNORE;
-
- // Because the number of threads is much less than the number of chunks,
- // the queue should never be empty.
- DCHECK(!QueueIsEmpty());
-
- *index = recyclable_chunks_queue_[queue_head_];
- queue_head_ = NextQueueIndex(queue_head_);
- current_iteration_index_ = queue_head_;
-
- if (*index >= chunks_.size())
- chunks_.resize(*index + 1);
-
- TraceBufferChunk* chunk = chunks_[*index].release();
- chunks_[*index] = nullptr; // Put nullptr in the slot of a in-flight chunk.
- if (chunk)
- chunk->Reset(current_chunk_seq_++);
- else
- chunk = new TraceBufferChunk(current_chunk_seq_++);
-
- return std::unique_ptr<TraceBufferChunk>(chunk);
- }
-
- void ReturnChunk(size_t index,
- std::unique_ptr<TraceBufferChunk> chunk) override {
- // When this method is called, the queue should not be full because it
- // can contain all chunks including the one to be returned.
- DCHECK(!QueueIsFull());
- DCHECK(chunk);
- DCHECK_LT(index, chunks_.size());
- DCHECK(!chunks_[index]);
- chunks_[index] = std::move(chunk);
- recyclable_chunks_queue_[queue_tail_] = index;
- queue_tail_ = NextQueueIndex(queue_tail_);
- }
-
- bool IsFull() const override { return false; }
-
- size_t Size() const override {
- // This is approximate because not all of the chunks are full.
- return chunks_.size() * TraceBufferChunk::kTraceBufferChunkSize;
- }
-
- size_t Capacity() const override {
- return max_chunks_ * TraceBufferChunk::kTraceBufferChunkSize;
- }
-
- TraceEvent* GetEventByHandle(TraceEventHandle handle) override {
- if (handle.chunk_index >= chunks_.size())
- return nullptr;
- TraceBufferChunk* chunk = chunks_[handle.chunk_index].get();
- if (!chunk || chunk->seq() != handle.chunk_seq)
- return nullptr;
- return chunk->GetEventAt(handle.event_index);
- }
-
- const TraceBufferChunk* NextChunk() override {
- if (chunks_.empty())
- return nullptr;
-
- while (current_iteration_index_ != queue_tail_) {
- size_t chunk_index = recyclable_chunks_queue_[current_iteration_index_];
- current_iteration_index_ = NextQueueIndex(current_iteration_index_);
- if (chunk_index >= chunks_.size()) // Skip uninitialized chunks.
- continue;
- DCHECK(chunks_[chunk_index]);
- return chunks_[chunk_index].get();
- }
- return nullptr;
- }
-
- void EstimateTraceMemoryOverhead(
- TraceEventMemoryOverhead* overhead) override {
- overhead->Add(TraceEventMemoryOverhead::kTraceBuffer, sizeof(*this));
- for (size_t queue_index = queue_head_; queue_index != queue_tail_;
- queue_index = NextQueueIndex(queue_index)) {
- size_t chunk_index = recyclable_chunks_queue_[queue_index];
- if (chunk_index >= chunks_.size()) // Skip uninitialized chunks.
- continue;
- chunks_[chunk_index]->EstimateTraceMemoryOverhead(overhead);
- }
- }
-
- private:
- bool QueueIsEmpty() const { return queue_head_ == queue_tail_; }
-
- size_t QueueSize() const {
- return queue_tail_ > queue_head_
- ? queue_tail_ - queue_head_
- : queue_tail_ + queue_capacity() - queue_head_;
- }
-
- bool QueueIsFull() const { return QueueSize() == queue_capacity() - 1; }
-
- size_t queue_capacity() const {
- // One extra space to help distinguish full state and empty state.
- return max_chunks_ + 1;
- }
-
- size_t NextQueueIndex(size_t index) const {
- index++;
- if (index >= queue_capacity())
- index = 0;
- return index;
- }
-
- size_t max_chunks_;
- std::vector<std::unique_ptr<TraceBufferChunk>> chunks_;
-
- std::unique_ptr<size_t[]> recyclable_chunks_queue_;
- size_t queue_head_;
- size_t queue_tail_;
-
- size_t current_iteration_index_;
- uint32_t current_chunk_seq_;
-
- DISALLOW_COPY_AND_ASSIGN(TraceBufferRingBuffer);
-};
-
-class TraceBufferVector : public TraceBuffer {
- public:
- TraceBufferVector(size_t max_chunks)
- : in_flight_chunk_count_(0),
- current_iteration_index_(0),
- max_chunks_(max_chunks) {
- chunks_.reserve(max_chunks_);
- }
-
- std::unique_ptr<TraceBufferChunk> GetChunk(size_t* index) override {
- HEAP_PROFILER_SCOPED_IGNORE;
-
- // This function may be called when adding normal events or indirectly from
- // AddMetadataEventsWhileLocked(). We can not DECHECK(!IsFull()) because we
- // have to add the metadata events and flush thread-local buffers even if
- // the buffer is full.
- *index = chunks_.size();
- // Put nullptr in the slot of a in-flight chunk.
- chunks_.push_back(nullptr);
- ++in_flight_chunk_count_;
- // + 1 because zero chunk_seq is not allowed.
- return std::unique_ptr<TraceBufferChunk>(
- new TraceBufferChunk(static_cast<uint32_t>(*index) + 1));
- }
-
- void ReturnChunk(size_t index,
- std::unique_ptr<TraceBufferChunk> chunk) override {
- DCHECK_GT(in_flight_chunk_count_, 0u);
- DCHECK_LT(index, chunks_.size());
- DCHECK(!chunks_[index]);
- --in_flight_chunk_count_;
- chunks_[index] = std::move(chunk);
- }
-
- bool IsFull() const override { return chunks_.size() >= max_chunks_; }
-
- size_t Size() const override {
- // This is approximate because not all of the chunks are full.
- return chunks_.size() * TraceBufferChunk::kTraceBufferChunkSize;
- }
-
- size_t Capacity() const override {
- return max_chunks_ * TraceBufferChunk::kTraceBufferChunkSize;
- }
-
- TraceEvent* GetEventByHandle(TraceEventHandle handle) override {
- if (handle.chunk_index >= chunks_.size())
- return nullptr;
- TraceBufferChunk* chunk = chunks_[handle.chunk_index].get();
- if (!chunk || chunk->seq() != handle.chunk_seq)
- return nullptr;
- return chunk->GetEventAt(handle.event_index);
- }
-
- const TraceBufferChunk* NextChunk() override {
- while (current_iteration_index_ < chunks_.size()) {
- // Skip in-flight chunks.
- const TraceBufferChunk* chunk = chunks_[current_iteration_index_++].get();
- if (chunk)
- return chunk;
- }
- return nullptr;
- }
-
- void EstimateTraceMemoryOverhead(
- TraceEventMemoryOverhead* overhead) override {
- const size_t chunks_ptr_vector_allocated_size =
- sizeof(*this) + max_chunks_ * sizeof(decltype(chunks_)::value_type);
- const size_t chunks_ptr_vector_resident_size =
- sizeof(*this) + chunks_.size() * sizeof(decltype(chunks_)::value_type);
- overhead->Add(TraceEventMemoryOverhead::kTraceBuffer,
- chunks_ptr_vector_allocated_size,
- chunks_ptr_vector_resident_size);
- for (size_t i = 0; i < chunks_.size(); ++i) {
- TraceBufferChunk* chunk = chunks_[i].get();
- // Skip the in-flight (nullptr) chunks. They will be accounted by the
- // per-thread-local dumpers, see ThreadLocalEventBuffer::OnMemoryDump.
- if (chunk)
- chunk->EstimateTraceMemoryOverhead(overhead);
- }
- }
-
- private:
- size_t in_flight_chunk_count_;
- size_t current_iteration_index_;
- size_t max_chunks_;
- std::vector<std::unique_ptr<TraceBufferChunk>> chunks_;
-
- DISALLOW_COPY_AND_ASSIGN(TraceBufferVector);
-};
-
-} // namespace
-
-TraceBufferChunk::TraceBufferChunk(uint32_t seq) : next_free_(0), seq_(seq) {}
-
-TraceBufferChunk::~TraceBufferChunk() = default;
-
-void TraceBufferChunk::Reset(uint32_t new_seq) {
- for (size_t i = 0; i < next_free_; ++i)
- chunk_[i].Reset();
- next_free_ = 0;
- seq_ = new_seq;
- cached_overhead_estimate_.reset();
-}
-
-TraceEvent* TraceBufferChunk::AddTraceEvent(size_t* event_index) {
- DCHECK(!IsFull());
- *event_index = next_free_++;
- return &chunk_[*event_index];
-}
-
-void TraceBufferChunk::EstimateTraceMemoryOverhead(
- TraceEventMemoryOverhead* overhead) {
- if (!cached_overhead_estimate_) {
- cached_overhead_estimate_.reset(new TraceEventMemoryOverhead);
-
- // When estimating the size of TraceBufferChunk, exclude the array of trace
- // events, as they are computed individually below.
- cached_overhead_estimate_->Add(TraceEventMemoryOverhead::kTraceBufferChunk,
- sizeof(*this) - sizeof(chunk_));
- }
-
- const size_t num_cached_estimated_events =
- cached_overhead_estimate_->GetCount(
- TraceEventMemoryOverhead::kTraceEvent);
- DCHECK_LE(num_cached_estimated_events, size());
-
- if (IsFull() && num_cached_estimated_events == size()) {
- overhead->Update(*cached_overhead_estimate_);
- return;
- }
-
- for (size_t i = num_cached_estimated_events; i < size(); ++i)
- chunk_[i].EstimateTraceMemoryOverhead(cached_overhead_estimate_.get());
-
- if (IsFull()) {
- cached_overhead_estimate_->AddSelf();
- } else {
- // The unused TraceEvents in |chunks_| are not cached. They will keep
- // changing as new TraceEvents are added to this chunk, so they are
- // computed on the fly.
- const size_t num_unused_trace_events = capacity() - size();
- overhead->Add(TraceEventMemoryOverhead::kUnusedTraceEvent,
- num_unused_trace_events * sizeof(TraceEvent));
- }
-
- overhead->Update(*cached_overhead_estimate_);
-}
-
-TraceResultBuffer::OutputCallback
-TraceResultBuffer::SimpleOutput::GetCallback() {
- return Bind(&SimpleOutput::Append, Unretained(this));
-}
-
-void TraceResultBuffer::SimpleOutput::Append(
- const std::string& json_trace_output) {
- json_output += json_trace_output;
-}
-
-TraceResultBuffer::TraceResultBuffer() : append_comma_(false) {}
-
-TraceResultBuffer::~TraceResultBuffer() = default;
-
-void TraceResultBuffer::SetOutputCallback(
- const OutputCallback& json_chunk_callback) {
- output_callback_ = json_chunk_callback;
-}
-
-void TraceResultBuffer::Start() {
- append_comma_ = false;
- output_callback_.Run("[");
-}
-
-void TraceResultBuffer::AddFragment(const std::string& trace_fragment) {
- if (append_comma_)
- output_callback_.Run(",");
- append_comma_ = true;
- output_callback_.Run(trace_fragment);
-}
-
-void TraceResultBuffer::Finish() {
- output_callback_.Run("]");
-}
-
-TraceBuffer* TraceBuffer::CreateTraceBufferRingBuffer(size_t max_chunks) {
- return new TraceBufferRingBuffer(max_chunks);
-}
-
-TraceBuffer* TraceBuffer::CreateTraceBufferVectorOfSize(size_t max_chunks) {
- return new TraceBufferVector(max_chunks);
-}
-
-} // namespace trace_event
-} // namespace base
diff --git a/base/trace_event/trace_buffer.h b/base/trace_event/trace_buffer.h
deleted file mode 100644
index 3d6465f..0000000
--- a/base/trace_event/trace_buffer.h
+++ /dev/null
@@ -1,130 +0,0 @@
-// Copyright 2015 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_BUFFER_H_
-#define BASE_TRACE_EVENT_TRACE_BUFFER_H_
-
-#include <stddef.h>
-#include <stdint.h>
-
-#include "base/base_export.h"
-#include "base/trace_event/trace_event.h"
-#include "base/trace_event/trace_event_impl.h"
-
-namespace base {
-
-namespace trace_event {
-
-// TraceBufferChunk is the basic unit of TraceBuffer.
-class BASE_EXPORT TraceBufferChunk {
- public:
- explicit TraceBufferChunk(uint32_t seq);
- ~TraceBufferChunk();
-
- void Reset(uint32_t new_seq);
- TraceEvent* AddTraceEvent(size_t* event_index);
- bool IsFull() const { return next_free_ == kTraceBufferChunkSize; }
-
- uint32_t seq() const { return seq_; }
- size_t capacity() const { return kTraceBufferChunkSize; }
- size_t size() const { return next_free_; }
-
- TraceEvent* GetEventAt(size_t index) {
- DCHECK(index < size());
- return &chunk_[index];
- }
- const TraceEvent* GetEventAt(size_t index) const {
- DCHECK(index < size());
- return &chunk_[index];
- }
-
- void EstimateTraceMemoryOverhead(TraceEventMemoryOverhead* overhead);
-
- // These values must be kept consistent with the numbers of bits of
- // chunk_index and event_index fields in TraceEventHandle
- // (in trace_event_impl.h).
- static const size_t kMaxChunkIndex = (1u << 26) - 1;
- static const size_t kTraceBufferChunkSize = 64;
-
- private:
- size_t next_free_;
- std::unique_ptr<TraceEventMemoryOverhead> cached_overhead_estimate_;
- TraceEvent chunk_[kTraceBufferChunkSize];
- uint32_t seq_;
-};
-
-// TraceBuffer holds the events as they are collected.
-class BASE_EXPORT TraceBuffer {
- public:
- virtual ~TraceBuffer() = default;
-
- virtual std::unique_ptr<TraceBufferChunk> GetChunk(size_t* index) = 0;
- virtual void ReturnChunk(size_t index,
- std::unique_ptr<TraceBufferChunk> chunk) = 0;
-
- virtual bool IsFull() const = 0;
- virtual size_t Size() const = 0;
- virtual size_t Capacity() const = 0;
- virtual TraceEvent* GetEventByHandle(TraceEventHandle handle) = 0;
-
- // For iteration. Each TraceBuffer can only be iterated once.
- virtual const TraceBufferChunk* NextChunk() = 0;
-
-
- // Computes an estimate of the size of the buffer, including all the retained
- // objects.
- virtual void EstimateTraceMemoryOverhead(
- TraceEventMemoryOverhead* overhead) = 0;
-
- static TraceBuffer* CreateTraceBufferRingBuffer(size_t max_chunks);
- static TraceBuffer* CreateTraceBufferVectorOfSize(size_t max_chunks);
-};
-
-// TraceResultBuffer collects and converts trace fragments returned by TraceLog
-// to JSON output.
-class BASE_EXPORT TraceResultBuffer {
- public:
- typedef base::Callback<void(const std::string&)> OutputCallback;
-
- // If you don't need to stream JSON chunks out efficiently, and just want to
- // get a complete JSON string after calling Finish, use this struct to collect
- // JSON trace output.
- struct BASE_EXPORT SimpleOutput {
- OutputCallback GetCallback();
- void Append(const std::string& json_string);
-
- // Do what you want with the json_output_ string after calling
- // TraceResultBuffer::Finish.
- std::string json_output;
- };
-
- TraceResultBuffer();
- ~TraceResultBuffer();
-
- // Set callback. The callback will be called during Start with the initial
- // JSON output and during AddFragment and Finish with following JSON output
- // chunks. The callback target must live past the last calls to
- // TraceResultBuffer::Start/AddFragment/Finish.
- void SetOutputCallback(const OutputCallback& json_chunk_callback);
-
- // Start JSON output. This resets all internal state, so you can reuse
- // the TraceResultBuffer by calling Start.
- void Start();
-
- // Call AddFragment 0 or more times to add trace fragments from TraceLog.
- void AddFragment(const std::string& trace_fragment);
-
- // When all fragments have been added, call Finish to complete the JSON
- // formatted output.
- void Finish();
-
- private:
- OutputCallback output_callback_;
- bool append_comma_;
-};
-
-} // namespace trace_event
-} // namespace base
-
-#endif // BASE_TRACE_EVENT_TRACE_BUFFER_H_
diff --git a/base/trace_event/trace_category.h b/base/trace_event/trace_category.h
deleted file mode 100644
index 792bc5e..0000000
--- a/base/trace_event/trace_category.h
+++ /dev/null
@@ -1,109 +0,0 @@
-// Copyright 2016 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_CATEGORY_H_
-#define BASE_TRACE_EVENT_TRACE_CATEGORY_H_
-
-#include <stdint.h>
-
-namespace base {
-namespace trace_event {
-
-// Captures the state of an invidivual trace category. Nothing except tracing
-// internals (e.g., TraceLog) is supposed to have non-const Category pointers.
-struct TraceCategory {
- // The TRACE_EVENT macros should only use this value as a bool.
- // These enum values are effectively a public API and third_party projects
- // depend on their value. Hence, never remove or recycle existing bits, unless
- // you are sure that all the third-party projects that depend on this have
- // been updated.
- enum StateFlags : uint8_t {
- ENABLED_FOR_RECORDING = 1 << 0,
-
- // Not used anymore.
- DEPRECATED_ENABLED_FOR_MONITORING = 1 << 1,
- DEPRECATED_ENABLED_FOR_EVENT_CALLBACK = 1 << 2,
-
- ENABLED_FOR_ETW_EXPORT = 1 << 3,
- ENABLED_FOR_FILTERING = 1 << 4
- };
-
- static const TraceCategory* FromStatePtr(const uint8_t* state_ptr) {
- static_assert(
- offsetof(TraceCategory, state_) == 0,
- "|state_| must be the first field of the TraceCategory class.");
- return reinterpret_cast<const TraceCategory*>(state_ptr);
- }
-
- bool is_valid() const { return name_ != nullptr; }
- void set_name(const char* name) { name_ = name; }
- const char* name() const {
- DCHECK(is_valid());
- return name_;
- }
-
- // TODO(primiano): This is an intermediate solution to deal with the fact that
- // today TRACE_EVENT* macros cache the state ptr. They should just cache the
- // full TraceCategory ptr, which is immutable, and use these helper function
- // here. This will get rid of the need of this awkward ptr getter completely.
- const uint8_t* state_ptr() const {
- return const_cast<const uint8_t*>(&state_);
- }
-
- uint8_t state() const {
- return *const_cast<volatile const uint8_t*>(&state_);
- }
-
- bool is_enabled() const { return state() != 0; }
-
- void set_state(uint8_t state) {
- *const_cast<volatile uint8_t*>(&state_) = state;
- }
-
- void clear_state_flag(StateFlags flag) { set_state(state() & (~flag)); }
- void set_state_flag(StateFlags flag) { set_state(state() | flag); }
-
- uint32_t enabled_filters() const {
- return *const_cast<volatile const uint32_t*>(&enabled_filters_);
- }
-
- bool is_filter_enabled(size_t index) const {
- DCHECK(index < sizeof(enabled_filters_) * 8);
- return (enabled_filters() & (1 << index)) != 0;
- }
-
- void set_enabled_filters(uint32_t enabled_filters) {
- *const_cast<volatile uint32_t*>(&enabled_filters_) = enabled_filters;
- }
-
- void reset_for_testing() {
- set_state(0);
- set_enabled_filters(0);
- }
-
- // These fields should not be accessed directly, not even by tracing code.
- // The only reason why these are not private is because it makes it impossible
- // to have a global array of TraceCategory in category_registry.cc without
- // creating initializers. See discussion on goo.gl/qhZN94 and
- // crbug.com/{660967,660828}.
-
- // The enabled state. TRACE_EVENT* macros will capture events if any of the
- // flags here are set. Since TRACE_EVENTx macros are used in a lot of
- // fast-paths, accesses to this field are non-barriered and racy by design.
- // This field is mutated when starting/stopping tracing and we don't care
- // about missing some events.
- uint8_t state_;
-
- // When ENABLED_FOR_FILTERING is set, this contains a bitmap to the
- // corresponding filter (see event_filters.h).
- uint32_t enabled_filters_;
-
- // TraceCategory group names are long lived static strings.
- const char* name_;
-};
-
-} // namespace trace_event
-} // namespace base
-
-#endif // BASE_TRACE_EVENT_TRACE_CATEGORY_H_
diff --git a/base/trace_event/trace_config.cc b/base/trace_event/trace_config.cc
deleted file mode 100644
index 624a29c..0000000
--- a/base/trace_event/trace_config.cc
+++ /dev/null
@@ -1,557 +0,0 @@
-// Copyright (c) 2015 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_config.h"
-
-#include <stddef.h>
-
-#include <utility>
-
-#include "base/json/json_reader.h"
-#include "base/json/json_writer.h"
-#include "base/memory/ptr_util.h"
-#include "base/strings/string_split.h"
-#include "base/trace_event/memory_dump_manager.h"
-#include "base/trace_event/memory_dump_request_args.h"
-#include "base/trace_event/trace_event.h"
-
-namespace base {
-namespace trace_event {
-
-namespace {
-
-// String options that can be used to initialize TraceOptions.
-const char kRecordUntilFull[] = "record-until-full";
-const char kRecordContinuously[] = "record-continuously";
-const char kRecordAsMuchAsPossible[] = "record-as-much-as-possible";
-const char kTraceToConsole[] = "trace-to-console";
-const char kEnableSystrace[] = "enable-systrace";
-const char kEnableArgumentFilter[] = "enable-argument-filter";
-
-// String parameters that can be used to parse the trace config string.
-const char kRecordModeParam[] = "record_mode";
-const char kEnableSystraceParam[] = "enable_systrace";
-const char kEnableArgumentFilterParam[] = "enable_argument_filter";
-
-// String parameters that is used to parse memory dump config in trace config
-// string.
-const char kMemoryDumpConfigParam[] = "memory_dump_config";
-const char kAllowedDumpModesParam[] = "allowed_dump_modes";
-const char kTriggersParam[] = "triggers";
-const char kTriggerModeParam[] = "mode";
-const char kMinTimeBetweenDumps[] = "min_time_between_dumps_ms";
-const char kTriggerTypeParam[] = "type";
-const char kPeriodicIntervalLegacyParam[] = "periodic_interval_ms";
-const char kHeapProfilerOptions[] = "heap_profiler_options";
-const char kBreakdownThresholdBytes[] = "breakdown_threshold_bytes";
-
-// String parameters used to parse category event filters.
-const char kEventFiltersParam[] = "event_filters";
-const char kFilterPredicateParam[] = "filter_predicate";
-const char kFilterArgsParam[] = "filter_args";
-
-class ConvertableTraceConfigToTraceFormat
- : public base::trace_event::ConvertableToTraceFormat {
- public:
- explicit ConvertableTraceConfigToTraceFormat(const TraceConfig& trace_config)
- : trace_config_(trace_config) {}
-
- ~ConvertableTraceConfigToTraceFormat() override = default;
-
- void AppendAsTraceFormat(std::string* out) const override {
- out->append(trace_config_.ToString());
- }
-
- private:
- const TraceConfig trace_config_;
-};
-
-std::set<MemoryDumpLevelOfDetail> GetDefaultAllowedMemoryDumpModes() {
- std::set<MemoryDumpLevelOfDetail> all_modes;
- for (uint32_t mode = static_cast<uint32_t>(MemoryDumpLevelOfDetail::FIRST);
- mode <= static_cast<uint32_t>(MemoryDumpLevelOfDetail::LAST); mode++) {
- all_modes.insert(static_cast<MemoryDumpLevelOfDetail>(mode));
- }
- return all_modes;
-}
-
-} // namespace
-
-TraceConfig::MemoryDumpConfig::HeapProfiler::HeapProfiler()
- : breakdown_threshold_bytes(kDefaultBreakdownThresholdBytes) {}
-
-void TraceConfig::MemoryDumpConfig::HeapProfiler::Clear() {
- breakdown_threshold_bytes = kDefaultBreakdownThresholdBytes;
-}
-
-void TraceConfig::ResetMemoryDumpConfig(
- const TraceConfig::MemoryDumpConfig& memory_dump_config) {
- memory_dump_config_.Clear();
- memory_dump_config_ = memory_dump_config;
-}
-
-TraceConfig::MemoryDumpConfig::MemoryDumpConfig() = default;
-
-TraceConfig::MemoryDumpConfig::MemoryDumpConfig(
- const MemoryDumpConfig& other) = default;
-
-TraceConfig::MemoryDumpConfig::~MemoryDumpConfig() = default;
-
-void TraceConfig::MemoryDumpConfig::Clear() {
- allowed_dump_modes.clear();
- triggers.clear();
- heap_profiler_options.Clear();
-}
-
-void TraceConfig::MemoryDumpConfig::Merge(
- const TraceConfig::MemoryDumpConfig& config) {
- triggers.insert(triggers.end(), config.triggers.begin(),
- config.triggers.end());
- allowed_dump_modes.insert(config.allowed_dump_modes.begin(),
- config.allowed_dump_modes.end());
- heap_profiler_options.breakdown_threshold_bytes =
- std::min(heap_profiler_options.breakdown_threshold_bytes,
- config.heap_profiler_options.breakdown_threshold_bytes);
-}
-
-TraceConfig::EventFilterConfig::EventFilterConfig(
- const std::string& predicate_name)
- : predicate_name_(predicate_name) {}
-
-TraceConfig::EventFilterConfig::~EventFilterConfig() = default;
-
-TraceConfig::EventFilterConfig::EventFilterConfig(const EventFilterConfig& tc) {
- *this = tc;
-}
-
-TraceConfig::EventFilterConfig& TraceConfig::EventFilterConfig::operator=(
- const TraceConfig::EventFilterConfig& rhs) {
- if (this == &rhs)
- return *this;
-
- predicate_name_ = rhs.predicate_name_;
- category_filter_ = rhs.category_filter_;
-
- if (rhs.args_)
- args_ = rhs.args_->CreateDeepCopy();
-
- return *this;
-}
-
-void TraceConfig::EventFilterConfig::InitializeFromConfigDict(
- const base::DictionaryValue* event_filter) {
- category_filter_.InitializeFromConfigDict(*event_filter);
-
- const base::DictionaryValue* args_dict = nullptr;
- if (event_filter->GetDictionary(kFilterArgsParam, &args_dict))
- args_ = args_dict->CreateDeepCopy();
-}
-
-void TraceConfig::EventFilterConfig::SetCategoryFilter(
- const TraceConfigCategoryFilter& category_filter) {
- category_filter_ = category_filter;
-}
-
-void TraceConfig::EventFilterConfig::ToDict(
- DictionaryValue* filter_dict) const {
- filter_dict->SetString(kFilterPredicateParam, predicate_name());
-
- category_filter_.ToDict(filter_dict);
-
- if (args_)
- filter_dict->Set(kFilterArgsParam, args_->CreateDeepCopy());
-}
-
-bool TraceConfig::EventFilterConfig::GetArgAsSet(
- const char* key,
- std::unordered_set<std::string>* out_set) const {
- const ListValue* list = nullptr;
- if (!args_->GetList(key, &list))
- return false;
- for (size_t i = 0; i < list->GetSize(); ++i) {
- std::string value;
- if (list->GetString(i, &value))
- out_set->insert(value);
- }
- return true;
-}
-
-bool TraceConfig::EventFilterConfig::IsCategoryGroupEnabled(
- const StringPiece& category_group_name) const {
- return category_filter_.IsCategoryGroupEnabled(category_group_name);
-}
-
-// static
-std::string TraceConfig::TraceRecordModeToStr(TraceRecordMode record_mode) {
- switch (record_mode) {
- case RECORD_UNTIL_FULL:
- return kRecordUntilFull;
- case RECORD_CONTINUOUSLY:
- return kRecordContinuously;
- case RECORD_AS_MUCH_AS_POSSIBLE:
- return kRecordAsMuchAsPossible;
- case ECHO_TO_CONSOLE:
- return kTraceToConsole;
- default:
- NOTREACHED();
- }
- return kRecordUntilFull;
-}
-
-TraceConfig::TraceConfig() {
- InitializeDefault();
-}
-
-TraceConfig::TraceConfig(StringPiece category_filter_string,
- StringPiece trace_options_string) {
- InitializeFromStrings(category_filter_string, trace_options_string);
-}
-
-TraceConfig::TraceConfig(StringPiece category_filter_string,
- TraceRecordMode record_mode) {
- InitializeFromStrings(category_filter_string,
- TraceConfig::TraceRecordModeToStr(record_mode));
-}
-
-TraceConfig::TraceConfig(const DictionaryValue& config) {
- InitializeFromConfigDict(config);
-}
-
-TraceConfig::TraceConfig(StringPiece config_string) {
- if (!config_string.empty())
- InitializeFromConfigString(config_string);
- else
- InitializeDefault();
-}
-
-TraceConfig::TraceConfig(const TraceConfig& tc) = default;
-
-TraceConfig::~TraceConfig() = default;
-
-TraceConfig& TraceConfig::operator=(const TraceConfig& rhs) {
- if (this == &rhs)
- return *this;
-
- record_mode_ = rhs.record_mode_;
- enable_systrace_ = rhs.enable_systrace_;
- enable_argument_filter_ = rhs.enable_argument_filter_;
- category_filter_ = rhs.category_filter_;
- memory_dump_config_ = rhs.memory_dump_config_;
- event_filters_ = rhs.event_filters_;
- return *this;
-}
-
-std::string TraceConfig::ToString() const {
- std::unique_ptr<DictionaryValue> dict = ToDict();
- std::string json;
- JSONWriter::Write(*dict, &json);
- return json;
-}
-
-std::unique_ptr<ConvertableToTraceFormat>
-TraceConfig::AsConvertableToTraceFormat() const {
- return std::make_unique<ConvertableTraceConfigToTraceFormat>(*this);
-}
-
-std::string TraceConfig::ToCategoryFilterString() const {
- return category_filter_.ToFilterString();
-}
-
-bool TraceConfig::IsCategoryGroupEnabled(
- const StringPiece& category_group_name) const {
- // TraceLog should call this method only as part of enabling/disabling
- // categories.
- return category_filter_.IsCategoryGroupEnabled(category_group_name);
-}
-
-void TraceConfig::Merge(const TraceConfig& config) {
- if (record_mode_ != config.record_mode_
- || enable_systrace_ != config.enable_systrace_
- || enable_argument_filter_ != config.enable_argument_filter_) {
- DLOG(ERROR) << "Attempting to merge trace config with a different "
- << "set of options.";
- }
-
- category_filter_.Merge(config.category_filter_);
-
- memory_dump_config_.Merge(config.memory_dump_config_);
-
- event_filters_.insert(event_filters_.end(), config.event_filters().begin(),
- config.event_filters().end());
-}
-
-void TraceConfig::Clear() {
- record_mode_ = RECORD_UNTIL_FULL;
- enable_systrace_ = false;
- enable_argument_filter_ = false;
- category_filter_.Clear();
- memory_dump_config_.Clear();
- event_filters_.clear();
-}
-
-void TraceConfig::InitializeDefault() {
- record_mode_ = RECORD_UNTIL_FULL;
- enable_systrace_ = false;
- enable_argument_filter_ = false;
-}
-
-void TraceConfig::InitializeFromConfigDict(const DictionaryValue& dict) {
- record_mode_ = RECORD_UNTIL_FULL;
- std::string record_mode;
- if (dict.GetString(kRecordModeParam, &record_mode)) {
- if (record_mode == kRecordUntilFull) {
- record_mode_ = RECORD_UNTIL_FULL;
- } else if (record_mode == kRecordContinuously) {
- record_mode_ = RECORD_CONTINUOUSLY;
- } else if (record_mode == kTraceToConsole) {
- record_mode_ = ECHO_TO_CONSOLE;
- } else if (record_mode == kRecordAsMuchAsPossible) {
- record_mode_ = RECORD_AS_MUCH_AS_POSSIBLE;
- }
- }
-
- bool val;
- enable_systrace_ = dict.GetBoolean(kEnableSystraceParam, &val) ? val : false;
- enable_argument_filter_ =
- dict.GetBoolean(kEnableArgumentFilterParam, &val) ? val : false;
-
- category_filter_.InitializeFromConfigDict(dict);
-
- const base::ListValue* category_event_filters = nullptr;
- if (dict.GetList(kEventFiltersParam, &category_event_filters))
- SetEventFiltersFromConfigList(*category_event_filters);
-
- if (category_filter_.IsCategoryEnabled(MemoryDumpManager::kTraceCategory)) {
- // If dump triggers not set, the client is using the legacy with just
- // category enabled. So, use the default periodic dump config.
- const DictionaryValue* memory_dump_config = nullptr;
- if (dict.GetDictionary(kMemoryDumpConfigParam, &memory_dump_config))
- SetMemoryDumpConfigFromConfigDict(*memory_dump_config);
- else
- SetDefaultMemoryDumpConfig();
- }
-}
-
-void TraceConfig::InitializeFromConfigString(StringPiece config_string) {
- auto dict = DictionaryValue::From(JSONReader::Read(config_string));
- if (dict)
- InitializeFromConfigDict(*dict);
- else
- InitializeDefault();
-}
-
-void TraceConfig::InitializeFromStrings(StringPiece category_filter_string,
- StringPiece trace_options_string) {
- if (!category_filter_string.empty())
- category_filter_.InitializeFromString(category_filter_string);
-
- record_mode_ = RECORD_UNTIL_FULL;
- enable_systrace_ = false;
- enable_argument_filter_ = false;
- if (!trace_options_string.empty()) {
- std::vector<std::string> split =
- SplitString(trace_options_string, ",", TRIM_WHITESPACE, SPLIT_WANT_ALL);
- for (const std::string& token : split) {
- if (token == kRecordUntilFull) {
- record_mode_ = RECORD_UNTIL_FULL;
- } else if (token == kRecordContinuously) {
- record_mode_ = RECORD_CONTINUOUSLY;
- } else if (token == kTraceToConsole) {
- record_mode_ = ECHO_TO_CONSOLE;
- } else if (token == kRecordAsMuchAsPossible) {
- record_mode_ = RECORD_AS_MUCH_AS_POSSIBLE;
- } else if (token == kEnableSystrace) {
- enable_systrace_ = true;
- } else if (token == kEnableArgumentFilter) {
- enable_argument_filter_ = true;
- }
- }
- }
-
- if (category_filter_.IsCategoryEnabled(MemoryDumpManager::kTraceCategory)) {
- SetDefaultMemoryDumpConfig();
- }
-}
-
-void TraceConfig::SetMemoryDumpConfigFromConfigDict(
- const DictionaryValue& memory_dump_config) {
- // Set allowed dump modes.
- memory_dump_config_.allowed_dump_modes.clear();
- const ListValue* allowed_modes_list;
- if (memory_dump_config.GetList(kAllowedDumpModesParam, &allowed_modes_list)) {
- for (size_t i = 0; i < allowed_modes_list->GetSize(); ++i) {
- std::string level_of_detail_str;
- allowed_modes_list->GetString(i, &level_of_detail_str);
- memory_dump_config_.allowed_dump_modes.insert(
- StringToMemoryDumpLevelOfDetail(level_of_detail_str));
- }
- } else {
- // If allowed modes param is not given then allow all modes by default.
- memory_dump_config_.allowed_dump_modes = GetDefaultAllowedMemoryDumpModes();
- }
-
- // Set triggers
- memory_dump_config_.triggers.clear();
- const ListValue* trigger_list = nullptr;
- if (memory_dump_config.GetList(kTriggersParam, &trigger_list) &&
- trigger_list->GetSize() > 0) {
- for (size_t i = 0; i < trigger_list->GetSize(); ++i) {
- const DictionaryValue* trigger = nullptr;
- if (!trigger_list->GetDictionary(i, &trigger))
- continue;
-
- MemoryDumpConfig::Trigger dump_config;
- int interval = 0;
- if (!trigger->GetInteger(kMinTimeBetweenDumps, &interval)) {
- // If "min_time_between_dumps_ms" param was not given, then the trace
- // config uses old format where only periodic dumps are supported.
- trigger->GetInteger(kPeriodicIntervalLegacyParam, &interval);
- dump_config.trigger_type = MemoryDumpType::PERIODIC_INTERVAL;
- } else {
- std::string trigger_type_str;
- trigger->GetString(kTriggerTypeParam, &trigger_type_str);
- dump_config.trigger_type = StringToMemoryDumpType(trigger_type_str);
- }
- DCHECK_GT(interval, 0);
- dump_config.min_time_between_dumps_ms = static_cast<uint32_t>(interval);
-
- std::string level_of_detail_str;
- trigger->GetString(kTriggerModeParam, &level_of_detail_str);
- dump_config.level_of_detail =
- StringToMemoryDumpLevelOfDetail(level_of_detail_str);
-
- memory_dump_config_.triggers.push_back(dump_config);
- }
- }
-
- // Set heap profiler options
- const DictionaryValue* heap_profiler_options = nullptr;
- if (memory_dump_config.GetDictionary(kHeapProfilerOptions,
- &heap_profiler_options)) {
- int min_size_bytes = 0;
- if (heap_profiler_options->GetInteger(kBreakdownThresholdBytes,
- &min_size_bytes)
- && min_size_bytes >= 0) {
- memory_dump_config_.heap_profiler_options.breakdown_threshold_bytes =
- static_cast<size_t>(min_size_bytes);
- } else {
- memory_dump_config_.heap_profiler_options.breakdown_threshold_bytes =
- MemoryDumpConfig::HeapProfiler::kDefaultBreakdownThresholdBytes;
- }
- }
-}
-
-void TraceConfig::SetDefaultMemoryDumpConfig() {
- memory_dump_config_.Clear();
- memory_dump_config_.allowed_dump_modes = GetDefaultAllowedMemoryDumpModes();
-}
-
-void TraceConfig::SetEventFiltersFromConfigList(
- const base::ListValue& category_event_filters) {
- event_filters_.clear();
-
- for (size_t event_filter_index = 0;
- event_filter_index < category_event_filters.GetSize();
- ++event_filter_index) {
- const base::DictionaryValue* event_filter = nullptr;
- if (!category_event_filters.GetDictionary(event_filter_index,
- &event_filter))
- continue;
-
- std::string predicate_name;
- CHECK(event_filter->GetString(kFilterPredicateParam, &predicate_name))
- << "Invalid predicate name in category event filter.";
-
- EventFilterConfig new_config(predicate_name);
- new_config.InitializeFromConfigDict(event_filter);
- event_filters_.push_back(new_config);
- }
-}
-
-std::unique_ptr<DictionaryValue> TraceConfig::ToDict() const {
- auto dict = std::make_unique<DictionaryValue>();
- dict->SetString(kRecordModeParam,
- TraceConfig::TraceRecordModeToStr(record_mode_));
- dict->SetBoolean(kEnableSystraceParam, enable_systrace_);
- dict->SetBoolean(kEnableArgumentFilterParam, enable_argument_filter_);
-
- category_filter_.ToDict(dict.get());
-
- if (!event_filters_.empty()) {
- std::unique_ptr<base::ListValue> filter_list(new base::ListValue());
- for (const EventFilterConfig& filter : event_filters_) {
- std::unique_ptr<base::DictionaryValue> filter_dict(
- new base::DictionaryValue());
- filter.ToDict(filter_dict.get());
- filter_list->Append(std::move(filter_dict));
- }
- dict->Set(kEventFiltersParam, std::move(filter_list));
- }
-
- if (category_filter_.IsCategoryEnabled(MemoryDumpManager::kTraceCategory)) {
- auto allowed_modes = std::make_unique<ListValue>();
- for (auto dump_mode : memory_dump_config_.allowed_dump_modes)
- allowed_modes->AppendString(MemoryDumpLevelOfDetailToString(dump_mode));
-
- auto memory_dump_config = std::make_unique<DictionaryValue>();
- memory_dump_config->Set(kAllowedDumpModesParam, std::move(allowed_modes));
-
- auto triggers_list = std::make_unique<ListValue>();
- for (const auto& config : memory_dump_config_.triggers) {
- auto trigger_dict = std::make_unique<DictionaryValue>();
- trigger_dict->SetString(kTriggerTypeParam,
- MemoryDumpTypeToString(config.trigger_type));
- trigger_dict->SetInteger(
- kMinTimeBetweenDumps,
- static_cast<int>(config.min_time_between_dumps_ms));
- trigger_dict->SetString(
- kTriggerModeParam,
- MemoryDumpLevelOfDetailToString(config.level_of_detail));
- triggers_list->Append(std::move(trigger_dict));
- }
-
- // Empty triggers will still be specified explicitly since it means that
- // the periodic dumps are not enabled.
- memory_dump_config->Set(kTriggersParam, std::move(triggers_list));
-
- if (memory_dump_config_.heap_profiler_options.breakdown_threshold_bytes !=
- MemoryDumpConfig::HeapProfiler::kDefaultBreakdownThresholdBytes) {
- auto options = std::make_unique<DictionaryValue>();
- options->SetInteger(
- kBreakdownThresholdBytes,
- memory_dump_config_.heap_profiler_options.breakdown_threshold_bytes);
- memory_dump_config->Set(kHeapProfilerOptions, std::move(options));
- }
- dict->Set(kMemoryDumpConfigParam, std::move(memory_dump_config));
- }
- return dict;
-}
-
-std::string TraceConfig::ToTraceOptionsString() const {
- std::string ret;
- switch (record_mode_) {
- case RECORD_UNTIL_FULL:
- ret = kRecordUntilFull;
- break;
- case RECORD_CONTINUOUSLY:
- ret = kRecordContinuously;
- break;
- case RECORD_AS_MUCH_AS_POSSIBLE:
- ret = kRecordAsMuchAsPossible;
- break;
- case ECHO_TO_CONSOLE:
- ret = kTraceToConsole;
- break;
- default:
- NOTREACHED();
- }
- if (enable_systrace_)
- ret = ret + "," + kEnableSystrace;
- if (enable_argument_filter_)
- ret = ret + "," + kEnableArgumentFilter;
- return ret;
-}
-
-} // namespace trace_event
-} // namespace base
diff --git a/base/trace_event/trace_config.h b/base/trace_event/trace_config.h
deleted file mode 100644
index decd54d..0000000
--- a/base/trace_event/trace_config.h
+++ /dev/null
@@ -1,289 +0,0 @@
-// Copyright 2015 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_CONFIG_H_
-#define BASE_TRACE_EVENT_TRACE_CONFIG_H_
-
-#include <stdint.h>
-
-#include <memory>
-#include <set>
-#include <string>
-#include <unordered_set>
-#include <vector>
-
-#include "base/base_export.h"
-#include "base/gtest_prod_util.h"
-#include "base/strings/string_piece.h"
-#include "base/trace_event/memory_dump_request_args.h"
-#include "base/trace_event/trace_config_category_filter.h"
-#include "base/values.h"
-
-namespace base {
-namespace trace_event {
-
-class ConvertableToTraceFormat;
-
-// Options determines how the trace buffer stores data.
-// A Java counterpart will be generated for this enum.
-// GENERATED_JAVA_ENUM_PACKAGE: org.chromium.base
-enum TraceRecordMode {
- // Record until the trace buffer is full.
- RECORD_UNTIL_FULL,
-
- // Record until the user ends the trace. The trace buffer is a fixed size
- // and we use it as a ring buffer during recording.
- RECORD_CONTINUOUSLY,
-
- // Record until the trace buffer is full, but with a huge buffer size.
- RECORD_AS_MUCH_AS_POSSIBLE,
-
- // Echo to console. Events are discarded.
- ECHO_TO_CONSOLE,
-};
-
-class BASE_EXPORT TraceConfig {
- public:
- using StringList = std::vector<std::string>;
-
- // Specifies the memory dump config for tracing.
- // Used only when "memory-infra" category is enabled.
- struct BASE_EXPORT MemoryDumpConfig {
- MemoryDumpConfig();
- MemoryDumpConfig(const MemoryDumpConfig& other);
- ~MemoryDumpConfig();
-
- // Specifies the triggers in the memory dump config.
- struct Trigger {
- uint32_t min_time_between_dumps_ms;
- MemoryDumpLevelOfDetail level_of_detail;
- MemoryDumpType trigger_type;
- };
-
- // Specifies the configuration options for the heap profiler.
- struct HeapProfiler {
- // Default value for |breakdown_threshold_bytes|.
- enum { kDefaultBreakdownThresholdBytes = 1024 };
-
- HeapProfiler();
-
- // Reset the options to default.
- void Clear();
-
- uint32_t breakdown_threshold_bytes;
- };
-
- // Reset the values in the config.
- void Clear();
-
- void Merge(const MemoryDumpConfig& config);
-
- // Set of memory dump modes allowed for the tracing session. The explicitly
- // triggered dumps will be successful only if the dump mode is allowed in
- // the config.
- std::set<MemoryDumpLevelOfDetail> allowed_dump_modes;
-
- std::vector<Trigger> triggers;
- HeapProfiler heap_profiler_options;
- };
-
- class BASE_EXPORT EventFilterConfig {
- public:
- EventFilterConfig(const std::string& predicate_name);
- EventFilterConfig(const EventFilterConfig& tc);
-
- ~EventFilterConfig();
-
- EventFilterConfig& operator=(const EventFilterConfig& rhs);
-
- void InitializeFromConfigDict(const base::DictionaryValue* event_filter);
-
- void SetCategoryFilter(const TraceConfigCategoryFilter& category_filter);
-
- void ToDict(DictionaryValue* filter_dict) const;
-
- bool GetArgAsSet(const char* key, std::unordered_set<std::string>*) const;
-
- bool IsCategoryGroupEnabled(const StringPiece& category_group_name) const;
-
- const std::string& predicate_name() const { return predicate_name_; }
- base::DictionaryValue* filter_args() const { return args_.get(); }
- const TraceConfigCategoryFilter& category_filter() const {
- return category_filter_;
- }
-
- private:
- std::string predicate_name_;
- TraceConfigCategoryFilter category_filter_;
- std::unique_ptr<base::DictionaryValue> args_;
- };
- typedef std::vector<EventFilterConfig> EventFilters;
-
- static std::string TraceRecordModeToStr(TraceRecordMode record_mode);
-
- TraceConfig();
-
- // Create TraceConfig object from category filter and trace options strings.
- //
- // |category_filter_string| is a comma-delimited list of category wildcards.
- // A category can have an optional '-' prefix to make it an excluded category.
- // All the same rules apply above, so for example, having both included and
- // excluded categories in the same list would not be supported.
- //
- // |trace_options_string| is a comma-delimited list of trace options.
- // Possible options are: "record-until-full", "record-continuously",
- // "record-as-much-as-possible", "trace-to-console", "enable-systrace" and
- // "enable-argument-filter".
- // The first 4 options are trace recoding modes and hence
- // mutually exclusive. If more than one trace recording modes appear in the
- // options_string, the last one takes precedence. If none of the trace
- // recording mode is specified, recording mode is RECORD_UNTIL_FULL.
- //
- // The trace option will first be reset to the default option
- // (record_mode set to RECORD_UNTIL_FULL, enable_systrace and
- // enable_argument_filter set to false) before options parsed from
- // |trace_options_string| are applied on it. If |trace_options_string| is
- // invalid, the final state of trace options is undefined.
- //
- // Example: TraceConfig("test_MyTest*", "record-until-full");
- // Example: TraceConfig("test_MyTest*,test_OtherStuff",
- // "record-continuously");
- // Example: TraceConfig("-excluded_category1,-excluded_category2",
- // "record-until-full, trace-to-console");
- // would set ECHO_TO_CONSOLE as the recording mode.
- // Example: TraceConfig("-*,webkit", "");
- // would disable everything but webkit; and use default options.
- // Example: TraceConfig("-webkit", "");
- // would enable everything but webkit; and use default options.
- TraceConfig(StringPiece category_filter_string,
- StringPiece trace_options_string);
-
- TraceConfig(StringPiece category_filter_string, TraceRecordMode record_mode);
-
- // Create TraceConfig object from the trace config string.
- //
- // |config_string| is a dictionary formatted as a JSON string, containing both
- // category filters and trace options.
- //
- // Example:
- // {
- // "record_mode": "record-continuously",
- // "enable_systrace": true,
- // "enable_argument_filter": true,
- // "included_categories": ["included",
- // "inc_pattern*",
- // "disabled-by-default-memory-infra"],
- // "excluded_categories": ["excluded", "exc_pattern*"],
- // "memory_dump_config": {
- // "triggers": [
- // {
- // "mode": "detailed",
- // "periodic_interval_ms": 2000
- // }
- // ]
- // }
- // }
- //
- // Note: memory_dump_config can be specified only if
- // disabled-by-default-memory-infra category is enabled.
- explicit TraceConfig(StringPiece config_string);
-
- // Functionally identical to the above, but takes a parsed dictionary as input
- // instead of its JSON serialization.
- explicit TraceConfig(const DictionaryValue& config);
-
- TraceConfig(const TraceConfig& tc);
-
- ~TraceConfig();
-
- TraceConfig& operator=(const TraceConfig& rhs);
-
- TraceRecordMode GetTraceRecordMode() const { return record_mode_; }
- bool IsSystraceEnabled() const { return enable_systrace_; }
- bool IsArgumentFilterEnabled() const { return enable_argument_filter_; }
-
- void SetTraceRecordMode(TraceRecordMode mode) { record_mode_ = mode; }
- void EnableSystrace() { enable_systrace_ = true; }
- void EnableArgumentFilter() { enable_argument_filter_ = true; }
-
- // Writes the string representation of the TraceConfig. The string is JSON
- // formatted.
- std::string ToString() const;
-
- // Returns a copy of the TraceConfig wrapped in a ConvertableToTraceFormat
- std::unique_ptr<ConvertableToTraceFormat> AsConvertableToTraceFormat() const;
-
- // Write the string representation of the CategoryFilter part.
- std::string ToCategoryFilterString() const;
-
- // Returns true if at least one category in the list is enabled by this
- // trace config. This is used to determine if the category filters are
- // enabled in the TRACE_* macros.
- bool IsCategoryGroupEnabled(const StringPiece& category_group_name) const;
-
- // Merges config with the current TraceConfig
- void Merge(const TraceConfig& config);
-
- void Clear();
-
- // Clears and resets the memory dump config.
- void ResetMemoryDumpConfig(const MemoryDumpConfig& memory_dump_config);
-
- const TraceConfigCategoryFilter& category_filter() const {
- return category_filter_;
- }
-
- const MemoryDumpConfig& memory_dump_config() const {
- return memory_dump_config_;
- }
-
- const EventFilters& event_filters() const { return event_filters_; }
- void SetEventFilters(const EventFilters& filter_configs) {
- event_filters_ = filter_configs;
- }
-
- private:
- FRIEND_TEST_ALL_PREFIXES(TraceConfigTest, TraceConfigFromValidLegacyFormat);
- FRIEND_TEST_ALL_PREFIXES(TraceConfigTest,
- TraceConfigFromInvalidLegacyStrings);
-
- // The default trace config, used when none is provided.
- // Allows all non-disabled-by-default categories through, except if they end
- // in the suffix 'Debug' or 'Test'.
- void InitializeDefault();
-
- // Initialize from a config dictionary.
- void InitializeFromConfigDict(const DictionaryValue& dict);
-
- // Initialize from a config string.
- void InitializeFromConfigString(StringPiece config_string);
-
- // Initialize from category filter and trace options strings
- void InitializeFromStrings(StringPiece category_filter_string,
- StringPiece trace_options_string);
-
- void SetMemoryDumpConfigFromConfigDict(
- const DictionaryValue& memory_dump_config);
- void SetDefaultMemoryDumpConfig();
-
- void SetEventFiltersFromConfigList(const base::ListValue& event_filters);
- std::unique_ptr<DictionaryValue> ToDict() const;
-
- std::string ToTraceOptionsString() const;
-
- TraceRecordMode record_mode_;
- bool enable_systrace_ : 1;
- bool enable_argument_filter_ : 1;
-
- TraceConfigCategoryFilter category_filter_;
-
- MemoryDumpConfig memory_dump_config_;
-
- EventFilters event_filters_;
-};
-
-} // namespace trace_event
-} // namespace base
-
-#endif // BASE_TRACE_EVENT_TRACE_CONFIG_H_
diff --git a/base/trace_event/trace_config_category_filter.cc b/base/trace_event/trace_config_category_filter.cc
deleted file mode 100644
index d188430..0000000
--- a/base/trace_event/trace_config_category_filter.cc
+++ /dev/null
@@ -1,235 +0,0 @@
-// Copyright 2017 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_config_category_filter.h"
-
-#include "base/memory/ptr_util.h"
-#include "base/strings/pattern.h"
-#include "base/strings/string_split.h"
-#include "base/strings/string_tokenizer.h"
-#include "base/strings/string_util.h"
-#include "base/strings/stringprintf.h"
-#include "base/trace_event/trace_event.h"
-
-namespace base {
-namespace trace_event {
-
-namespace {
-const char kIncludedCategoriesParam[] = "included_categories";
-const char kExcludedCategoriesParam[] = "excluded_categories";
-}
-
-TraceConfigCategoryFilter::TraceConfigCategoryFilter() = default;
-
-TraceConfigCategoryFilter::TraceConfigCategoryFilter(
- const TraceConfigCategoryFilter& other) = default;
-
-TraceConfigCategoryFilter::~TraceConfigCategoryFilter() = default;
-
-TraceConfigCategoryFilter& TraceConfigCategoryFilter::operator=(
- const TraceConfigCategoryFilter& rhs) = default;
-
-void TraceConfigCategoryFilter::InitializeFromString(
- const StringPiece& category_filter_string) {
- std::vector<StringPiece> split = SplitStringPiece(
- category_filter_string, ",", TRIM_WHITESPACE, SPLIT_WANT_ALL);
- for (const StringPiece& category : split) {
- // Ignore empty categories.
- if (category.empty())
- continue;
- if (category.front() == '-') {
- // Excluded categories start with '-'.
- // Remove '-' from category string.
- excluded_categories_.push_back(category.substr(1).as_string());
- } else if (category.starts_with(TRACE_DISABLED_BY_DEFAULT(""))) {
- disabled_categories_.push_back(category.as_string());
- } else {
- included_categories_.push_back(category.as_string());
- }
- }
-}
-
-void TraceConfigCategoryFilter::InitializeFromConfigDict(
- const DictionaryValue& dict) {
- const ListValue* category_list = nullptr;
- if (dict.GetList(kIncludedCategoriesParam, &category_list))
- SetCategoriesFromIncludedList(*category_list);
- if (dict.GetList(kExcludedCategoriesParam, &category_list))
- SetCategoriesFromExcludedList(*category_list);
-}
-
-bool TraceConfigCategoryFilter::IsCategoryGroupEnabled(
- const StringPiece& category_group_name) const {
- bool had_enabled_by_default = false;
- DCHECK(!category_group_name.empty());
- CStringTokenizer category_group_tokens(category_group_name.begin(),
- category_group_name.end(), ",");
- while (category_group_tokens.GetNext()) {
- StringPiece category_group_token = category_group_tokens.token_piece();
- // Don't allow empty tokens, nor tokens with leading or trailing space.
- DCHECK(IsCategoryNameAllowed(category_group_token))
- << "Disallowed category string";
- if (IsCategoryEnabled(category_group_token))
- return true;
-
- if (!MatchPattern(category_group_token, TRACE_DISABLED_BY_DEFAULT("*")))
- had_enabled_by_default = true;
- }
- // Do a second pass to check for explicitly disabled categories
- // (those explicitly enabled have priority due to first pass).
- category_group_tokens.Reset();
- bool category_group_disabled = false;
- while (category_group_tokens.GetNext()) {
- StringPiece category_group_token = category_group_tokens.token_piece();
- for (const std::string& category : excluded_categories_) {
- if (MatchPattern(category_group_token, category)) {
- // Current token of category_group_name is present in excluded_list.
- // Flag the exclusion and proceed further to check if any of the
- // remaining categories of category_group_name is not present in the
- // excluded_ list.
- category_group_disabled = true;
- break;
- }
- // One of the category of category_group_name is not present in
- // excluded_ list. So, if it's not a disabled-by-default category,
- // it has to be included_ list. Enable the category_group_name
- // for recording.
- if (!MatchPattern(category_group_token, TRACE_DISABLED_BY_DEFAULT("*")))
- category_group_disabled = false;
- }
- // One of the categories present in category_group_name is not present in
- // excluded_ list. Implies this category_group_name group can be enabled
- // for recording, since one of its groups is enabled for recording.
- if (!category_group_disabled)
- break;
- }
- // If the category group is not excluded, and there are no included patterns
- // we consider this category group enabled, as long as it had categories
- // other than disabled-by-default.
- return !category_group_disabled && had_enabled_by_default &&
- included_categories_.empty();
-}
-
-bool TraceConfigCategoryFilter::IsCategoryEnabled(
- const StringPiece& category_name) const {
- // Check the disabled- filters and the disabled-* wildcard first so that a
- // "*" filter does not include the disabled.
- for (const std::string& category : disabled_categories_) {
- if (MatchPattern(category_name, category))
- return true;
- }
-
- if (MatchPattern(category_name, TRACE_DISABLED_BY_DEFAULT("*")))
- return false;
-
- for (const std::string& category : included_categories_) {
- if (MatchPattern(category_name, category))
- return true;
- }
-
- return false;
-}
-
-void TraceConfigCategoryFilter::Merge(const TraceConfigCategoryFilter& config) {
- // Keep included patterns only if both filters have an included entry.
- // Otherwise, one of the filter was specifying "*" and we want to honor the
- // broadest filter.
- if (!included_categories_.empty() && !config.included_categories_.empty()) {
- included_categories_.insert(included_categories_.end(),
- config.included_categories_.begin(),
- config.included_categories_.end());
- } else {
- included_categories_.clear();
- }
-
- disabled_categories_.insert(disabled_categories_.end(),
- config.disabled_categories_.begin(),
- config.disabled_categories_.end());
- excluded_categories_.insert(excluded_categories_.end(),
- config.excluded_categories_.begin(),
- config.excluded_categories_.end());
-}
-
-void TraceConfigCategoryFilter::Clear() {
- included_categories_.clear();
- disabled_categories_.clear();
- excluded_categories_.clear();
-}
-
-void TraceConfigCategoryFilter::ToDict(DictionaryValue* dict) const {
- StringList categories(included_categories_);
- categories.insert(categories.end(), disabled_categories_.begin(),
- disabled_categories_.end());
- AddCategoriesToDict(categories, kIncludedCategoriesParam, dict);
- AddCategoriesToDict(excluded_categories_, kExcludedCategoriesParam, dict);
-}
-
-std::string TraceConfigCategoryFilter::ToFilterString() const {
- std::string filter_string;
- WriteCategoryFilterString(included_categories_, &filter_string, true);
- WriteCategoryFilterString(disabled_categories_, &filter_string, true);
- WriteCategoryFilterString(excluded_categories_, &filter_string, false);
- return filter_string;
-}
-
-void TraceConfigCategoryFilter::SetCategoriesFromIncludedList(
- const ListValue& included_list) {
- included_categories_.clear();
- for (size_t i = 0; i < included_list.GetSize(); ++i) {
- std::string category;
- if (!included_list.GetString(i, &category))
- continue;
- if (category.compare(0, strlen(TRACE_DISABLED_BY_DEFAULT("")),
- TRACE_DISABLED_BY_DEFAULT("")) == 0) {
- disabled_categories_.push_back(category);
- } else {
- included_categories_.push_back(category);
- }
- }
-}
-
-void TraceConfigCategoryFilter::SetCategoriesFromExcludedList(
- const ListValue& excluded_list) {
- excluded_categories_.clear();
- for (size_t i = 0; i < excluded_list.GetSize(); ++i) {
- std::string category;
- if (excluded_list.GetString(i, &category))
- excluded_categories_.push_back(category);
- }
-}
-
-void TraceConfigCategoryFilter::AddCategoriesToDict(
- const StringList& categories,
- const char* param,
- DictionaryValue* dict) const {
- if (categories.empty())
- return;
-
- auto list = std::make_unique<ListValue>();
- for (const std::string& category : categories)
- list->AppendString(category);
- dict->Set(param, std::move(list));
-}
-
-void TraceConfigCategoryFilter::WriteCategoryFilterString(
- const StringList& values,
- std::string* out,
- bool included) const {
- bool prepend_comma = !out->empty();
- int token_cnt = 0;
- for (const std::string& category : values) {
- if (token_cnt > 0 || prepend_comma)
- StringAppendF(out, ",");
- StringAppendF(out, "%s%s", (included ? "" : "-"), category.c_str());
- ++token_cnt;
- }
-}
-
-// static
-bool TraceConfigCategoryFilter::IsCategoryNameAllowed(StringPiece str) {
- return !str.empty() && str.front() != ' ' && str.back() != ' ';
-}
-
-} // namespace trace_event
-} // namespace base
diff --git a/base/trace_event/trace_config_category_filter.h b/base/trace_event/trace_config_category_filter.h
deleted file mode 100644
index 0140c1d..0000000
--- a/base/trace_event/trace_config_category_filter.h
+++ /dev/null
@@ -1,81 +0,0 @@
-// Copyright 2017 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_CONFIG_CATEGORY_FILTER_H_
-#define BASE_TRACE_EVENT_TRACE_CONFIG_CATEGORY_FILTER_H_
-
-#include <string>
-#include <vector>
-
-#include "base/base_export.h"
-#include "base/strings/string_piece.h"
-#include "base/values.h"
-
-namespace base {
-namespace trace_event {
-
-// Configuration of categories enabled and disabled in TraceConfig.
-class BASE_EXPORT TraceConfigCategoryFilter {
- public:
- using StringList = std::vector<std::string>;
-
- TraceConfigCategoryFilter();
- TraceConfigCategoryFilter(const TraceConfigCategoryFilter& other);
- ~TraceConfigCategoryFilter();
-
- TraceConfigCategoryFilter& operator=(const TraceConfigCategoryFilter& rhs);
-
- // Initializes from category filter string. See TraceConfig constructor for
- // description of how to write category filter string.
- void InitializeFromString(const StringPiece& category_filter_string);
-
- // Initializes TraceConfigCategoryFilter object from the config dictionary.
- void InitializeFromConfigDict(const DictionaryValue& dict);
-
- // Merges this with category filter config.
- void Merge(const TraceConfigCategoryFilter& config);
- void Clear();
-
- // Returns true if at least one category in the list is enabled by this
- // trace config. This is used to determine if the category filters are
- // enabled in the TRACE_* macros.
- bool IsCategoryGroupEnabled(const StringPiece& category_group_name) const;
-
- // Returns true if the category is enabled according to this trace config.
- // This tells whether a category is enabled from the TraceConfig's
- // perspective. Please refer to IsCategoryGroupEnabled() to determine if a
- // category is enabled from the tracing runtime's perspective.
- bool IsCategoryEnabled(const StringPiece& category_name) const;
-
- void ToDict(DictionaryValue* dict) const;
-
- std::string ToFilterString() const;
-
- // Returns true if category name is a valid string.
- static bool IsCategoryNameAllowed(StringPiece str);
-
- const StringList& included_categories() const { return included_categories_; }
- const StringList& excluded_categories() const { return excluded_categories_; }
-
- private:
- void SetCategoriesFromIncludedList(const ListValue& included_list);
- void SetCategoriesFromExcludedList(const ListValue& excluded_list);
-
- void AddCategoriesToDict(const StringList& categories,
- const char* param,
- DictionaryValue* dict) const;
-
- void WriteCategoryFilterString(const StringList& values,
- std::string* out,
- bool included) const;
-
- StringList included_categories_;
- StringList disabled_categories_;
- StringList excluded_categories_;
-};
-
-} // namespace trace_event
-} // namespace base
-
-#endif // BASE_TRACE_EVENT_TRACE_CONFIG_CATEGORY_FILTER_H_
diff --git a/base/trace_event/trace_config_memory_test_util.h b/base/trace_event/trace_config_memory_test_util.h
deleted file mode 100644
index 57608fd..0000000
--- a/base/trace_event/trace_config_memory_test_util.h
+++ /dev/null
@@ -1,178 +0,0 @@
-// Copyright 2015 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_CONFIG_MEMORY_TEST_UTIL_H_
-#define BASE_TRACE_EVENT_TRACE_CONFIG_MEMORY_TEST_UTIL_H_
-
-#include "base/strings/stringprintf.h"
-#include "base/trace_event/memory_dump_manager.h"
-
-namespace base {
-namespace trace_event {
-
-class TraceConfigMemoryTestUtil {
- public:
- static std::string GetTraceConfig_LegacyPeriodicTriggers(int light_period,
- int heavy_period) {
- return StringPrintf(
- "{"
- "\"enable_argument_filter\":false,"
- "\"enable_systrace\":false,"
- "\"excluded_categories\":["
- "\"*\""
- "],"
- "\"included_categories\":["
- "\"%s\""
- "],"
- "\"memory_dump_config\":{"
- "\"allowed_dump_modes\":[\"background\",\"light\",\"detailed\"],"
- "\"heap_profiler_options\":{"
- "\"breakdown_threshold_bytes\":2048"
- "},"
- "\"triggers\":["
- "{"
- "\"mode\":\"light\","
- "\"periodic_interval_ms\":%d"
- "},"
- "{"
- "\"mode\":\"detailed\","
- "\"periodic_interval_ms\":%d"
- "}"
- "]"
- "},"
- "\"record_mode\":\"record-until-full\""
- "}",
- MemoryDumpManager::kTraceCategory, light_period, heavy_period);
- ;
- }
-
- static std::string GetTraceConfig_PeriodicTriggers(int light_period,
- int heavy_period) {
- return StringPrintf(
- "{"
- "\"enable_argument_filter\":false,"
- "\"enable_systrace\":false,"
- "\"excluded_categories\":["
- "\"*\""
- "],"
- "\"included_categories\":["
- "\"%s\""
- "],"
- "\"memory_dump_config\":{"
- "\"allowed_dump_modes\":[\"background\",\"light\",\"detailed\"],"
- "\"heap_profiler_options\":{"
- "\"breakdown_threshold_bytes\":2048"
- "},"
- "\"triggers\":["
- "{"
- "\"min_time_between_dumps_ms\":%d,"
- "\"mode\":\"light\","
- "\"type\":\"periodic_interval\""
- "},"
- "{"
- "\"min_time_between_dumps_ms\":%d,"
- "\"mode\":\"detailed\","
- "\"type\":\"periodic_interval\""
- "}"
- "]"
- "},"
- "\"record_mode\":\"record-until-full\""
- "}",
- MemoryDumpManager::kTraceCategory, light_period, heavy_period);
- }
-
- static std::string GetTraceConfig_EmptyTriggers() {
- return StringPrintf(
- "{"
- "\"enable_argument_filter\":false,"
- "\"enable_systrace\":false,"
- "\"excluded_categories\":["
- "\"*\""
- "],"
- "\"included_categories\":["
- "\"%s\""
- "],"
- "\"memory_dump_config\":{"
- "\"allowed_dump_modes\":[\"background\",\"light\",\"detailed\"],"
- "\"triggers\":["
- "]"
- "},"
- "\"record_mode\":\"record-until-full\""
- "}",
- MemoryDumpManager::kTraceCategory);
- }
-
- static std::string GetTraceConfig_NoTriggers() {
- return StringPrintf(
- "{"
- "\"enable_argument_filter\":false,"
- "\"enable_systrace\":false,"
- "\"excluded_categories\":["
- "\"*\""
- "],"
- "\"included_categories\":["
- "\"%s\""
- "],"
- "\"record_mode\":\"record-until-full\""
- "}",
- MemoryDumpManager::kTraceCategory);
- }
-
- static std::string GetTraceConfig_BackgroundTrigger(int period_ms) {
- return StringPrintf(
- "{"
- "\"enable_argument_filter\":false,"
- "\"enable_systrace\":false,"
- "\"excluded_categories\":["
- "\"*\""
- "],"
- "\"included_categories\":["
- "\"%s\""
- "],"
- "\"memory_dump_config\":{"
- "\"allowed_dump_modes\":[\"background\"],"
- "\"triggers\":["
- "{"
- "\"min_time_between_dumps_ms\":%d,"
- "\"mode\":\"background\","
- "\"type\":\"periodic_interval\""
- "}"
- "]"
- "},"
- "\"record_mode\":\"record-until-full\""
- "}",
- MemoryDumpManager::kTraceCategory, period_ms);
- }
-
- static std::string GetTraceConfig_PeakDetectionTrigger(int heavy_period) {
- return StringPrintf(
- "{"
- "\"enable_argument_filter\":false,"
- "\"enable_systrace\":false,"
- "\"excluded_categories\":["
- "\"*\""
- "],"
- "\"included_categories\":["
- "\"%s\""
- "],"
- "\"memory_dump_config\":{"
- "\"allowed_dump_modes\":[\"background\",\"light\",\"detailed\"],"
- "\"triggers\":["
- "{"
- "\"min_time_between_dumps_ms\":%d,"
- "\"mode\":\"detailed\","
- "\"type\":\"peak_memory_usage\""
- "}"
- "]"
- "},"
- "\"record_mode\":\"record-until-full\""
- "}",
- MemoryDumpManager::kTraceCategory, heavy_period);
- }
-};
-
-} // namespace trace_event
-} // namespace base
-
-#endif // BASE_TRACE_EVENT_TRACE_CONFIG_MEMORY_TEST_UTIL_H_
diff --git a/base/trace_event/trace_event.h b/base/trace_event/trace_event.h
deleted file mode 100644
index e3ee400..0000000
--- a/base/trace_event/trace_event.h
+++ /dev/null
@@ -1,1170 +0,0 @@
-// Copyright (c) 2012 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_EVENT_H_
-#define BASE_TRACE_EVENT_TRACE_EVENT_H_
-
-// This header file defines implementation details of how the trace macros in
-// trace_event_common.h collect and store trace events. Anything not
-// implementation-specific should go in trace_event_common.h instead of here.
-
-#include <stddef.h>
-#include <stdint.h>
-
-#include <string>
-
-#include "base/atomicops.h"
-#include "base/macros.h"
-#include "base/time/time.h"
-#include "base/time/time_override.h"
-#include "base/trace_event/common/trace_event_common.h"
-#include "base/trace_event/heap_profiler.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"
-#include "build_config.h"
-
-// 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) \
- trace_event_internal::TraceStringWithCopy(str)
-
-// DEPRECATED: do not use: Consider using TRACE_ID_{GLOBAL, LOCAL} macros,
-// instead. By default, uint64_t ID argument values are not mangled with the
-// Process ID in TRACE_EVENT_ASYNC macros. Use this macro to force Process ID
-// mangling.
-#define TRACE_ID_MANGLE(id) \
- trace_event_internal::TraceID::ForceMangle(id)
-
-// DEPRECATED: do not use: Consider using TRACE_ID_{GLOBAL, LOCAL} macros,
-// instead. By default, pointers are mangled with the Process ID in
-// TRACE_EVENT_ASYNC macros. Use this macro to prevent Process ID mangling.
-#define TRACE_ID_DONT_MANGLE(id) \
- trace_event_internal::TraceID::DontMangle(id)
-
-// By default, trace IDs are eventually converted to a single 64-bit number. Use
-// this macro to add a scope string. For example,
-//
-// TRACE_EVENT_NESTABLE_ASYNC_BEGIN0(
-// "network", "ResourceLoad",
-// TRACE_ID_WITH_SCOPE("BlinkResourceID", resourceID));
-//
-// Also, it is possible to prepend the ID with another number, like the process
-// ID. This is useful in creating IDs that are unique among all processes. To do
-// that, pass two numbers after the scope string instead of one. For example,
-//
-// TRACE_EVENT_NESTABLE_ASYNC_BEGIN0(
-// "network", "ResourceLoad",
-// TRACE_ID_WITH_SCOPE("BlinkResourceID", pid, resourceID));
-#define TRACE_ID_WITH_SCOPE(scope, ...) \
- trace_event_internal::TraceID::WithScope(scope, ##__VA_ARGS__)
-
-#define TRACE_ID_GLOBAL(id) trace_event_internal::TraceID::GlobalId(id)
-#define TRACE_ID_LOCAL(id) trace_event_internal::TraceID::LocalId(id)
-
-#define TRACE_EVENT_API_CURRENT_THREAD_ID \
- static_cast<int>(base::PlatformThread::CurrentId())
-
-#define INTERNAL_TRACE_EVENT_CATEGORY_GROUP_ENABLED_FOR_RECORDING_MODE() \
- UNLIKELY(*INTERNAL_TRACE_EVENT_UID(category_group_enabled) & \
- (base::trace_event::TraceCategory::ENABLED_FOR_RECORDING | \
- base::trace_event::TraceCategory::ENABLED_FOR_ETW_EXPORT))
-
-#define INTERNAL_TRACE_EVENT_CATEGORY_GROUP_ENABLED() \
- UNLIKELY(*INTERNAL_TRACE_EVENT_UID(category_group_enabled) & \
- (base::trace_event::TraceCategory::ENABLED_FOR_RECORDING | \
- base::trace_event::TraceCategory::ENABLED_FOR_ETW_EXPORT | \
- base::trace_event::TraceCategory::ENABLED_FOR_FILTERING))
-
-////////////////////////////////////////////////////////////////////////////////
-// Implementation specific tracing API definitions.
-
-// Get a pointer to the enabled state of the given trace category. Only
-// long-lived literal strings should be given as the category group. The
-// returned pointer can be held permanently in a local static for example. If
-// the unsigned char is non-zero, tracing is enabled. If tracing is enabled,
-// TRACE_EVENT_API_ADD_TRACE_EVENT can be called. It's OK if tracing is disabled
-// between the load of the tracing state and the call to
-// TRACE_EVENT_API_ADD_TRACE_EVENT, because this flag only provides an early out
-// for best performance when tracing is disabled.
-// const unsigned char*
-// TRACE_EVENT_API_GET_CATEGORY_GROUP_ENABLED(const char* category_group)
-#define TRACE_EVENT_API_GET_CATEGORY_GROUP_ENABLED \
- base::trace_event::TraceLog::GetCategoryGroupEnabled
-
-// Get the number of times traces have been recorded. This is used to implement
-// the TRACE_EVENT_IS_NEW_TRACE facility.
-// unsigned int TRACE_EVENT_API_GET_NUM_TRACES_RECORDED()
-#define TRACE_EVENT_API_GET_NUM_TRACES_RECORDED \
- base::trace_event::TraceLog::GetInstance()->GetNumTracesRecorded
-
-// Add a trace event to the platform tracing system.
-// base::trace_event::TraceEventHandle TRACE_EVENT_API_ADD_TRACE_EVENT(
-// char phase,
-// const unsigned char* category_group_enabled,
-// const char* name,
-// const char* scope,
-// unsigned long long id,
-// int num_args,
-// const char** arg_names,
-// const unsigned char* arg_types,
-// const unsigned long long* arg_values,
-// std::unique_ptr<ConvertableToTraceFormat>*
-// convertable_values,
-// unsigned int flags)
-#define TRACE_EVENT_API_ADD_TRACE_EVENT \
- base::trace_event::TraceLog::GetInstance()->AddTraceEvent
-
-// Add a trace event to the platform tracing system.
-// base::trace_event::TraceEventHandle
-// TRACE_EVENT_API_ADD_TRACE_EVENT_WITH_BIND_ID(
-// 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** arg_names,
-// const unsigned char* arg_types,
-// const unsigned long long* arg_values,
-// std::unique_ptr<ConvertableToTraceFormat>*
-// convertable_values,
-// unsigned int flags)
-#define TRACE_EVENT_API_ADD_TRACE_EVENT_WITH_BIND_ID \
- base::trace_event::TraceLog::GetInstance()->AddTraceEventWithBindId
-
-// Add a trace event to the platform tracing system overriding the pid.
-// The resulting event will have tid = pid == (process_id passed here).
-// base::trace_event::TraceEventHandle
-// TRACE_EVENT_API_ADD_TRACE_EVENT_WITH_PROCESS_ID(
-// char phase,
-// const unsigned char* category_group_enabled,
-// const char* name,
-// const char* scope,
-// unsigned long long id,
-// int process_id,
-// int num_args,
-// const char** arg_names,
-// const unsigned char* arg_types,
-// const unsigned long long* arg_values,
-// std::unique_ptr<ConvertableToTraceFormat>*
-// convertable_values,
-// unsigned int flags)
-#define TRACE_EVENT_API_ADD_TRACE_EVENT_WITH_PROCESS_ID \
- base::trace_event::TraceLog::GetInstance()->AddTraceEventWithProcessId
-
-// Add a trace event to the platform tracing system.
-// base::trace_event::TraceEventHandle
-// TRACE_EVENT_API_ADD_TRACE_EVENT_WITH_TIMESTAMP(
-// char phase,
-// const unsigned char* category_group_enabled,
-// const char* name,
-// const char* scope,
-// unsigned long long id,
-// int thread_id,
-// const TimeTicks& timestamp,
-// int num_args,
-// const char** arg_names,
-// const unsigned char* arg_types,
-// const unsigned long long* arg_values,
-// std::unique_ptr<ConvertableToTraceFormat>*
-// convertable_values,
-// unsigned int flags)
-#define TRACE_EVENT_API_ADD_TRACE_EVENT_WITH_THREAD_ID_AND_TIMESTAMP \
- base::trace_event::TraceLog::GetInstance() \
- ->AddTraceEventWithThreadIdAndTimestamp
-
-// Set the duration field of a COMPLETE trace event.
-// void TRACE_EVENT_API_UPDATE_TRACE_EVENT_DURATION(
-// const unsigned char* category_group_enabled,
-// const char* name,
-// base::trace_event::TraceEventHandle id)
-#define TRACE_EVENT_API_UPDATE_TRACE_EVENT_DURATION \
- base::trace_event::TraceLog::GetInstance()->UpdateTraceEventDuration
-
-// Set the duration field of a COMPLETE trace event.
-// void TRACE_EVENT_API_UPDATE_TRACE_EVENT_DURATION_EXPLICIT(
-// const unsigned char* category_group_enabled,
-// const char* name,
-// base::trace_event::TraceEventHandle id,
-// const TimeTicks& now,
-// const ThreadTicks* thread_now)
-#define TRACE_EVENT_API_UPDATE_TRACE_EVENT_DURATION_EXPLICIT \
- base::trace_event::TraceLog::GetInstance()->UpdateTraceEventDurationExplicit
-
-// Adds a metadata event to the trace log. The |AppendValueAsTraceFormat| method
-// on the convertable value will be called at flush time.
-// TRACE_EVENT_API_ADD_METADATA_EVENT(
-// const unsigned char* category_group_enabled,
-// const char* event_name,
-// const char* arg_name,
-// std::unique_ptr<ConvertableToTraceFormat> arg_value)
-#define TRACE_EVENT_API_ADD_METADATA_EVENT \
- trace_event_internal::AddMetadataEvent
-
-// Defines atomic operations used internally by the tracing system.
-#define TRACE_EVENT_API_ATOMIC_WORD base::subtle::AtomicWord
-#define TRACE_EVENT_API_ATOMIC_LOAD(var) base::subtle::NoBarrier_Load(&(var))
-#define TRACE_EVENT_API_ATOMIC_STORE(var, value) \
- base::subtle::NoBarrier_Store(&(var), (value))
-
-// Defines visibility for classes in trace_event.h
-#define TRACE_EVENT_API_CLASS_EXPORT BASE_EXPORT
-
-////////////////////////////////////////////////////////////////////////////////
-
-// Implementation detail: trace event macros create temporary variables
-// to keep instrumentation overhead low. These macros give each temporary
-// variable a unique name based on the line number to prevent name collisions.
-#define INTERNAL_TRACE_EVENT_UID3(a,b) \
- trace_event_unique_##a##b
-#define INTERNAL_TRACE_EVENT_UID2(a,b) \
- INTERNAL_TRACE_EVENT_UID3(a,b)
-#define INTERNAL_TRACE_EVENT_UID(name_prefix) \
- INTERNAL_TRACE_EVENT_UID2(name_prefix, __LINE__)
-
-// Implementation detail: internal macro to create static category.
-// No barriers are needed, because this code is designed to operate safely
-// even when the unsigned char* points to garbage data (which may be the case
-// on processors without cache coherency).
-#define INTERNAL_TRACE_EVENT_GET_CATEGORY_INFO_CUSTOM_VARIABLES( \
- category_group, atomic, category_group_enabled) \
- category_group_enabled = \
- reinterpret_cast<const unsigned char*>(TRACE_EVENT_API_ATOMIC_LOAD( \
- atomic)); \
- if (UNLIKELY(!category_group_enabled)) { \
- category_group_enabled = \
- TRACE_EVENT_API_GET_CATEGORY_GROUP_ENABLED(category_group); \
- TRACE_EVENT_API_ATOMIC_STORE(atomic, \
- reinterpret_cast<TRACE_EVENT_API_ATOMIC_WORD>( \
- category_group_enabled)); \
- }
-
-#define INTERNAL_TRACE_EVENT_GET_CATEGORY_INFO(category_group) \
- static TRACE_EVENT_API_ATOMIC_WORD INTERNAL_TRACE_EVENT_UID(atomic) = 0; \
- const unsigned char* INTERNAL_TRACE_EVENT_UID(category_group_enabled); \
- INTERNAL_TRACE_EVENT_GET_CATEGORY_INFO_CUSTOM_VARIABLES(category_group, \
- INTERNAL_TRACE_EVENT_UID(atomic), \
- INTERNAL_TRACE_EVENT_UID(category_group_enabled));
-
-// Implementation detail: internal macro to return unoverridden
-// base::TimeTicks::Now(). This is important because in headless VirtualTime can
-// override base:TimeTicks::Now().
-#define INTERNAL_TRACE_TIME_TICKS_NOW() \
- base::subtle::TimeTicksNowIgnoringOverride()
-
-// Implementation detail: internal macro to return unoverridden
-// base::Time::Now(). This is important because in headless VirtualTime can
-// override base:TimeTicks::Now().
-#define INTERNAL_TRACE_TIME_NOW() base::subtle::TimeNowIgnoringOverride()
-
-// Implementation detail: internal macro to create static category and add
-// event if the category is enabled.
-#define INTERNAL_TRACE_EVENT_ADD(phase, category_group, name, flags, ...) \
- do { \
- INTERNAL_TRACE_EVENT_GET_CATEGORY_INFO(category_group); \
- if (INTERNAL_TRACE_EVENT_CATEGORY_GROUP_ENABLED()) { \
- trace_event_internal::AddTraceEvent( \
- phase, INTERNAL_TRACE_EVENT_UID(category_group_enabled), name, \
- trace_event_internal::kGlobalScope, trace_event_internal::kNoId, \
- flags, trace_event_internal::kNoId, ##__VA_ARGS__); \
- } \
- } while (0)
-
-// Implementation detail: internal macro to create static category and add begin
-// event if the category is enabled. Also adds the end event when the scope
-// ends.
-#define INTERNAL_TRACE_EVENT_ADD_SCOPED(category_group, name, ...) \
- INTERNAL_TRACE_EVENT_GET_CATEGORY_INFO(category_group); \
- trace_event_internal::ScopedTracer INTERNAL_TRACE_EVENT_UID(tracer); \
- if (INTERNAL_TRACE_EVENT_CATEGORY_GROUP_ENABLED()) { \
- base::trace_event::TraceEventHandle h = \
- trace_event_internal::AddTraceEvent( \
- TRACE_EVENT_PHASE_COMPLETE, \
- INTERNAL_TRACE_EVENT_UID(category_group_enabled), name, \
- trace_event_internal::kGlobalScope, trace_event_internal::kNoId, \
- TRACE_EVENT_FLAG_NONE, trace_event_internal::kNoId, \
- ##__VA_ARGS__); \
- INTERNAL_TRACE_EVENT_UID(tracer).Initialize( \
- INTERNAL_TRACE_EVENT_UID(category_group_enabled), name, h); \
- }
-
-#define INTERNAL_TRACE_EVENT_ADD_SCOPED_WITH_FLOW(category_group, name, \
- bind_id, flow_flags, ...) \
- INTERNAL_TRACE_EVENT_GET_CATEGORY_INFO(category_group); \
- trace_event_internal::ScopedTracer INTERNAL_TRACE_EVENT_UID(tracer); \
- if (INTERNAL_TRACE_EVENT_CATEGORY_GROUP_ENABLED()) { \
- trace_event_internal::TraceID trace_event_bind_id((bind_id)); \
- unsigned int trace_event_flags = \
- flow_flags | trace_event_bind_id.id_flags(); \
- base::trace_event::TraceEventHandle h = \
- trace_event_internal::AddTraceEvent( \
- TRACE_EVENT_PHASE_COMPLETE, \
- INTERNAL_TRACE_EVENT_UID(category_group_enabled), name, \
- trace_event_internal::kGlobalScope, trace_event_internal::kNoId, \
- trace_event_flags, trace_event_bind_id.raw_id(), ##__VA_ARGS__); \
- INTERNAL_TRACE_EVENT_UID(tracer).Initialize( \
- INTERNAL_TRACE_EVENT_UID(category_group_enabled), name, h); \
- }
-
-// Implementation detail: internal macro to create static category and add
-// event if the category is enabled.
-#define INTERNAL_TRACE_EVENT_ADD_WITH_ID(phase, category_group, name, id, \
- flags, ...) \
- do { \
- INTERNAL_TRACE_EVENT_GET_CATEGORY_INFO(category_group); \
- if (INTERNAL_TRACE_EVENT_CATEGORY_GROUP_ENABLED()) { \
- trace_event_internal::TraceID trace_event_trace_id((id)); \
- unsigned int trace_event_flags = \
- flags | trace_event_trace_id.id_flags(); \
- trace_event_internal::AddTraceEvent( \
- phase, INTERNAL_TRACE_EVENT_UID(category_group_enabled), name, \
- trace_event_trace_id.scope(), trace_event_trace_id.raw_id(), \
- trace_event_flags, trace_event_internal::kNoId, ##__VA_ARGS__); \
- } \
- } while (0)
-
-// Implementation detail: internal macro to create static category and add
-// event if the category is enabled.
-#define INTERNAL_TRACE_EVENT_ADD_WITH_TIMESTAMP(phase, category_group, name, \
- timestamp, flags, ...) \
- do { \
- INTERNAL_TRACE_EVENT_GET_CATEGORY_INFO(category_group); \
- if (INTERNAL_TRACE_EVENT_CATEGORY_GROUP_ENABLED()) { \
- trace_event_internal::AddTraceEventWithThreadIdAndTimestamp( \
- phase, INTERNAL_TRACE_EVENT_UID(category_group_enabled), name, \
- trace_event_internal::kGlobalScope, trace_event_internal::kNoId, \
- TRACE_EVENT_API_CURRENT_THREAD_ID, timestamp, \
- flags | TRACE_EVENT_FLAG_EXPLICIT_TIMESTAMP, \
- trace_event_internal::kNoId, ##__VA_ARGS__); \
- } \
- } while (0)
-
-// Implementation detail: internal macro to create static category and add
-// event if the category is enabled.
-#define INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP( \
- phase, category_group, name, id, thread_id, timestamp, flags, ...) \
- do { \
- INTERNAL_TRACE_EVENT_GET_CATEGORY_INFO(category_group); \
- if (INTERNAL_TRACE_EVENT_CATEGORY_GROUP_ENABLED()) { \
- trace_event_internal::TraceID trace_event_trace_id((id)); \
- unsigned int trace_event_flags = \
- flags | trace_event_trace_id.id_flags(); \
- trace_event_internal::AddTraceEventWithThreadIdAndTimestamp( \
- phase, INTERNAL_TRACE_EVENT_UID(category_group_enabled), name, \
- trace_event_trace_id.scope(), trace_event_trace_id.raw_id(), \
- thread_id, timestamp, \
- trace_event_flags | TRACE_EVENT_FLAG_EXPLICIT_TIMESTAMP, \
- trace_event_internal::kNoId, ##__VA_ARGS__); \
- } \
- } while (0)
-
-// Implementation detail: internal macro to create static category and add
-// event if the category is enabled.
-#define INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMPS( \
- category_group, name, id, thread_id, begin_timestamp, end_timestamp, \
- thread_end_timestamp, flags, ...) \
- do { \
- INTERNAL_TRACE_EVENT_GET_CATEGORY_INFO(category_group); \
- if (INTERNAL_TRACE_EVENT_CATEGORY_GROUP_ENABLED()) { \
- trace_event_internal::TraceID trace_event_trace_id((id)); \
- unsigned int trace_event_flags = \
- flags | trace_event_trace_id.id_flags(); \
- const unsigned char* uid_category_group_enabled = \
- INTERNAL_TRACE_EVENT_UID(category_group_enabled); \
- auto handle = \
- trace_event_internal::AddTraceEventWithThreadIdAndTimestamp( \
- TRACE_EVENT_PHASE_COMPLETE, uid_category_group_enabled, name, \
- trace_event_trace_id.scope(), trace_event_trace_id.raw_id(), \
- thread_id, begin_timestamp, \
- trace_event_flags | TRACE_EVENT_FLAG_EXPLICIT_TIMESTAMP, \
- trace_event_internal::kNoId, ##__VA_ARGS__); \
- TRACE_EVENT_API_UPDATE_TRACE_EVENT_DURATION_EXPLICIT( \
- uid_category_group_enabled, name, handle, end_timestamp, \
- thread_end_timestamp); \
- } \
- } while (0)
-
-// The linked ID will not be mangled.
-#define INTERNAL_TRACE_EVENT_ADD_LINK_IDS(category_group, name, id1, id2) \
- do { \
- INTERNAL_TRACE_EVENT_GET_CATEGORY_INFO(category_group); \
- if (INTERNAL_TRACE_EVENT_CATEGORY_GROUP_ENABLED()) { \
- trace_event_internal::TraceID source_id((id1)); \
- unsigned int source_flags = source_id.id_flags(); \
- trace_event_internal::TraceID target_id((id2)); \
- trace_event_internal::AddTraceEvent( \
- TRACE_EVENT_PHASE_LINK_IDS, \
- INTERNAL_TRACE_EVENT_UID(category_group_enabled), name, \
- source_id.scope(), source_id.raw_id(), source_flags, \
- trace_event_internal::kNoId, "linked_id", \
- target_id.AsConvertableToTraceFormat()); \
- } \
- } while (0)
-
-// Implementation detail: internal macro to create static category and add
-// metadata event if the category is enabled.
-#define INTERNAL_TRACE_EVENT_METADATA_ADD(category_group, name, ...) \
- do { \
- INTERNAL_TRACE_EVENT_GET_CATEGORY_INFO(category_group); \
- if (INTERNAL_TRACE_EVENT_CATEGORY_GROUP_ENABLED()) { \
- TRACE_EVENT_API_ADD_METADATA_EVENT( \
- INTERNAL_TRACE_EVENT_UID(category_group_enabled), name, \
- ##__VA_ARGS__); \
- } \
- } while (0)
-
-// Implementation detail: internal macro to enter and leave a
-// context based on the current scope.
-#define INTERNAL_TRACE_EVENT_SCOPED_CONTEXT(category_group, name, context) \
- struct INTERNAL_TRACE_EVENT_UID(ScopedContext) { \
- public: \
- INTERNAL_TRACE_EVENT_UID(ScopedContext)(uint64_t cid) : cid_(cid) { \
- TRACE_EVENT_ENTER_CONTEXT(category_group, name, cid_); \
- } \
- ~INTERNAL_TRACE_EVENT_UID(ScopedContext)() { \
- TRACE_EVENT_LEAVE_CONTEXT(category_group, name, cid_); \
- } \
- \
- private: \
- uint64_t cid_; \
- /* Local class friendly DISALLOW_COPY_AND_ASSIGN */ \
- INTERNAL_TRACE_EVENT_UID(ScopedContext) \
- (const INTERNAL_TRACE_EVENT_UID(ScopedContext)&) {}; \
- void operator=(const INTERNAL_TRACE_EVENT_UID(ScopedContext)&) {}; \
- }; \
- INTERNAL_TRACE_EVENT_UID(ScopedContext) \
- INTERNAL_TRACE_EVENT_UID(scoped_context)(context);
-
-// TODO(http://crbug.com760702) remove file name and just pass the program
-// counter to the heap profiler macro.
-// TODO(ssid): The program counter of the current task should be added here.
-#define INTERNAL_TRACE_TASK_EXECUTION(run_function, task) \
- TRACE_EVENT1("toplevel", run_function, "src", (task).posted_from.ToString()) \
- TRACE_HEAP_PROFILER_API_SCOPED_TASK_EXECUTION INTERNAL_TRACE_EVENT_UID( \
- task_event)((task).posted_from.file_name()); \
- TRACE_HEAP_PROFILER_API_SCOPED_WITH_PROGRAM_COUNTER \
- INTERNAL_TRACE_EVENT_UID(task_pc_event)((task).posted_from.program_counter());
-
-namespace trace_event_internal {
-
-// Specify these values when the corresponding argument of AddTraceEvent is not
-// used.
-const int kZeroNumArgs = 0;
-const std::nullptr_t kGlobalScope = nullptr;
-const unsigned long long kNoId = 0;
-
-// TraceID encapsulates an ID that can either be an integer or pointer. Pointers
-// are by default mangled with the Process ID so that they are unlikely to
-// collide when the same pointer is used on different processes.
-class BASE_EXPORT TraceID {
- public:
- // Can be combined with WithScope.
- class LocalId {
- public:
- explicit LocalId(const void* raw_id)
- : raw_id_(static_cast<unsigned long long>(
- reinterpret_cast<uintptr_t>(raw_id))) {}
- explicit LocalId(unsigned long long raw_id) : raw_id_(raw_id) {}
- unsigned long long raw_id() const { return raw_id_; }
- private:
- unsigned long long raw_id_;
- };
-
- // Can be combined with WithScope.
- class GlobalId {
- public:
- explicit GlobalId(unsigned long long raw_id) : raw_id_(raw_id) {}
- unsigned long long raw_id() const { return raw_id_; }
- private:
- unsigned long long raw_id_;
- };
-
- class WithScope {
- public:
- WithScope(const char* scope, unsigned long long raw_id)
- : scope_(scope), raw_id_(raw_id) {}
- WithScope(const char* scope, LocalId local_id)
- : scope_(scope), raw_id_(local_id.raw_id()) {
- id_flags_ = TRACE_EVENT_FLAG_HAS_LOCAL_ID;
- }
- WithScope(const char* scope, GlobalId global_id)
- : scope_(scope), raw_id_(global_id.raw_id()) {
- id_flags_ = TRACE_EVENT_FLAG_HAS_GLOBAL_ID;
- }
- WithScope(const char* scope,
- unsigned long long prefix,
- unsigned long long raw_id)
- : scope_(scope), has_prefix_(true), prefix_(prefix), raw_id_(raw_id) {}
- WithScope(const char* scope, unsigned long long prefix, GlobalId global_id)
- : scope_(scope),
- has_prefix_(true),
- prefix_(prefix),
- raw_id_(global_id.raw_id()) {
- id_flags_ = TRACE_EVENT_FLAG_HAS_GLOBAL_ID;
- }
- unsigned long long raw_id() const { return raw_id_; }
- const char* scope() const { return scope_; }
- bool has_prefix() const { return has_prefix_; }
- unsigned long long prefix() const { return prefix_; }
- unsigned int id_flags() const { return id_flags_; }
-
- private:
- const char* scope_ = nullptr;
- bool has_prefix_ = false;
- unsigned long long prefix_;
- unsigned long long raw_id_;
- unsigned int id_flags_ = TRACE_EVENT_FLAG_HAS_ID;
- };
-
- // DEPRECATED: consider using LocalId or GlobalId, instead.
- class DontMangle {
- public:
- explicit DontMangle(const void* raw_id)
- : raw_id_(static_cast<unsigned long long>(
- reinterpret_cast<uintptr_t>(raw_id))) {}
- explicit DontMangle(unsigned long long raw_id) : raw_id_(raw_id) {}
- explicit DontMangle(unsigned long raw_id) : raw_id_(raw_id) {}
- explicit DontMangle(unsigned int raw_id) : raw_id_(raw_id) {}
- explicit DontMangle(unsigned short raw_id) : raw_id_(raw_id) {}
- explicit DontMangle(unsigned char raw_id) : raw_id_(raw_id) {}
- explicit DontMangle(long long raw_id)
- : raw_id_(static_cast<unsigned long long>(raw_id)) {}
- explicit DontMangle(long raw_id)
- : raw_id_(static_cast<unsigned long long>(raw_id)) {}
- explicit DontMangle(int raw_id)
- : raw_id_(static_cast<unsigned long long>(raw_id)) {}
- explicit DontMangle(short raw_id)
- : raw_id_(static_cast<unsigned long long>(raw_id)) {}
- explicit DontMangle(signed char raw_id)
- : raw_id_(static_cast<unsigned long long>(raw_id)) {}
- unsigned long long raw_id() const { return raw_id_; }
- private:
- unsigned long long raw_id_;
- };
-
- // DEPRECATED: consider using LocalId or GlobalId, instead.
- class ForceMangle {
- public:
- explicit ForceMangle(unsigned long long raw_id) : raw_id_(raw_id) {}
- explicit ForceMangle(unsigned long raw_id) : raw_id_(raw_id) {}
- explicit ForceMangle(unsigned int raw_id) : raw_id_(raw_id) {}
- explicit ForceMangle(unsigned short raw_id) : raw_id_(raw_id) {}
- explicit ForceMangle(unsigned char raw_id) : raw_id_(raw_id) {}
- explicit ForceMangle(long long raw_id)
- : raw_id_(static_cast<unsigned long long>(raw_id)) {}
- explicit ForceMangle(long raw_id)
- : raw_id_(static_cast<unsigned long long>(raw_id)) {}
- explicit ForceMangle(int raw_id)
- : raw_id_(static_cast<unsigned long long>(raw_id)) {}
- explicit ForceMangle(short raw_id)
- : raw_id_(static_cast<unsigned long long>(raw_id)) {}
- explicit ForceMangle(signed char raw_id)
- : raw_id_(static_cast<unsigned long long>(raw_id)) {}
- unsigned long long raw_id() const { return raw_id_; }
- private:
- unsigned long long raw_id_;
- };
-
- TraceID(const void* raw_id) : raw_id_(static_cast<unsigned long long>(
- reinterpret_cast<uintptr_t>(raw_id))) {
- id_flags_ = TRACE_EVENT_FLAG_HAS_ID | TRACE_EVENT_FLAG_MANGLE_ID;
- }
- TraceID(ForceMangle raw_id) : raw_id_(raw_id.raw_id()) {
- id_flags_ = TRACE_EVENT_FLAG_HAS_ID | TRACE_EVENT_FLAG_MANGLE_ID;
- }
- TraceID(DontMangle raw_id) : raw_id_(raw_id.raw_id()) {}
- TraceID(unsigned long long raw_id) : raw_id_(raw_id) {}
- TraceID(unsigned long raw_id) : raw_id_(raw_id) {}
- TraceID(unsigned int raw_id) : raw_id_(raw_id) {}
- TraceID(unsigned short raw_id) : raw_id_(raw_id) {}
- TraceID(unsigned char raw_id) : raw_id_(raw_id) {}
- TraceID(long long raw_id)
- : raw_id_(static_cast<unsigned long long>(raw_id)) {}
- TraceID(long raw_id)
- : raw_id_(static_cast<unsigned long long>(raw_id)) {}
- TraceID(int raw_id)
- : raw_id_(static_cast<unsigned long long>(raw_id)) {}
- TraceID(short raw_id)
- : raw_id_(static_cast<unsigned long long>(raw_id)) {}
- TraceID(signed char raw_id)
- : raw_id_(static_cast<unsigned long long>(raw_id)) {}
- TraceID(LocalId raw_id) : raw_id_(raw_id.raw_id()) {
- id_flags_ = TRACE_EVENT_FLAG_HAS_LOCAL_ID;
- }
- TraceID(GlobalId raw_id) : raw_id_(raw_id.raw_id()) {
- id_flags_ = TRACE_EVENT_FLAG_HAS_GLOBAL_ID;
- }
- TraceID(WithScope scoped_id)
- : scope_(scoped_id.scope()),
- has_prefix_(scoped_id.has_prefix()),
- prefix_(scoped_id.prefix()),
- raw_id_(scoped_id.raw_id()),
- id_flags_(scoped_id.id_flags()) {}
-
- unsigned long long raw_id() const { return raw_id_; }
- const char* scope() const { return scope_; }
- bool has_prefix() const { return has_prefix_; }
- unsigned long long prefix() const { return prefix_; }
- unsigned int id_flags() const { return id_flags_; }
-
- std::unique_ptr<base::trace_event::ConvertableToTraceFormat>
- AsConvertableToTraceFormat() const;
-
- private:
- const char* scope_ = nullptr;
- bool has_prefix_ = false;
- unsigned long long prefix_;
- unsigned long long raw_id_;
- unsigned int id_flags_ = TRACE_EVENT_FLAG_HAS_ID;
-};
-
-// 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;
-};
-
-// 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_;
-};
-
-// 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); \
- }
-
-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;
-}
-
-// 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();
-}
-
-static inline void SetTraceValue(const base::TimeTicks arg,
- unsigned char* type,
- unsigned long long* value) {
- *type = TRACE_VALUE_TYPE_INT;
- *value = arg.ToInternalValue();
-}
-
-static inline void SetTraceValue(const base::ThreadTicks arg,
- unsigned char* type,
- unsigned long long* value) {
- *type = TRACE_VALUE_TYPE_INT;
- *value = arg.ToInternalValue();
-}
-
-// 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_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,
- 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,
- 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, num_args, arg_names, arg_types, arg_values, convertable_values,
- flags);
-}
-
-template <class ARG1_CONVERTABLE_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,
- std::unique_ptr<ARG1_CONVERTABLE_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];
- 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, 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
-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) {
- return TRACE_EVENT_API_ADD_TRACE_EVENT_WITH_THREAD_ID_AND_TIMESTAMP(
- phase, category_group_enabled, name, scope, id, bind_id, thread_id,
- timestamp, kZeroNumArgs, NULL, NULL, NULL, NULL, flags);
-}
-
-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 int thread_id = static_cast<int>(base::PlatformThread::CurrentId());
- const base::TimeTicks now = TRACE_TIME_TICKS_NOW();
- return AddTraceEventWithThreadIdAndTimestamp(
- phase, category_group_enabled, name, scope, id, thread_id, now, flags,
- bind_id);
-}
-
-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,
- 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,
- 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, arg1_val, arg2_name, std::move(arg2_val));
-}
-
-template <class ARG1_CONVERTABLE_TYPE, class ARG2_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,
- 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::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)};
- base::trace_event::TraceLog::GetInstance()->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,
- 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]);
-
- base::trace_event::TraceLog::GetInstance()->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.
-class TRACE_EVENT_API_CLASS_EXPORT ScopedTracer {
- public:
- // Note: members of data_ intentionally left uninitialized. See Initialize.
- ScopedTracer() : p_data_(NULL) {}
-
- ~ScopedTracer() {
- if (p_data_ && *data_.category_group_enabled) {
- TRACE_EVENT_API_UPDATE_TRACE_EVENT_DURATION(
- data_.category_group_enabled, data_.name, data_.event_handle);
- }
- }
-
- void Initialize(const unsigned char* category_group_enabled,
- const char* name,
- base::trace_event::TraceEventHandle event_handle) {
- data_.category_group_enabled = category_group_enabled;
- data_.name = name;
- data_.event_handle = event_handle;
- p_data_ = &data_;
- }
-
- private:
- // This Data struct workaround is to avoid initializing all the members
- // in Data during construction of this object, since this object is always
- // constructed, even when tracing is disabled. If the members of Data were
- // members of this class instead, compiler warnings occur about potential
- // uninitialized accesses.
- struct Data {
- const unsigned char* category_group_enabled;
- const char* name;
- base::trace_event::TraceEventHandle event_handle;
- };
- Data* p_data_;
- Data data_;
-};
-
-// Used by TRACE_EVENT_BINARY_EFFICIENTx macro. Do not use directly.
-class TRACE_EVENT_API_CLASS_EXPORT ScopedTraceBinaryEfficient {
- public:
- ScopedTraceBinaryEfficient(const char* category_group, const char* name);
- ~ScopedTraceBinaryEfficient();
-
- private:
- const unsigned char* category_group_enabled_;
- const char* name_;
- base::trace_event::TraceEventHandle event_handle_;
-};
-
-// This macro generates less code then TRACE_EVENT0 but is also
-// slower to execute when tracing is off. It should generally only be
-// used with code that is seldom executed or conditionally executed
-// when debugging.
-// For now the category_group must be "gpu".
-#define TRACE_EVENT_BINARY_EFFICIENT0(category_group, name) \
- trace_event_internal::ScopedTraceBinaryEfficient \
- INTERNAL_TRACE_EVENT_UID(scoped_trace)(category_group, name);
-
-} // namespace trace_event_internal
-
-namespace base {
-namespace trace_event {
-
-template<typename IDType> class TraceScopedTrackableObject {
- public:
- TraceScopedTrackableObject(const char* category_group, const char* name,
- IDType id)
- : category_group_(category_group),
- name_(name),
- id_(id) {
- TRACE_EVENT_OBJECT_CREATED_WITH_ID(category_group_, name_, id_);
- }
-
- template <typename ArgType> void snapshot(ArgType snapshot) {
- TRACE_EVENT_OBJECT_SNAPSHOT_WITH_ID(category_group_, name_, id_, snapshot);
- }
-
- ~TraceScopedTrackableObject() {
- TRACE_EVENT_OBJECT_DELETED_WITH_ID(category_group_, name_, id_);
- }
-
- private:
- const char* category_group_;
- const char* name_;
- IDType id_;
-
- DISALLOW_COPY_AND_ASSIGN(TraceScopedTrackableObject);
-};
-
-} // namespace trace_event
-} // namespace base
-
-#endif // BASE_TRACE_EVENT_TRACE_EVENT_H_
diff --git a/base/trace_event/trace_event_android.cc b/base/trace_event/trace_event_android.cc
deleted file mode 100644
index 30d9c74..0000000
--- a/base/trace_event/trace_event_android.cc
+++ /dev/null
@@ -1,216 +0,0 @@
-// Copyright (c) 2012 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_event_impl.h"
-
-#include <fcntl.h>
-#include <stddef.h>
-#include <stdint.h>
-
-#include "base/format_macros.h"
-#include "base/logging.h"
-#include "base/posix/eintr_wrapper.h"
-#include "base/strings/stringprintf.h"
-#include "base/synchronization/waitable_event.h"
-#include "base/threading/thread.h"
-#include "base/trace_event/trace_event.h"
-
-namespace base {
-namespace trace_event {
-
-namespace {
-
-int g_atrace_fd = -1;
-const char kATraceMarkerFile[] = "/sys/kernel/debug/tracing/trace_marker";
-
-void WriteToATrace(int fd, const char* buffer, size_t size) {
- size_t total_written = 0;
- while (total_written < size) {
- ssize_t written = HANDLE_EINTR(write(
- fd, buffer + total_written, size - total_written));
- if (written <= 0)
- break;
- total_written += written;
- }
- if (total_written < size) {
- PLOG(WARNING) << "Failed to write buffer '" << std::string(buffer, size)
- << "' to " << kATraceMarkerFile;
- }
-}
-
-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 += '|';
-
- 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();
- 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, "\\\"", "'");
- ReplaceSubstringsAfterOffset(&out, value_start, "\"", "");
- // Replace chars used for separators with similar chars in the value.
- std::replace(out.begin() + value_start, out.end(), ';', ',');
- std::replace(out.begin() + value_start, out.end(), '|', '!');
- }
-
- out += '|';
- out += category_group;
- WriteToATrace(g_atrace_fd, out.c_str(), out.size());
-}
-
-void NoOpOutputCallback(WaitableEvent* complete_event,
- const scoped_refptr<RefCountedString>&,
- bool has_more_events) {
- if (!has_more_events)
- complete_event->Signal();
-}
-
-void EndChromeTracing(TraceLog* trace_log,
- WaitableEvent* complete_event) {
- trace_log->SetDisabled();
- // Delete the buffered trace events as they have been sent to atrace.
- trace_log->Flush(Bind(&NoOpOutputCallback, complete_event));
-}
-
-} // namespace
-
-// These functions support Android systrace.py when 'webview' category is
-// traced. With the new adb_profile_chrome, we may have two phases:
-// - before WebView is ready for combined tracing, we can use adb_profile_chrome
-// to trace android categories other than 'webview' and chromium categories.
-// In this way we can avoid the conflict between StartATrace/StopATrace and
-// the intents.
-// - TODO(wangxianzhu): after WebView is ready for combined tracing, remove
-// StartATrace, StopATrace and SendToATrace, and perhaps send Java traces
-// directly to atrace in trace_event_binding.cc.
-
-void TraceLog::StartATrace() {
- if (g_atrace_fd != -1)
- return;
-
- g_atrace_fd = HANDLE_EINTR(open(kATraceMarkerFile, O_WRONLY));
- if (g_atrace_fd == -1) {
- PLOG(WARNING) << "Couldn't open " << kATraceMarkerFile;
- return;
- }
- TraceConfig trace_config;
- trace_config.SetTraceRecordMode(RECORD_CONTINUOUSLY);
- SetEnabled(trace_config, TraceLog::RECORDING_MODE);
-}
-
-void TraceLog::StopATrace() {
- if (g_atrace_fd == -1)
- return;
-
- close(g_atrace_fd);
- g_atrace_fd = -1;
-
- // TraceLog::Flush() requires the current thread to have a message loop, but
- // this thread called from Java may not have one, so flush in another thread.
- Thread end_chrome_tracing_thread("end_chrome_tracing");
- WaitableEvent complete_event(WaitableEvent::ResetPolicy::AUTOMATIC,
- WaitableEvent::InitialState::NOT_SIGNALED);
- end_chrome_tracing_thread.Start();
- end_chrome_tracing_thread.task_runner()->PostTask(
- FROM_HERE, base::Bind(&EndChromeTracing, Unretained(this),
- Unretained(&complete_event)));
- complete_event.Wait();
-}
-
-void TraceEvent::SendToATrace() {
- if (g_atrace_fd == -1)
- return;
-
- const char* category_group =
- TraceLog::GetCategoryGroupName(category_group_enabled_);
-
- switch (phase_) {
- case TRACE_EVENT_PHASE_BEGIN:
- 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_,
- 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_,
- 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_,
- arg_names_, arg_types_, arg_values_, convertable_values_,
- flags_);
- WriteToATrace(g_atrace_fd, "E", 1);
- break;
-
- case TRACE_EVENT_PHASE_COUNTER:
- 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_values_[i].as_int), category_group);
- WriteToATrace(g_atrace_fd, out.c_str(), out.size());
- }
- break;
-
- default:
- // Do nothing.
- break;
- }
-}
-
-void TraceLog::AddClockSyncMetadataEvent() {
- int atrace_fd = HANDLE_EINTR(open(kATraceMarkerFile, O_WRONLY | O_APPEND));
- if (atrace_fd == -1) {
- PLOG(WARNING) << "Couldn't open " << kATraceMarkerFile;
- return;
- }
-
- // Android's kernel trace system has a trace_marker feature: this is a file on
- // debugfs that takes the written data and pushes it onto the trace
- // buffer. So, to establish clock sync, we write our monotonic clock into that
- // trace buffer.
- double now_in_seconds = (TRACE_TIME_TICKS_NOW() - TimeTicks()).InSecondsF();
- std::string marker = StringPrintf(
- "trace_event_clock_sync: parent_ts=%f\n", now_in_seconds);
- WriteToATrace(atrace_fd, marker.c_str(), marker.size());
- close(atrace_fd);
-}
-
-} // namespace trace_event
-} // namespace base
diff --git a/base/trace_event/trace_event_argument.cc b/base/trace_event/trace_event_argument.cc
deleted file mode 100644
index e614b27..0000000
--- a/base/trace_event/trace_event_argument.cc
+++ /dev/null
@@ -1,576 +0,0 @@
-// Copyright (c) 2014 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_event_argument.h"
-
-#include <stdint.h>
-
-#include <utility>
-
-#include "base/bits.h"
-#include "base/containers/circular_deque.h"
-#include "base/json/string_escape.h"
-#include "base/memory/ptr_util.h"
-#include "base/trace_event/trace_event.h"
-#include "base/trace_event/trace_event_impl.h"
-#include "base/trace_event/trace_event_memory_overhead.h"
-#include "base/values.h"
-
-namespace base {
-namespace trace_event {
-
-namespace {
-const char kTypeStartDict = '{';
-const char kTypeEndDict = '}';
-const char kTypeStartArray = '[';
-const char kTypeEndArray = ']';
-const char kTypeBool = 'b';
-const char kTypeInt = 'i';
-const char kTypeDouble = 'd';
-const char kTypeString = 's';
-const char kTypeCStr = '*'; // only used for key names
-
-#ifndef NDEBUG
-const bool kStackTypeDict = false;
-const bool kStackTypeArray = true;
-#define DCHECK_CURRENT_CONTAINER_IS(x) DCHECK_EQ(x, nesting_stack_.back())
-#define DCHECK_CONTAINER_STACK_DEPTH_EQ(x) DCHECK_EQ(x, nesting_stack_.size())
-#define DEBUG_PUSH_CONTAINER(x) nesting_stack_.push_back(x)
-#define DEBUG_POP_CONTAINER() nesting_stack_.pop_back()
-#else
-#define DCHECK_CURRENT_CONTAINER_IS(x) do {} while (0)
-#define DCHECK_CONTAINER_STACK_DEPTH_EQ(x) do {} while (0)
-#define DEBUG_PUSH_CONTAINER(x) do {} while (0)
-#define DEBUG_POP_CONTAINER() do {} while (0)
-#endif
-
-inline void WriteKeyNameAsRawPtr(Pickle& pickle, const char* ptr) {
- pickle.WriteBytes(&kTypeCStr, 1);
- pickle.WriteUInt64(static_cast<uint64_t>(reinterpret_cast<uintptr_t>(ptr)));
-}
-
-inline void WriteKeyNameWithCopy(Pickle& pickle, base::StringPiece str) {
- pickle.WriteBytes(&kTypeString, 1);
- pickle.WriteString(str);
-}
-
-std::string ReadKeyName(PickleIterator& pickle_iterator) {
- const char* type = nullptr;
- bool res = pickle_iterator.ReadBytes(&type, 1);
- std::string key_name;
- if (res && *type == kTypeCStr) {
- uint64_t ptr_value = 0;
- res = pickle_iterator.ReadUInt64(&ptr_value);
- key_name = reinterpret_cast<const char*>(static_cast<uintptr_t>(ptr_value));
- } else if (res && *type == kTypeString) {
- res = pickle_iterator.ReadString(&key_name);
- }
- DCHECK(res);
- return key_name;
-}
-} // namespace
-
-TracedValue::TracedValue() : TracedValue(0) {
-}
-
-TracedValue::TracedValue(size_t capacity) {
- DEBUG_PUSH_CONTAINER(kStackTypeDict);
- if (capacity)
- pickle_.Reserve(capacity);
-}
-
-TracedValue::~TracedValue() {
- DCHECK_CURRENT_CONTAINER_IS(kStackTypeDict);
- DEBUG_POP_CONTAINER();
- DCHECK_CONTAINER_STACK_DEPTH_EQ(0u);
-}
-
-void TracedValue::SetInteger(const char* name, int value) {
- DCHECK_CURRENT_CONTAINER_IS(kStackTypeDict);
- pickle_.WriteBytes(&kTypeInt, 1);
- pickle_.WriteInt(value);
- WriteKeyNameAsRawPtr(pickle_, name);
-}
-
-void TracedValue::SetIntegerWithCopiedName(base::StringPiece name, int value) {
- DCHECK_CURRENT_CONTAINER_IS(kStackTypeDict);
- pickle_.WriteBytes(&kTypeInt, 1);
- pickle_.WriteInt(value);
- WriteKeyNameWithCopy(pickle_, name);
-}
-
-void TracedValue::SetDouble(const char* name, double value) {
- DCHECK_CURRENT_CONTAINER_IS(kStackTypeDict);
- pickle_.WriteBytes(&kTypeDouble, 1);
- pickle_.WriteDouble(value);
- WriteKeyNameAsRawPtr(pickle_, name);
-}
-
-void TracedValue::SetDoubleWithCopiedName(base::StringPiece name,
- double value) {
- DCHECK_CURRENT_CONTAINER_IS(kStackTypeDict);
- pickle_.WriteBytes(&kTypeDouble, 1);
- pickle_.WriteDouble(value);
- WriteKeyNameWithCopy(pickle_, name);
-}
-
-void TracedValue::SetBoolean(const char* name, bool value) {
- DCHECK_CURRENT_CONTAINER_IS(kStackTypeDict);
- pickle_.WriteBytes(&kTypeBool, 1);
- pickle_.WriteBool(value);
- WriteKeyNameAsRawPtr(pickle_, name);
-}
-
-void TracedValue::SetBooleanWithCopiedName(base::StringPiece name,
- bool value) {
- DCHECK_CURRENT_CONTAINER_IS(kStackTypeDict);
- pickle_.WriteBytes(&kTypeBool, 1);
- pickle_.WriteBool(value);
- WriteKeyNameWithCopy(pickle_, name);
-}
-
-void TracedValue::SetString(const char* name, base::StringPiece value) {
- DCHECK_CURRENT_CONTAINER_IS(kStackTypeDict);
- pickle_.WriteBytes(&kTypeString, 1);
- pickle_.WriteString(value);
- WriteKeyNameAsRawPtr(pickle_, name);
-}
-
-void TracedValue::SetStringWithCopiedName(base::StringPiece name,
- base::StringPiece value) {
- DCHECK_CURRENT_CONTAINER_IS(kStackTypeDict);
- pickle_.WriteBytes(&kTypeString, 1);
- pickle_.WriteString(value);
- WriteKeyNameWithCopy(pickle_, name);
-}
-
-void TracedValue::SetValue(const char* name, const TracedValue& value) {
- DCHECK_CURRENT_CONTAINER_IS(kStackTypeDict);
- BeginDictionary(name);
- pickle_.WriteBytes(value.pickle_.payload(),
- static_cast<int>(value.pickle_.payload_size()));
- EndDictionary();
-}
-
-void TracedValue::SetValueWithCopiedName(base::StringPiece name,
- const TracedValue& value) {
- DCHECK_CURRENT_CONTAINER_IS(kStackTypeDict);
- BeginDictionaryWithCopiedName(name);
- pickle_.WriteBytes(value.pickle_.payload(),
- static_cast<int>(value.pickle_.payload_size()));
- EndDictionary();
-}
-
-void TracedValue::BeginDictionary(const char* name) {
- DCHECK_CURRENT_CONTAINER_IS(kStackTypeDict);
- DEBUG_PUSH_CONTAINER(kStackTypeDict);
- pickle_.WriteBytes(&kTypeStartDict, 1);
- WriteKeyNameAsRawPtr(pickle_, name);
-}
-
-void TracedValue::BeginDictionaryWithCopiedName(base::StringPiece name) {
- DCHECK_CURRENT_CONTAINER_IS(kStackTypeDict);
- DEBUG_PUSH_CONTAINER(kStackTypeDict);
- pickle_.WriteBytes(&kTypeStartDict, 1);
- WriteKeyNameWithCopy(pickle_, name);
-}
-
-void TracedValue::BeginArray(const char* name) {
- DCHECK_CURRENT_CONTAINER_IS(kStackTypeDict);
- DEBUG_PUSH_CONTAINER(kStackTypeArray);
- pickle_.WriteBytes(&kTypeStartArray, 1);
- WriteKeyNameAsRawPtr(pickle_, name);
-}
-
-void TracedValue::BeginArrayWithCopiedName(base::StringPiece name) {
- DCHECK_CURRENT_CONTAINER_IS(kStackTypeDict);
- DEBUG_PUSH_CONTAINER(kStackTypeArray);
- pickle_.WriteBytes(&kTypeStartArray, 1);
- WriteKeyNameWithCopy(pickle_, name);
-}
-
-void TracedValue::EndDictionary() {
- DCHECK_CURRENT_CONTAINER_IS(kStackTypeDict);
- DEBUG_POP_CONTAINER();
- pickle_.WriteBytes(&kTypeEndDict, 1);
-}
-
-void TracedValue::AppendInteger(int value) {
- DCHECK_CURRENT_CONTAINER_IS(kStackTypeArray);
- pickle_.WriteBytes(&kTypeInt, 1);
- pickle_.WriteInt(value);
-}
-
-void TracedValue::AppendDouble(double value) {
- DCHECK_CURRENT_CONTAINER_IS(kStackTypeArray);
- pickle_.WriteBytes(&kTypeDouble, 1);
- pickle_.WriteDouble(value);
-}
-
-void TracedValue::AppendBoolean(bool value) {
- DCHECK_CURRENT_CONTAINER_IS(kStackTypeArray);
- pickle_.WriteBytes(&kTypeBool, 1);
- pickle_.WriteBool(value);
-}
-
-void TracedValue::AppendString(base::StringPiece value) {
- DCHECK_CURRENT_CONTAINER_IS(kStackTypeArray);
- pickle_.WriteBytes(&kTypeString, 1);
- pickle_.WriteString(value);
-}
-
-void TracedValue::BeginArray() {
- DCHECK_CURRENT_CONTAINER_IS(kStackTypeArray);
- DEBUG_PUSH_CONTAINER(kStackTypeArray);
- pickle_.WriteBytes(&kTypeStartArray, 1);
-}
-
-void TracedValue::BeginDictionary() {
- DCHECK_CURRENT_CONTAINER_IS(kStackTypeArray);
- DEBUG_PUSH_CONTAINER(kStackTypeDict);
- pickle_.WriteBytes(&kTypeStartDict, 1);
-}
-
-void TracedValue::EndArray() {
- DCHECK_CURRENT_CONTAINER_IS(kStackTypeArray);
- DEBUG_POP_CONTAINER();
- pickle_.WriteBytes(&kTypeEndArray, 1);
-}
-
-void TracedValue::SetValue(const char* name,
- std::unique_ptr<base::Value> value) {
- SetBaseValueWithCopiedName(name, *value);
-}
-
-void TracedValue::SetBaseValueWithCopiedName(base::StringPiece name,
- const base::Value& value) {
- DCHECK_CURRENT_CONTAINER_IS(kStackTypeDict);
- switch (value.type()) {
- case base::Value::Type::NONE:
- case base::Value::Type::BINARY:
- NOTREACHED();
- break;
-
- case base::Value::Type::BOOLEAN: {
- bool bool_value;
- value.GetAsBoolean(&bool_value);
- SetBooleanWithCopiedName(name, bool_value);
- } break;
-
- case base::Value::Type::INTEGER: {
- int int_value;
- value.GetAsInteger(&int_value);
- SetIntegerWithCopiedName(name, int_value);
- } break;
-
- case base::Value::Type::DOUBLE: {
- double double_value;
- value.GetAsDouble(&double_value);
- SetDoubleWithCopiedName(name, double_value);
- } break;
-
- case base::Value::Type::STRING: {
- const Value* string_value;
- value.GetAsString(&string_value);
- SetStringWithCopiedName(name, string_value->GetString());
- } break;
-
- case base::Value::Type::DICTIONARY: {
- const DictionaryValue* dict_value;
- value.GetAsDictionary(&dict_value);
- BeginDictionaryWithCopiedName(name);
- for (DictionaryValue::Iterator it(*dict_value); !it.IsAtEnd();
- it.Advance()) {
- SetBaseValueWithCopiedName(it.key(), it.value());
- }
- EndDictionary();
- } break;
-
- case base::Value::Type::LIST: {
- const ListValue* list_value;
- value.GetAsList(&list_value);
- BeginArrayWithCopiedName(name);
- for (const auto& base_value : *list_value)
- AppendBaseValue(base_value);
- EndArray();
- } break;
- }
-}
-
-void TracedValue::AppendBaseValue(const base::Value& value) {
- DCHECK_CURRENT_CONTAINER_IS(kStackTypeArray);
- switch (value.type()) {
- case base::Value::Type::NONE:
- case base::Value::Type::BINARY:
- NOTREACHED();
- break;
-
- case base::Value::Type::BOOLEAN: {
- bool bool_value;
- value.GetAsBoolean(&bool_value);
- AppendBoolean(bool_value);
- } break;
-
- case base::Value::Type::INTEGER: {
- int int_value;
- value.GetAsInteger(&int_value);
- AppendInteger(int_value);
- } break;
-
- case base::Value::Type::DOUBLE: {
- double double_value;
- value.GetAsDouble(&double_value);
- AppendDouble(double_value);
- } break;
-
- case base::Value::Type::STRING: {
- const Value* string_value;
- value.GetAsString(&string_value);
- AppendString(string_value->GetString());
- } break;
-
- case base::Value::Type::DICTIONARY: {
- const DictionaryValue* dict_value;
- value.GetAsDictionary(&dict_value);
- BeginDictionary();
- for (DictionaryValue::Iterator it(*dict_value); !it.IsAtEnd();
- it.Advance()) {
- SetBaseValueWithCopiedName(it.key(), it.value());
- }
- EndDictionary();
- } break;
-
- case base::Value::Type::LIST: {
- const ListValue* list_value;
- value.GetAsList(&list_value);
- BeginArray();
- for (const auto& base_value : *list_value)
- AppendBaseValue(base_value);
- EndArray();
- } break;
- }
-}
-
-std::unique_ptr<base::Value> TracedValue::ToBaseValue() const {
- base::Value root(base::Value::Type::DICTIONARY);
- Value* cur_dict = &root;
- Value* cur_list = nullptr;
- std::vector<Value*> stack;
- PickleIterator it(pickle_);
- const char* type;
-
- while (it.ReadBytes(&type, 1)) {
- DCHECK((cur_dict && !cur_list) || (cur_list && !cur_dict));
- switch (*type) {
- case kTypeStartDict: {
- base::Value new_dict(base::Value::Type::DICTIONARY);
- if (cur_dict) {
- stack.push_back(cur_dict);
- cur_dict = cur_dict->SetKey(ReadKeyName(it), std::move(new_dict));
- } else {
- cur_list->GetList().push_back(std::move(new_dict));
- // |new_dict| is invalidated at this point, so |cur_dict| needs to be
- // reset.
- cur_dict = &cur_list->GetList().back();
- stack.push_back(cur_list);
- cur_list = nullptr;
- }
- } break;
-
- case kTypeEndArray:
- case kTypeEndDict: {
- if (stack.back()->is_dict()) {
- cur_dict = stack.back();
- cur_list = nullptr;
- } else if (stack.back()->is_list()) {
- cur_list = stack.back();
- cur_dict = nullptr;
- }
- stack.pop_back();
- } break;
-
- case kTypeStartArray: {
- base::Value new_list(base::Value::Type::LIST);
- if (cur_dict) {
- stack.push_back(cur_dict);
- cur_list = cur_dict->SetKey(ReadKeyName(it), std::move(new_list));
- cur_dict = nullptr;
- } else {
- cur_list->GetList().push_back(std::move(new_list));
- stack.push_back(cur_list);
- // |cur_list| is invalidated at this point by the Append, so it needs
- // to be reset.
- cur_list = &cur_list->GetList().back();
- }
- } break;
-
- case kTypeBool: {
- bool value;
- CHECK(it.ReadBool(&value));
- base::Value new_bool(value);
- if (cur_dict) {
- cur_dict->SetKey(ReadKeyName(it), std::move(new_bool));
- } else {
- cur_list->GetList().push_back(std::move(new_bool));
- }
- } break;
-
- case kTypeInt: {
- int value;
- CHECK(it.ReadInt(&value));
- base::Value new_int(value);
- if (cur_dict) {
- cur_dict->SetKey(ReadKeyName(it), std::move(new_int));
- } else {
- cur_list->GetList().push_back(std::move(new_int));
- }
- } break;
-
- case kTypeDouble: {
- double value;
- CHECK(it.ReadDouble(&value));
- base::Value new_double(value);
- if (cur_dict) {
- cur_dict->SetKey(ReadKeyName(it), std::move(new_double));
- } else {
- cur_list->GetList().push_back(std::move(new_double));
- }
- } break;
-
- case kTypeString: {
- std::string value;
- CHECK(it.ReadString(&value));
- base::Value new_str(std::move(value));
- if (cur_dict) {
- cur_dict->SetKey(ReadKeyName(it), std::move(new_str));
- } else {
- cur_list->GetList().push_back(std::move(new_str));
- }
- } break;
-
- default:
- NOTREACHED();
- }
- }
- DCHECK(stack.empty());
- return base::Value::ToUniquePtrValue(std::move(root));
-}
-
-void TracedValue::AppendAsTraceFormat(std::string* out) const {
- DCHECK_CURRENT_CONTAINER_IS(kStackTypeDict);
- DCHECK_CONTAINER_STACK_DEPTH_EQ(1u);
-
- struct State {
- enum Type { kTypeDict, kTypeArray };
- Type type;
- bool needs_comma;
- };
-
- auto maybe_append_key_name = [](State current_state, PickleIterator* it,
- std::string* out) {
- if (current_state.type == State::kTypeDict) {
- EscapeJSONString(ReadKeyName(*it), true, out);
- out->append(":");
- }
- };
-
- base::circular_deque<State> state_stack;
-
- out->append("{");
- state_stack.push_back({State::kTypeDict});
-
- PickleIterator it(pickle_);
- for (const char* type; it.ReadBytes(&type, 1);) {
- switch (*type) {
- case kTypeEndDict:
- out->append("}");
- state_stack.pop_back();
- continue;
-
- case kTypeEndArray:
- out->append("]");
- state_stack.pop_back();
- continue;
- }
-
- // Use an index so it will stay valid across resizes.
- size_t current_state_index = state_stack.size() - 1;
- if (state_stack[current_state_index].needs_comma)
- out->append(",");
-
- switch (*type) {
- case kTypeStartDict: {
- maybe_append_key_name(state_stack[current_state_index], &it, out);
- out->append("{");
- state_stack.push_back({State::kTypeDict});
- break;
- }
-
- case kTypeStartArray: {
- maybe_append_key_name(state_stack[current_state_index], &it, out);
- out->append("[");
- state_stack.push_back({State::kTypeArray});
- break;
- }
-
- case kTypeBool: {
- TraceEvent::TraceValue json_value;
- CHECK(it.ReadBool(&json_value.as_bool));
- maybe_append_key_name(state_stack[current_state_index], &it, out);
- TraceEvent::AppendValueAsJSON(TRACE_VALUE_TYPE_BOOL, json_value, out);
- break;
- }
-
- case kTypeInt: {
- int value;
- CHECK(it.ReadInt(&value));
- maybe_append_key_name(state_stack[current_state_index], &it, out);
- TraceEvent::TraceValue json_value;
- json_value.as_int = value;
- TraceEvent::AppendValueAsJSON(TRACE_VALUE_TYPE_INT, json_value, out);
- break;
- }
-
- case kTypeDouble: {
- TraceEvent::TraceValue json_value;
- CHECK(it.ReadDouble(&json_value.as_double));
- maybe_append_key_name(state_stack[current_state_index], &it, out);
- TraceEvent::AppendValueAsJSON(TRACE_VALUE_TYPE_DOUBLE, json_value, out);
- break;
- }
-
- case kTypeString: {
- std::string value;
- CHECK(it.ReadString(&value));
- maybe_append_key_name(state_stack[current_state_index], &it, out);
- TraceEvent::TraceValue json_value;
- json_value.as_string = value.c_str();
- TraceEvent::AppendValueAsJSON(TRACE_VALUE_TYPE_STRING, json_value, out);
- break;
- }
-
- default:
- NOTREACHED();
- }
-
- state_stack[current_state_index].needs_comma = true;
- }
-
- out->append("}");
- state_stack.pop_back();
-
- DCHECK(state_stack.empty());
-}
-
-void TracedValue::EstimateTraceMemoryOverhead(
- TraceEventMemoryOverhead* overhead) {
- overhead->Add(TraceEventMemoryOverhead::kTracedValue,
- /* allocated size */
- pickle_.GetTotalAllocatedSize(),
- /* resident size */
- pickle_.size());
-}
-
-} // namespace trace_event
-} // namespace base
diff --git a/base/trace_event/trace_event_argument.h b/base/trace_event/trace_event_argument.h
deleted file mode 100644
index 81d8c01..0000000
--- a/base/trace_event/trace_event_argument.h
+++ /dev/null
@@ -1,92 +0,0 @@
-// Copyright 2014 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_EVENT_ARGUMENT_H_
-#define BASE_TRACE_EVENT_TRACE_EVENT_ARGUMENT_H_
-
-#include <stddef.h>
-
-#include <memory>
-#include <string>
-#include <vector>
-
-#include "base/macros.h"
-#include "base/pickle.h"
-#include "base/strings/string_piece.h"
-#include "base/trace_event/trace_event_impl.h"
-
-namespace base {
-
-class Value;
-
-namespace trace_event {
-
-class BASE_EXPORT TracedValue : public ConvertableToTraceFormat {
- public:
- TracedValue();
- explicit TracedValue(size_t capacity);
- ~TracedValue() override;
-
- void EndDictionary();
- void EndArray();
-
- // These methods assume that |name| is a long lived "quoted" string.
- void SetInteger(const char* name, int value);
- void SetDouble(const char* name, double value);
- void SetBoolean(const char* name, bool value);
- void SetString(const char* name, base::StringPiece value);
- void SetValue(const char* name, const TracedValue& value);
- void BeginDictionary(const char* name);
- void BeginArray(const char* name);
-
- // These, instead, can be safely passed a temporary string.
- void SetIntegerWithCopiedName(base::StringPiece name, int value);
- void SetDoubleWithCopiedName(base::StringPiece name, double value);
- void SetBooleanWithCopiedName(base::StringPiece name, bool value);
- void SetStringWithCopiedName(base::StringPiece name,
- base::StringPiece value);
- void SetValueWithCopiedName(base::StringPiece name,
- const TracedValue& value);
- void BeginDictionaryWithCopiedName(base::StringPiece name);
- void BeginArrayWithCopiedName(base::StringPiece name);
-
- void AppendInteger(int);
- void AppendDouble(double);
- void AppendBoolean(bool);
- void AppendString(base::StringPiece);
- void BeginArray();
- void BeginDictionary();
-
- // ConvertableToTraceFormat implementation.
- void AppendAsTraceFormat(std::string* out) const override;
-
- void EstimateTraceMemoryOverhead(TraceEventMemoryOverhead* overhead) override;
-
- // DEPRECATED: do not use, here only for legacy reasons. These methods causes
- // a copy-and-translation of the base::Value into the equivalent TracedValue.
- // TODO(primiano): migrate the (three) existing clients to the cheaper
- // SetValue(TracedValue) API. crbug.com/495628.
- void SetValue(const char* name, std::unique_ptr<base::Value> value);
- void SetBaseValueWithCopiedName(base::StringPiece name,
- const base::Value& value);
- void AppendBaseValue(const base::Value& value);
-
- // Public for tests only.
- std::unique_ptr<base::Value> ToBaseValue() const;
-
- private:
- Pickle pickle_;
-
-#ifndef NDEBUG
- // In debug builds checks the pairings of {Start,End}{Dictionary,Array}
- std::vector<bool> nesting_stack_;
-#endif
-
- DISALLOW_COPY_AND_ASSIGN(TracedValue);
-};
-
-} // namespace trace_event
-} // namespace base
-
-#endif // BASE_TRACE_EVENT_TRACE_EVENT_ARGUMENT_H_
diff --git a/base/trace_event/trace_event_filter.cc b/base/trace_event/trace_event_filter.cc
deleted file mode 100644
index d0b116e..0000000
--- a/base/trace_event/trace_event_filter.cc
+++ /dev/null
@@ -1,17 +0,0 @@
-// Copyright 2016 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_event_filter.h"
-
-namespace base {
-namespace trace_event {
-
-TraceEventFilter::TraceEventFilter() = default;
-TraceEventFilter::~TraceEventFilter() = default;
-
-void TraceEventFilter::EndEvent(const char* category_name,
- const char* event_name) const {}
-
-} // namespace trace_event
-} // namespace base
diff --git a/base/trace_event/trace_event_filter.h b/base/trace_event/trace_event_filter.h
deleted file mode 100644
index 48c6711..0000000
--- a/base/trace_event/trace_event_filter.h
+++ /dev/null
@@ -1,51 +0,0 @@
-// Copyright 2016 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_EVENT_FILTER_H_
-#define BASE_TRACE_EVENT_TRACE_EVENT_FILTER_H_
-
-#include <memory>
-
-#include "base/base_export.h"
-#include "base/macros.h"
-
-namespace base {
-namespace trace_event {
-
-class TraceEvent;
-
-// TraceEventFilter is like iptables for TRACE_EVENT macros. Filters can be
-// enabled on a per-category basis, hence a single filter instance can serve
-// more than a TraceCategory. There are two use cases for filters:
-// 1. Snooping TRACE_EVENT macros without adding them to the TraceLog. This is
-// possible by setting the ENABLED_FOR_FILTERING flag on a category w/o
-// ENABLED_FOR_RECORDING (see TraceConfig for user-facing configuration).
-// 2. Filtering TRACE_EVENT macros before they are added to the TraceLog. This
-// requires both the ENABLED_FOR_FILTERING and ENABLED_FOR_RECORDING flags
-// on the category.
-// More importantly, filters must be thread-safe. The FilterTraceEvent and
-// EndEvent methods can be called concurrently as trace macros are hit on
-// different threads.
-class BASE_EXPORT TraceEventFilter {
- public:
- TraceEventFilter();
- virtual ~TraceEventFilter();
-
- // If the category is ENABLED_FOR_RECORDING, the event is added iff all the
- // filters enabled for the category return true. false causes the event to be
- // discarded.
- virtual bool FilterTraceEvent(const TraceEvent& trace_event) const = 0;
-
- // Notifies the end of a duration event when the RAII macro goes out of scope.
- virtual void EndEvent(const char* category_name,
- const char* event_name) const;
-
- private:
- DISALLOW_COPY_AND_ASSIGN(TraceEventFilter);
-};
-
-} // namespace trace_event
-} // namespace base
-
-#endif // BASE_TRACE_EVENT_TRACE_EVENT_FILTER_H_
diff --git a/base/trace_event/trace_event_filter_test_utils.cc b/base/trace_event/trace_event_filter_test_utils.cc
deleted file mode 100644
index 85b4cfa..0000000
--- a/base/trace_event/trace_event_filter_test_utils.cc
+++ /dev/null
@@ -1,61 +0,0 @@
-// Copyright 2016 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_event_filter_test_utils.h"
-
-#include "base/logging.h"
-
-namespace base {
-namespace trace_event {
-
-namespace {
-TestEventFilter::HitsCounter* g_hits_counter;
-} // namespace;
-
-// static
-const char TestEventFilter::kName[] = "testing_predicate";
-bool TestEventFilter::filter_return_value_;
-
-// static
-std::unique_ptr<TraceEventFilter> TestEventFilter::Factory(
- const std::string& predicate_name) {
- std::unique_ptr<TraceEventFilter> res;
- if (predicate_name == kName)
- res.reset(new TestEventFilter());
- return res;
-}
-
-TestEventFilter::TestEventFilter() = default;
-TestEventFilter::~TestEventFilter() = default;
-
-bool TestEventFilter::FilterTraceEvent(const TraceEvent& trace_event) const {
- if (g_hits_counter)
- g_hits_counter->filter_trace_event_hit_count++;
- return filter_return_value_;
-}
-
-void TestEventFilter::EndEvent(const char* category_name,
- const char* name) const {
- if (g_hits_counter)
- g_hits_counter->end_event_hit_count++;
-}
-
-TestEventFilter::HitsCounter::HitsCounter() {
- Reset();
- DCHECK(!g_hits_counter);
- g_hits_counter = this;
-}
-
-TestEventFilter::HitsCounter::~HitsCounter() {
- DCHECK(g_hits_counter);
- g_hits_counter = nullptr;
-}
-
-void TestEventFilter::HitsCounter::Reset() {
- filter_trace_event_hit_count = 0;
- end_event_hit_count = 0;
-}
-
-} // namespace trace_event
-} // namespace base
diff --git a/base/trace_event/trace_event_filter_test_utils.h b/base/trace_event/trace_event_filter_test_utils.h
deleted file mode 100644
index 419068b..0000000
--- a/base/trace_event/trace_event_filter_test_utils.h
+++ /dev/null
@@ -1,53 +0,0 @@
-// Copyright 2016 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_EVENT_FILTER_TEST_UTILS_H_
-#define BASE_TRACE_EVENT_TRACE_EVENT_FILTER_TEST_UTILS_H_
-
-#include <memory>
-#include <string>
-
-#include "base/macros.h"
-#include "base/trace_event/trace_event_filter.h"
-
-namespace base {
-namespace trace_event {
-
-class TestEventFilter : public TraceEventFilter {
- public:
- struct HitsCounter {
- HitsCounter();
- ~HitsCounter();
- void Reset();
- size_t filter_trace_event_hit_count;
- size_t end_event_hit_count;
- };
-
- static const char kName[];
-
- // Factory method for TraceLog::SetFilterFactoryForTesting().
- static std::unique_ptr<TraceEventFilter> Factory(
- const std::string& predicate_name);
-
- TestEventFilter();
- ~TestEventFilter() override;
-
- // TraceEventFilter implementation.
- bool FilterTraceEvent(const TraceEvent& trace_event) const override;
- void EndEvent(const char* category_name, const char* name) const override;
-
- static void set_filter_return_value(bool value) {
- filter_return_value_ = value;
- }
-
- private:
- static bool filter_return_value_;
-
- DISALLOW_COPY_AND_ASSIGN(TestEventFilter);
-};
-
-} // namespace trace_event
-} // namespace base
-
-#endif // BASE_TRACE_EVENT_TRACE_EVENT_FILTER_TEST_UTILS_H_
diff --git a/base/trace_event/trace_event_impl.cc b/base/trace_event/trace_event_impl.cc
deleted file mode 100644
index c72e1fc..0000000
--- a/base/trace_event/trace_event_impl.cc
+++ /dev/null
@@ -1,489 +0,0 @@
-// Copyright (c) 2012 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_event_impl.h"
-
-#include <stddef.h>
-
-#include "base/format_macros.h"
-#include "base/json/string_escape.h"
-#include "base/memory/ptr_util.h"
-#include "base/process/process_handle.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"
-#include "base/trace_event/trace_event.h"
-#include "base/trace_event/trace_event_argument.h"
-#include "base/trace_event/trace_log.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;
- }
-}
-
-} // namespace
-
-TraceEvent::TraceEvent()
- : duration_(TimeDelta::FromInternalValue(-1)),
- scope_(trace_event_internal::kGlobalScope),
- id_(0u),
- category_group_enabled_(nullptr),
- name_(nullptr),
- thread_id_(0),
- flags_(0),
- phase_(TRACE_EVENT_PHASE_BEGIN) {
- for (int i = 0; i < kTraceMaxNumArgs; ++i)
- arg_names_[i] = nullptr;
- memset(arg_values_, 0, sizeof(arg_values_));
-}
-
-TraceEvent::~TraceEvent() = default;
-
-void TraceEvent::MoveFrom(std::unique_ptr<TraceEvent> other) {
- timestamp_ = other->timestamp_;
- thread_timestamp_ = other->thread_timestamp_;
- duration_ = other->duration_;
- scope_ = other->scope_;
- id_ = other->id_;
- category_group_enabled_ = other->category_group_enabled_;
- name_ = other->name_;
- if (other->flags_ & TRACE_EVENT_FLAG_HAS_PROCESS_ID)
- process_id_ = other->process_id_;
- else
- thread_id_ = other->thread_id_;
- phase_ = other->phase_;
- flags_ = other->flags_;
- parameter_copy_storage_ = std::move(other->parameter_copy_storage_);
-
- for (int i = 0; i < kTraceMaxNumArgs; ++i) {
- arg_names_[i] = other->arg_names_[i];
- arg_types_[i] = other->arg_types_[i];
- arg_values_[i] = other->arg_values_[i];
- convertable_values_[i] = std::move(other->convertable_values_[i]);
- }
-}
-
-void TraceEvent::Initialize(
- 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;
- duration_ = TimeDelta::FromInternalValue(-1);
- scope_ = scope;
- id_ = id;
- category_group_enabled_ = category_group_enabled;
- name_ = name;
- thread_id_ = thread_id;
- phase_ = phase;
- flags_ = flags;
- bind_id_ = bind_id;
-
- // 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;
- }
-
- 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 Initialize(), or that may
- // hold references to other objects.
- duration_ = TimeDelta::FromInternalValue(-1);
- parameter_copy_storage_.reset();
- for (int i = 0; i < kTraceMaxNumArgs; ++i)
- convertable_values_[i].reset();
-}
-
-void TraceEvent::UpdateDuration(const TimeTicks& now,
- const ThreadTicks& thread_now) {
- DCHECK_EQ(duration_.ToInternalValue(), -1);
- duration_ = now - timestamp_;
-
- // |thread_timestamp_| can be empty if the thread ticks clock wasn't
- // initialized when it was recorded.
- if (thread_timestamp_ != ThreadTicks())
- thread_duration_ = thread_now - thread_timestamp_;
-}
-
-void TraceEvent::EstimateTraceMemoryOverhead(
- TraceEventMemoryOverhead* overhead) {
- overhead->Add(TraceEventMemoryOverhead::kTraceEvent, sizeof(*this));
-
- if (parameter_copy_storage_)
- overhead->AddString(*parameter_copy_storage_);
-
- 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;
- }
-}
-
-void TraceEvent::AppendAsJSON(
- std::string* out,
- const ArgumentFilterPredicate& argument_filter_predicate) const {
- int64_t time_int64 = timestamp_.ToInternalValue();
- int process_id;
- int thread_id;
- if ((flags_ & TRACE_EVENT_FLAG_HAS_PROCESS_ID) &&
- process_id_ != kNullProcessId) {
- process_id = process_id_;
- thread_id = -1;
- } else {
- process_id = TraceLog::GetInstance()->process_id();
- thread_id = thread_id_;
- }
- const char* category_group_name =
- TraceLog::GetCategoryGroupName(category_group_enabled_);
-
- // Category group checked at category creation time.
- DCHECK(!strchr(name_, '"'));
- StringAppendF(out, "{\"pid\":%i,\"tid\":%i,\"ts\":%" PRId64
- ",\"ph\":\"%c\",\"cat\":\"%s\",\"name\":",
- process_id, thread_id, time_int64, phase_, category_group_name);
- EscapeJSONString(name_, true, out);
- *out += ",\"args\":";
-
- // Output argument names and values, stop at first NULL argument name.
- // TODO(oysteine): The dual predicates here is a bit ugly; if the filtering
- // capabilities need to grow even more precise we should rethink this
- // approach
- ArgumentNameFilterPredicate argument_name_filter_predicate;
- bool strip_args =
- arg_names_[0] && !argument_filter_predicate.is_null() &&
- !argument_filter_predicate.Run(category_group_name, name_,
- &argument_name_filter_predicate);
-
- if (strip_args) {
- *out += "\"__stripped__\"";
- } else {
- *out += "{";
-
- for (int i = 0; i < kTraceMaxNumArgs && arg_names_[i]; ++i) {
- if (i > 0)
- *out += ",";
- *out += "\"";
- *out += arg_names_[i];
- *out += "\":";
-
- if (argument_name_filter_predicate.is_null() ||
- 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__\"";
- }
- }
-
- *out += "}";
- }
-
- if (phase_ == TRACE_EVENT_PHASE_COMPLETE) {
- int64_t duration = duration_.ToInternalValue();
- if (duration != -1)
- StringAppendF(out, ",\"dur\":%" PRId64, duration);
- if (!thread_timestamp_.is_null()) {
- int64_t thread_duration = thread_duration_.ToInternalValue();
- if (thread_duration != -1)
- StringAppendF(out, ",\"tdur\":%" PRId64, thread_duration);
- }
- }
-
- // Output tts if thread_timestamp is valid.
- if (!thread_timestamp_.is_null()) {
- int64_t thread_time_int64 = thread_timestamp_.ToInternalValue();
- StringAppendF(out, ",\"tts\":%" PRId64, thread_time_int64);
- }
-
- // Output async tts marker field if flag is set.
- if (flags_ & TRACE_EVENT_FLAG_ASYNC_TTS) {
- StringAppendF(out, ", \"use_async_tts\":1");
- }
-
- // If id_ is set, print it out as a hex string so we don't loose any
- // bits (it might be a 64-bit pointer).
- unsigned int id_flags_ = flags_ & (TRACE_EVENT_FLAG_HAS_ID |
- TRACE_EVENT_FLAG_HAS_LOCAL_ID |
- TRACE_EVENT_FLAG_HAS_GLOBAL_ID);
- if (id_flags_) {
- if (scope_ != trace_event_internal::kGlobalScope)
- StringAppendF(out, ",\"scope\":\"%s\"", scope_);
-
- switch (id_flags_) {
- case TRACE_EVENT_FLAG_HAS_ID:
- StringAppendF(out, ",\"id\":\"0x%" PRIx64 "\"",
- static_cast<uint64_t>(id_));
- break;
-
- case TRACE_EVENT_FLAG_HAS_LOCAL_ID:
- StringAppendF(out, ",\"id2\":{\"local\":\"0x%" PRIx64 "\"}",
- static_cast<uint64_t>(id_));
- break;
-
- case TRACE_EVENT_FLAG_HAS_GLOBAL_ID:
- StringAppendF(out, ",\"id2\":{\"global\":\"0x%" PRIx64 "\"}",
- static_cast<uint64_t>(id_));
- break;
-
- default:
- NOTREACHED() << "More than one of the ID flags are set";
- break;
- }
- }
-
- if (flags_ & TRACE_EVENT_FLAG_BIND_TO_ENCLOSING)
- StringAppendF(out, ",\"bp\":\"e\"");
-
- if ((flags_ & TRACE_EVENT_FLAG_FLOW_OUT) ||
- (flags_ & TRACE_EVENT_FLAG_FLOW_IN)) {
- StringAppendF(out, ",\"bind_id\":\"0x%" PRIx64 "\"",
- static_cast<uint64_t>(bind_id_));
- }
- if (flags_ & TRACE_EVENT_FLAG_FLOW_IN)
- StringAppendF(out, ",\"flow_in\":true");
- if (flags_ & TRACE_EVENT_FLAG_FLOW_OUT)
- StringAppendF(out, ",\"flow_out\":true");
-
- // Instant events also output their scope.
- if (phase_ == TRACE_EVENT_PHASE_INSTANT) {
- char scope = '?';
- switch (flags_ & TRACE_EVENT_FLAG_SCOPE_MASK) {
- case TRACE_EVENT_SCOPE_GLOBAL:
- scope = TRACE_EVENT_SCOPE_NAME_GLOBAL;
- break;
-
- case TRACE_EVENT_SCOPE_PROCESS:
- scope = TRACE_EVENT_SCOPE_NAME_PROCESS;
- break;
-
- case TRACE_EVENT_SCOPE_THREAD:
- scope = TRACE_EVENT_SCOPE_NAME_THREAD;
- break;
- }
- StringAppendF(out, ",\"s\":\"%c\"", scope);
- }
-
- *out += "}";
-}
-
-void TraceEvent::AppendPrettyPrinted(std::ostringstream* out) const {
- *out << name_ << "[";
- *out << TraceLog::GetCategoryGroupName(category_group_enabled_);
- *out << "]";
- if (arg_names_[0]) {
- *out << ", {";
- for (int i = 0; i < kTraceMaxNumArgs && arg_names_[i]; ++i) {
- if (i > 0)
- *out << ", ";
- *out << arg_names_[i] << ":";
- std::string 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 << "}";
- }
-}
-
-} // namespace trace_event
-} // namespace base
-
-namespace trace_event_internal {
-
-std::unique_ptr<base::trace_event::ConvertableToTraceFormat>
-TraceID::AsConvertableToTraceFormat() const {
- auto value = std::make_unique<base::trace_event::TracedValue>();
-
- if (scope_ != kGlobalScope)
- value->SetString("scope", scope_);
-
- const char* id_field_name = "id";
- if (id_flags_ == TRACE_EVENT_FLAG_HAS_GLOBAL_ID) {
- id_field_name = "global";
- value->BeginDictionary("id2");
- } else if (id_flags_ == TRACE_EVENT_FLAG_HAS_LOCAL_ID) {
- id_field_name = "local";
- value->BeginDictionary("id2");
- } else if (id_flags_ != TRACE_EVENT_FLAG_HAS_ID) {
- NOTREACHED() << "Unrecognized ID flag";
- }
-
- if (has_prefix_) {
- value->SetString(id_field_name,
- base::StringPrintf("0x%" PRIx64 "/0x%" PRIx64,
- static_cast<uint64_t>(prefix_),
- static_cast<uint64_t>(raw_id_)));
- } else {
- value->SetString(
- id_field_name,
- base::StringPrintf("0x%" PRIx64, static_cast<uint64_t>(raw_id_)));
- }
-
- if (id_flags_ != TRACE_EVENT_FLAG_HAS_ID)
- value->EndDictionary();
-
- return std::move(value);
-}
-
-} // namespace trace_event_internal
diff --git a/base/trace_event/trace_event_impl.h b/base/trace_event/trace_event_impl.h
deleted file mode 100644
index af47f49..0000000
--- a/base/trace_event/trace_event_impl.h
+++ /dev/null
@@ -1,187 +0,0 @@
-// Copyright (c) 2012 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_EVENT_IMPL_H_
-#define BASE_TRACE_EVENT_TRACE_EVENT_IMPL_H_
-
-#include <stdint.h>
-
-#include <memory>
-#include <string>
-#include <vector>
-
-#include "base/atomicops.h"
-#include "base/base_export.h"
-#include "base/callback.h"
-#include "base/containers/hash_tables.h"
-#include "base/macros.h"
-#include "base/observer_list.h"
-#include "base/single_thread_task_runner.h"
-#include "base/strings/string_util.h"
-#include "base/synchronization/condition_variable.h"
-#include "base/synchronization/lock.h"
-#include "base/threading/thread_local.h"
-#include "base/trace_event/trace_event_memory_overhead.h"
-#include "build_config.h"
-
-namespace base {
-namespace trace_event {
-
-typedef base::Callback<bool(const char* arg_name)> ArgumentNameFilterPredicate;
-
-typedef base::Callback<bool(const char* category_group_name,
- const char* event_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;
-
- 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
- // TraceBufferChunk::kMaxTrunkIndex and
- // TraceBufferChunk::kTraceBufferChunkSize (in trace_buffer.h).
- unsigned chunk_index : 26;
- unsigned event_index : 6;
-};
-
-class BASE_EXPORT TraceEvent {
- public:
- 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();
- ~TraceEvent();
-
- void MoveFrom(std::unique_ptr<TraceEvent> other);
-
- void Initialize(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);
-
- void Reset();
-
- void UpdateDuration(const TimeTicks& now, const ThreadTicks& thread_now);
-
- void EstimateTraceMemoryOverhead(TraceEventMemoryOverhead* overhead);
-
- // Serialize event data to JSON
- void AppendAsJSON(
- std::string* out,
- const ArgumentFilterPredicate& argument_filter_predicate) const;
- void AppendPrettyPrinted(std::ostringstream* out) const;
-
- static void AppendValueAsJSON(unsigned char type,
- TraceValue value,
- std::string* out);
-
- TimeTicks timestamp() const { return timestamp_; }
- ThreadTicks thread_timestamp() const { return thread_timestamp_; }
- char phase() const { return phase_; }
- int thread_id() const { return thread_id_; }
- TimeDelta duration() const { return duration_; }
- TimeDelta thread_duration() const { return thread_duration_; }
- const char* scope() const { return scope_; }
- unsigned long long id() const { return id_; }
- unsigned int flags() const { return flags_; }
- unsigned long long bind_id() const { return bind_id_; }
- // Exposed for unittesting:
-
- const std::string* parameter_copy_storage() const {
- return parameter_copy_storage_.get();
- }
-
- const unsigned char* category_group_enabled() const {
- return category_group_enabled_;
- }
-
- const char* name() const { return name_; }
-
- 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]; }
-
-#if defined(OS_ANDROID)
- void SendToATrace();
-#endif
-
- private:
- // Note: these are ordered by size (largest first) for optimal packing.
- TimeTicks timestamp_;
- ThreadTicks thread_timestamp_;
- TimeDelta duration_;
- TimeDelta thread_duration_;
- // scope_ and id_ can be used to store phase-specific data.
- const char* scope_;
- unsigned long long id_;
- TraceValue arg_values_[kTraceMaxNumArgs];
- const char* arg_names_[kTraceMaxNumArgs];
- std::unique_ptr<ConvertableToTraceFormat>
- convertable_values_[kTraceMaxNumArgs];
- const unsigned char* category_group_enabled_;
- const char* name_;
- 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).
- union {
- int thread_id_;
- int process_id_;
- };
- unsigned int flags_;
- unsigned long long bind_id_;
- unsigned char arg_types_[kTraceMaxNumArgs];
- char phase_;
-
- DISALLOW_COPY_AND_ASSIGN(TraceEvent);
-};
-
-} // namespace trace_event
-} // namespace base
-
-#endif // BASE_TRACE_EVENT_TRACE_EVENT_IMPL_H_
diff --git a/base/trace_event/trace_event_memory_overhead.cc b/base/trace_event/trace_event_memory_overhead.cc
deleted file mode 100644
index d5875f8..0000000
--- a/base/trace_event/trace_event_memory_overhead.cc
+++ /dev/null
@@ -1,177 +0,0 @@
-// Copyright 2015 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_event_memory_overhead.h"
-
-#include <algorithm>
-
-#include "base/bits.h"
-#include "base/memory/ref_counted_memory.h"
-#include "base/strings/stringprintf.h"
-#include "base/trace_event/memory_allocator_dump.h"
-#include "base/trace_event/memory_usage_estimator.h"
-#include "base/trace_event/process_memory_dump.h"
-#include "base/values.h"
-
-namespace base {
-namespace trace_event {
-
-namespace {
-
-const char* ObjectTypeToString(TraceEventMemoryOverhead::ObjectType type) {
- switch (type) {
- case TraceEventMemoryOverhead::kOther:
- return "(Other)";
- case TraceEventMemoryOverhead::kTraceBuffer:
- return "TraceBuffer";
- case TraceEventMemoryOverhead::kTraceBufferChunk:
- return "TraceBufferChunk";
- case TraceEventMemoryOverhead::kTraceEvent:
- return "TraceEvent";
- case TraceEventMemoryOverhead::kUnusedTraceEvent:
- return "TraceEvent(Unused)";
- case TraceEventMemoryOverhead::kTracedValue:
- return "TracedValue";
- case TraceEventMemoryOverhead::kConvertableToTraceFormat:
- return "ConvertableToTraceFormat";
- case TraceEventMemoryOverhead::kHeapProfilerAllocationRegister:
- return "AllocationRegister";
- case TraceEventMemoryOverhead::kHeapProfilerTypeNameDeduplicator:
- return "TypeNameDeduplicator";
- case TraceEventMemoryOverhead::kHeapProfilerStackFrameDeduplicator:
- return "StackFrameDeduplicator";
- case TraceEventMemoryOverhead::kStdString:
- return "std::string";
- case TraceEventMemoryOverhead::kBaseValue:
- return "base::Value";
- case TraceEventMemoryOverhead::kTraceEventMemoryOverhead:
- return "TraceEventMemoryOverhead";
- case TraceEventMemoryOverhead::kLast:
- NOTREACHED();
- }
- NOTREACHED();
- return "BUG";
-}
-
-} // namespace
-
-TraceEventMemoryOverhead::TraceEventMemoryOverhead() : allocated_objects_() {}
-
-TraceEventMemoryOverhead::~TraceEventMemoryOverhead() = default;
-
-void TraceEventMemoryOverhead::AddInternal(ObjectType object_type,
- size_t count,
- size_t allocated_size_in_bytes,
- size_t resident_size_in_bytes) {
- ObjectCountAndSize& count_and_size =
- allocated_objects_[static_cast<uint32_t>(object_type)];
- count_and_size.count += count;
- count_and_size.allocated_size_in_bytes += allocated_size_in_bytes;
- count_and_size.resident_size_in_bytes += resident_size_in_bytes;
-}
-
-void TraceEventMemoryOverhead::Add(ObjectType object_type,
- size_t allocated_size_in_bytes) {
- Add(object_type, allocated_size_in_bytes, allocated_size_in_bytes);
-}
-
-void TraceEventMemoryOverhead::Add(ObjectType object_type,
- size_t allocated_size_in_bytes,
- size_t resident_size_in_bytes) {
- AddInternal(object_type, 1, allocated_size_in_bytes, resident_size_in_bytes);
-}
-
-void TraceEventMemoryOverhead::AddString(const std::string& str) {
- Add(kStdString, EstimateMemoryUsage(str));
-}
-
-void TraceEventMemoryOverhead::AddRefCountedString(
- const RefCountedString& str) {
- Add(kOther, sizeof(RefCountedString));
- AddString(str.data());
-}
-
-void TraceEventMemoryOverhead::AddValue(const Value& value) {
- switch (value.type()) {
- case Value::Type::NONE:
- case Value::Type::BOOLEAN:
- case Value::Type::INTEGER:
- case Value::Type::DOUBLE:
- Add(kBaseValue, sizeof(Value));
- break;
-
- case Value::Type::STRING: {
- const Value* string_value = nullptr;
- value.GetAsString(&string_value);
- Add(kBaseValue, sizeof(Value));
- AddString(string_value->GetString());
- } break;
-
- case Value::Type::BINARY: {
- Add(kBaseValue, sizeof(Value) + value.GetBlob().size());
- } break;
-
- case Value::Type::DICTIONARY: {
- const DictionaryValue* dictionary_value = nullptr;
- value.GetAsDictionary(&dictionary_value);
- Add(kBaseValue, sizeof(DictionaryValue));
- for (DictionaryValue::Iterator it(*dictionary_value); !it.IsAtEnd();
- it.Advance()) {
- AddString(it.key());
- AddValue(it.value());
- }
- } break;
-
- case Value::Type::LIST: {
- const ListValue* list_value = nullptr;
- value.GetAsList(&list_value);
- Add(kBaseValue, sizeof(ListValue));
- for (const auto& v : *list_value)
- AddValue(v);
- } break;
-
- default:
- NOTREACHED();
- }
-}
-
-void TraceEventMemoryOverhead::AddSelf() {
- Add(kTraceEventMemoryOverhead, sizeof(*this));
-}
-
-size_t TraceEventMemoryOverhead::GetCount(ObjectType object_type) const {
- CHECK(object_type < kLast);
- return allocated_objects_[static_cast<uint32_t>(object_type)].count;
-}
-
-void TraceEventMemoryOverhead::Update(const TraceEventMemoryOverhead& other) {
- for (uint32_t i = 0; i < kLast; i++) {
- const ObjectCountAndSize& other_entry = other.allocated_objects_[i];
- AddInternal(static_cast<ObjectType>(i), other_entry.count,
- other_entry.allocated_size_in_bytes,
- other_entry.resident_size_in_bytes);
- }
-}
-
-void TraceEventMemoryOverhead::DumpInto(const char* base_name,
- ProcessMemoryDump* pmd) const {
- for (uint32_t i = 0; i < kLast; i++) {
- const ObjectCountAndSize& count_and_size = allocated_objects_[i];
- if (count_and_size.allocated_size_in_bytes == 0)
- continue;
- std::string dump_name = StringPrintf(
- "%s/%s", base_name, ObjectTypeToString(static_cast<ObjectType>(i)));
- MemoryAllocatorDump* mad = pmd->CreateAllocatorDump(dump_name);
- mad->AddScalar(MemoryAllocatorDump::kNameSize,
- MemoryAllocatorDump::kUnitsBytes,
- count_and_size.allocated_size_in_bytes);
- mad->AddScalar("resident_size", MemoryAllocatorDump::kUnitsBytes,
- count_and_size.resident_size_in_bytes);
- mad->AddScalar(MemoryAllocatorDump::kNameObjectCount,
- MemoryAllocatorDump::kUnitsObjects, count_and_size.count);
- }
-}
-
-} // namespace trace_event
-} // namespace base
diff --git a/base/trace_event/trace_event_memory_overhead.h b/base/trace_event/trace_event_memory_overhead.h
deleted file mode 100644
index 1587a30..0000000
--- a/base/trace_event/trace_event_memory_overhead.h
+++ /dev/null
@@ -1,94 +0,0 @@
-// Copyright 2015 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_EVENT_MEMORY_OVERHEAD_H_
-#define BASE_TRACE_EVENT_TRACE_EVENT_MEMORY_OVERHEAD_H_
-
-#include <stddef.h>
-#include <stdint.h>
-
-#include <unordered_map>
-
-#include "base/base_export.h"
-#include "base/macros.h"
-
-namespace base {
-
-class RefCountedString;
-class Value;
-
-namespace trace_event {
-
-class ProcessMemoryDump;
-
-// Used to estimate the memory overhead of the tracing infrastructure.
-class BASE_EXPORT TraceEventMemoryOverhead {
- public:
- enum ObjectType : uint32_t {
- kOther = 0,
- kTraceBuffer,
- kTraceBufferChunk,
- kTraceEvent,
- kUnusedTraceEvent,
- kTracedValue,
- kConvertableToTraceFormat,
- kHeapProfilerAllocationRegister,
- kHeapProfilerTypeNameDeduplicator,
- kHeapProfilerStackFrameDeduplicator,
- kStdString,
- kBaseValue,
- kTraceEventMemoryOverhead,
- kLast
- };
-
- TraceEventMemoryOverhead();
- ~TraceEventMemoryOverhead();
-
- // Use this method to account the overhead of an object for which an estimate
- // is known for both the allocated and resident memory.
- void Add(ObjectType object_type,
- size_t allocated_size_in_bytes,
- size_t resident_size_in_bytes);
-
- // Similar to Add() above, but assumes that
- // |resident_size_in_bytes| == |allocated_size_in_bytes|.
- void Add(ObjectType object_type, size_t allocated_size_in_bytes);
-
- // Specialized profiling functions for commonly used object types.
- void AddString(const std::string& str);
- void AddValue(const Value& value);
- void AddRefCountedString(const RefCountedString& str);
-
- // Call this after all the Add* methods above to account the memory used by
- // this TraceEventMemoryOverhead instance itself.
- void AddSelf();
-
- // Retrieves the count, that is, the count of Add*(|object_type|, ...) calls.
- size_t GetCount(ObjectType object_type) const;
-
- // Adds up and merges all the values from |other| to this instance.
- void Update(const TraceEventMemoryOverhead& other);
-
- void DumpInto(const char* base_name, ProcessMemoryDump* pmd) const;
-
- private:
- struct ObjectCountAndSize {
- size_t count;
- size_t allocated_size_in_bytes;
- size_t resident_size_in_bytes;
- };
- ObjectCountAndSize allocated_objects_[ObjectType::kLast];
-
- void AddInternal(ObjectType object_type,
- size_t count,
- size_t allocated_size_in_bytes,
- size_t resident_size_in_bytes);
-
- DISALLOW_COPY_AND_ASSIGN(TraceEventMemoryOverhead);
-};
-
-} // namespace trace_event
-} // namespace base
-
-#endif // BASE_TRACE_EVENT_TRACE_EVENT_MEMORY_OVERHEAD_H_
diff --git a/base/trace_event/trace_event_system_stats_monitor.cc b/base/trace_event/trace_event_system_stats_monitor.cc
deleted file mode 100644
index 7e082f3..0000000
--- a/base/trace_event/trace_event_system_stats_monitor.cc
+++ /dev/null
@@ -1,132 +0,0 @@
-// Copyright 2013 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_event_system_stats_monitor.h"
-
-#include <memory>
-
-#include "base/debug/leak_annotations.h"
-#include "base/json/json_writer.h"
-#include "base/lazy_instance.h"
-#include "base/logging.h"
-#include "base/macros.h"
-#include "base/process/process_metrics.h"
-#include "base/strings/string_number_conversions.h"
-#include "base/strings/string_util.h"
-#include "base/threading/thread_local_storage.h"
-#include "base/threading/thread_task_runner_handle.h"
-#include "base/trace_event/trace_event.h"
-
-namespace base {
-namespace trace_event {
-
-namespace {
-
-/////////////////////////////////////////////////////////////////////////////
-// Holds profiled system stats until the tracing system needs to serialize it.
-class SystemStatsHolder : public base::trace_event::ConvertableToTraceFormat {
- public:
- SystemStatsHolder() = default;
- ~SystemStatsHolder() override = default;
-
- // Fills system_metrics_ with profiled system memory and disk stats.
- // Uses the previous stats to compute rates if this is not the first profile.
- void GetSystemProfilingStats();
-
- // base::trace_event::ConvertableToTraceFormat overrides:
- void AppendAsTraceFormat(std::string* out) const override {
- AppendSystemProfileAsTraceFormat(system_stats_, out);
- }
-
- private:
- SystemMetrics system_stats_;
-
- DISALLOW_COPY_AND_ASSIGN(SystemStatsHolder);
-};
-
-void SystemStatsHolder::GetSystemProfilingStats() {
- system_stats_ = SystemMetrics::Sample();
-}
-
-} // namespace
-
-//////////////////////////////////////////////////////////////////////////////
-
-TraceEventSystemStatsMonitor::TraceEventSystemStatsMonitor(
- scoped_refptr<SingleThreadTaskRunner> task_runner)
- : task_runner_(task_runner),
- weak_factory_(this) {
- // Force the "system_stats" category to show up in the trace viewer.
- TraceLog::GetCategoryGroupEnabled(TRACE_DISABLED_BY_DEFAULT("system_stats"));
-
- // Allow this to be instantiated on unsupported platforms, but don't run.
- TraceLog::GetInstance()->AddEnabledStateObserver(this);
-}
-
-TraceEventSystemStatsMonitor::~TraceEventSystemStatsMonitor() {
- if (dump_timer_.IsRunning())
- StopProfiling();
- TraceLog::GetInstance()->RemoveEnabledStateObserver(this);
-}
-
-void TraceEventSystemStatsMonitor::OnTraceLogEnabled() {
- // Check to see if system tracing is enabled.
- bool enabled;
-
- TRACE_EVENT_CATEGORY_GROUP_ENABLED(TRACE_DISABLED_BY_DEFAULT(
- "system_stats"), &enabled);
- if (!enabled)
- return;
- task_runner_->PostTask(
- FROM_HERE, base::BindOnce(&TraceEventSystemStatsMonitor::StartProfiling,
- weak_factory_.GetWeakPtr()));
-}
-
-void TraceEventSystemStatsMonitor::OnTraceLogDisabled() {
- task_runner_->PostTask(
- FROM_HERE, base::BindOnce(&TraceEventSystemStatsMonitor::StopProfiling,
- weak_factory_.GetWeakPtr()));
-}
-
-void TraceEventSystemStatsMonitor::StartProfiling() {
- // Watch for the tracing framework sending enabling more than once.
- if (dump_timer_.IsRunning())
- return;
-
- dump_timer_.Start(FROM_HERE,
- TimeDelta::FromMilliseconds(TraceEventSystemStatsMonitor::
- kSamplingIntervalMilliseconds),
- base::Bind(&TraceEventSystemStatsMonitor::
- DumpSystemStats,
- weak_factory_.GetWeakPtr()));
-}
-
-// If system tracing is enabled, dumps a profile to the tracing system.
-void TraceEventSystemStatsMonitor::DumpSystemStats() {
- std::unique_ptr<SystemStatsHolder> dump_holder(new SystemStatsHolder());
- dump_holder->GetSystemProfilingStats();
-
- TRACE_EVENT_OBJECT_SNAPSHOT_WITH_ID(
- TRACE_DISABLED_BY_DEFAULT("system_stats"),
- "base::TraceEventSystemStatsMonitor::SystemStats", this,
- std::move(dump_holder));
-}
-
-void TraceEventSystemStatsMonitor::StopProfiling() {
- dump_timer_.Stop();
-}
-
-bool TraceEventSystemStatsMonitor::IsTimerRunningForTest() const {
- return dump_timer_.IsRunning();
-}
-
-void AppendSystemProfileAsTraceFormat(const SystemMetrics& system_metrics,
- std::string* output) {
- std::string tmp;
- base::JSONWriter::Write(*system_metrics.ToValue(), &tmp);
- *output += tmp;
-}
-
-} // namespace trace_event
-} // namespace base
diff --git a/base/trace_event/trace_event_system_stats_monitor.h b/base/trace_event/trace_event_system_stats_monitor.h
deleted file mode 100644
index 14aa568..0000000
--- a/base/trace_event/trace_event_system_stats_monitor.h
+++ /dev/null
@@ -1,76 +0,0 @@
-// Copyright 2013 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_EVENT_SYSTEM_STATS_MONITOR_H_
-#define BASE_TRACE_EVENT_TRACE_EVENT_SYSTEM_STATS_MONITOR_H_
-
-#include "base/base_export.h"
-#include "base/gtest_prod_util.h"
-#include "base/macros.h"
-#include "base/memory/ref_counted.h"
-#include "base/memory/weak_ptr.h"
-#include "base/process/process_metrics.h"
-#include "base/timer/timer.h"
-#include "base/trace_event/trace_log.h"
-
-namespace base {
-
-class SingleThreadTaskRunner;
-
-namespace trace_event {
-
-// Watches for chrome://tracing to be enabled or disabled. When tracing is
-// enabled, also enables system events profiling. This class is the preferred
-// way to turn system tracing on and off.
-class BASE_EXPORT TraceEventSystemStatsMonitor
- : public TraceLog::EnabledStateObserver {
- public:
- // Length of time interval between stat profiles.
- static const int kSamplingIntervalMilliseconds = 2000;
-
- // |task_runner| must be the primary thread for the client
- // process, e.g. the UI thread in a browser.
- explicit TraceEventSystemStatsMonitor(
- scoped_refptr<SingleThreadTaskRunner> task_runner);
-
- ~TraceEventSystemStatsMonitor() override;
-
- // base::trace_event::TraceLog::EnabledStateChangedObserver overrides:
- void OnTraceLogEnabled() override;
- void OnTraceLogDisabled() override;
-
- // Retrieves system profiling at the current time.
- void DumpSystemStats();
-
- private:
- FRIEND_TEST_ALL_PREFIXES(TraceSystemStatsMonitorTest,
- TraceEventSystemStatsMonitor);
-
- bool IsTimerRunningForTest() const;
-
- void StartProfiling();
-
- void StopProfiling();
-
- // Ensures the observer starts and stops tracing on the primary thread.
- scoped_refptr<SingleThreadTaskRunner> task_runner_;
-
- // Timer to schedule system profile dumps.
- RepeatingTimer dump_timer_;
-
- WeakPtrFactory<TraceEventSystemStatsMonitor> weak_factory_;
-
- DISALLOW_COPY_AND_ASSIGN(TraceEventSystemStatsMonitor);
-};
-
-// Converts system memory profiling stats in |input| to
-// trace event compatible JSON and appends to |output|. Visible for testing.
-BASE_EXPORT void AppendSystemProfileAsTraceFormat(const SystemMetrics&
- system_stats,
- std::string* output);
-
-} // namespace trace_event
-} // namespace base
-
-#endif // BASE_TRACE_EVENT_TRACE_EVENT_SYSTEM_STATS_MONITOR_H_
diff --git a/base/trace_event/trace_log.cc b/base/trace_event/trace_log.cc
deleted file mode 100644
index f608261..0000000
--- a/base/trace_event/trace_log.cc
+++ /dev/null
@@ -1,1743 +0,0 @@
-// Copyright 2015 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_log.h"
-
-#include <algorithm>
-#include <cmath>
-#include <memory>
-#include <utility>
-
-#include "base/base_switches.h"
-#include "base/bind.h"
-#include "base/command_line.h"
-#include "base/debug/leak_annotations.h"
-#include "base/location.h"
-#include "base/macros.h"
-#include "base/memory/ptr_util.h"
-#include "base/memory/ref_counted_memory.h"
-#include "base/message_loop/message_loop.h"
-#include "base/message_loop/message_loop_current.h"
-#include "base/no_destructor.h"
-#include "base/process/process_info.h"
-#include "base/process/process_metrics.h"
-#include "base/stl_util.h"
-#include "base/strings/string_piece.h"
-#include "base/strings/string_split.h"
-#include "base/strings/string_tokenizer.h"
-#include "base/strings/stringprintf.h"
-#include "base/sys_info.h"
-#include "base/task_scheduler/post_task.h"
-#include "base/threading/platform_thread.h"
-#include "base/threading/thread_id_name_manager.h"
-#include "base/threading/thread_task_runner_handle.h"
-#include "base/time/time.h"
-#include "base/trace_event/category_registry.h"
-#include "base/trace_event/event_name_filter.h"
-#include "base/trace_event/heap_profiler.h"
-#include "base/trace_event/heap_profiler_allocation_context_tracker.h"
-#include "base/trace_event/heap_profiler_event_filter.h"
-#include "base/trace_event/memory_dump_manager.h"
-#include "base/trace_event/memory_dump_provider.h"
-#include "base/trace_event/process_memory_dump.h"
-#include "base/trace_event/trace_buffer.h"
-#include "base/trace_event/trace_event.h"
-#include "build_config.h"
-
-#if defined(OS_ANDROID)
-// The linker assigns the virtual address of the start of current library to
-// this symbol.
-extern char __executable_start;
-#endif
-
-namespace base {
-namespace trace_event {
-
-namespace {
-
-// Controls the number of trace events we will buffer in-memory
-// before throwing them away.
-const size_t kTraceBufferChunkSize = TraceBufferChunk::kTraceBufferChunkSize;
-
-const size_t kTraceEventVectorBigBufferChunks =
- 512000000 / kTraceBufferChunkSize;
-static_assert(
- kTraceEventVectorBigBufferChunks <= TraceBufferChunk::kMaxChunkIndex,
- "Too many big buffer chunks");
-const size_t kTraceEventVectorBufferChunks = 256000 / kTraceBufferChunkSize;
-static_assert(
- kTraceEventVectorBufferChunks <= TraceBufferChunk::kMaxChunkIndex,
- "Too many vector buffer chunks");
-const size_t kTraceEventRingBufferChunks = kTraceEventVectorBufferChunks / 4;
-
-// ECHO_TO_CONSOLE needs a small buffer to hold the unfinished COMPLETE events.
-const size_t kEchoToConsoleTraceEventBufferChunks = 256;
-
-const size_t kTraceEventBufferSizeInBytes = 100 * 1024;
-const int kThreadFlushTimeoutMs = 3000;
-
-TraceLog* g_trace_log_for_testing = nullptr;
-
-#define MAX_TRACE_EVENT_FILTERS 32
-
-// List of TraceEventFilter objects from the most recent tracing session.
-std::vector<std::unique_ptr<TraceEventFilter>>& GetCategoryGroupFilters() {
- static auto* filters = new std::vector<std::unique_ptr<TraceEventFilter>>();
- return *filters;
-}
-
-ThreadTicks ThreadNow() {
- return ThreadTicks::IsSupported()
- ? base::subtle::ThreadTicksNowIgnoringOverride()
- : ThreadTicks();
-}
-
-template <typename T>
-void InitializeMetadataEvent(TraceEvent* trace_event,
- int thread_id,
- const char* metadata_name,
- const char* arg_name,
- const T& value) {
- if (!trace_event)
- return;
-
- int num_args = 1;
- unsigned char arg_type;
- unsigned long long arg_value;
- ::trace_event_internal::SetTraceValue(value, &arg_type, &arg_value);
- trace_event->Initialize(
- 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
- num_args,
- &arg_name,
- &arg_type,
- &arg_value,
- nullptr,
- TRACE_EVENT_FLAG_NONE);
-}
-
-class AutoThreadLocalBoolean {
- public:
- explicit AutoThreadLocalBoolean(ThreadLocalBoolean* thread_local_boolean)
- : thread_local_boolean_(thread_local_boolean) {
- DCHECK(!thread_local_boolean_->Get());
- thread_local_boolean_->Set(true);
- }
- ~AutoThreadLocalBoolean() { thread_local_boolean_->Set(false); }
-
- private:
- ThreadLocalBoolean* thread_local_boolean_;
- DISALLOW_COPY_AND_ASSIGN(AutoThreadLocalBoolean);
-};
-
-// Use this function instead of TraceEventHandle constructor to keep the
-// overhead of ScopedTracer (trace_event.h) constructor minimum.
-void MakeHandle(uint32_t chunk_seq,
- size_t chunk_index,
- size_t event_index,
- TraceEventHandle* handle) {
- DCHECK(chunk_seq);
- DCHECK(chunk_index <= TraceBufferChunk::kMaxChunkIndex);
- DCHECK(event_index < TraceBufferChunk::kTraceBufferChunkSize);
- DCHECK(chunk_index <= std::numeric_limits<uint16_t>::max());
- handle->chunk_seq = chunk_seq;
- handle->chunk_index = static_cast<uint16_t>(chunk_index);
- handle->event_index = static_cast<uint16_t>(event_index);
-}
-
-template <typename Function>
-void ForEachCategoryFilter(const unsigned char* category_group_enabled,
- Function filter_fn) {
- const TraceCategory* category =
- CategoryRegistry::GetCategoryByStatePtr(category_group_enabled);
- uint32_t filter_bitmap = category->enabled_filters();
- for (int index = 0; filter_bitmap != 0; filter_bitmap >>= 1, index++) {
- if (filter_bitmap & 1 && GetCategoryGroupFilters()[index])
- filter_fn(GetCategoryGroupFilters()[index].get());
- }
-}
-
-} // namespace
-
-// A helper class that allows the lock to be acquired in the middle of the scope
-// and unlocks at the end of scope if locked.
-class TraceLog::OptionalAutoLock {
- public:
- explicit OptionalAutoLock(Lock* lock) : lock_(lock), locked_(false) {}
-
- ~OptionalAutoLock() {
- if (locked_)
- lock_->Release();
- }
-
- void EnsureAcquired() {
- if (!locked_) {
- lock_->Acquire();
- locked_ = true;
- }
- }
-
- private:
- Lock* lock_;
- bool locked_;
- DISALLOW_COPY_AND_ASSIGN(OptionalAutoLock);
-};
-
-class TraceLog::ThreadLocalEventBuffer
- : public MessageLoopCurrent::DestructionObserver,
- public MemoryDumpProvider {
- public:
- explicit ThreadLocalEventBuffer(TraceLog* trace_log);
- ~ThreadLocalEventBuffer() override;
-
- TraceEvent* AddTraceEvent(TraceEventHandle* handle);
-
- TraceEvent* GetEventByHandle(TraceEventHandle handle) {
- if (!chunk_ || handle.chunk_seq != chunk_->seq() ||
- handle.chunk_index != chunk_index_) {
- return nullptr;
- }
-
- return chunk_->GetEventAt(handle.event_index);
- }
-
- int generation() const { return generation_; }
-
- private:
- // MessageLoopCurrent::DestructionObserver
- void WillDestroyCurrentMessageLoop() override;
-
- // MemoryDumpProvider implementation.
- bool OnMemoryDump(const MemoryDumpArgs& args,
- ProcessMemoryDump* pmd) override;
-
- void FlushWhileLocked();
-
- void CheckThisIsCurrentBuffer() const {
- DCHECK(trace_log_->thread_local_event_buffer_.Get() == this);
- }
-
- // Since TraceLog is a leaky singleton, trace_log_ will always be valid
- // as long as the thread exists.
- TraceLog* trace_log_;
- std::unique_ptr<TraceBufferChunk> chunk_;
- size_t chunk_index_;
- int generation_;
-
- DISALLOW_COPY_AND_ASSIGN(ThreadLocalEventBuffer);
-};
-
-TraceLog::ThreadLocalEventBuffer::ThreadLocalEventBuffer(TraceLog* trace_log)
- : trace_log_(trace_log),
- chunk_index_(0),
- generation_(trace_log->generation()) {
- // ThreadLocalEventBuffer is created only if the thread has a message loop, so
- // the following message_loop won't be NULL.
- MessageLoop* message_loop = MessageLoop::current();
- message_loop->AddDestructionObserver(this);
-
- // This is to report the local memory usage when memory-infra is enabled.
- MemoryDumpManager::GetInstance()->RegisterDumpProvider(
- this, "ThreadLocalEventBuffer", ThreadTaskRunnerHandle::Get());
-
- AutoLock lock(trace_log->lock_);
- trace_log->thread_message_loops_.insert(message_loop);
-}
-
-TraceLog::ThreadLocalEventBuffer::~ThreadLocalEventBuffer() {
- CheckThisIsCurrentBuffer();
- MessageLoop::current()->RemoveDestructionObserver(this);
- MemoryDumpManager::GetInstance()->UnregisterDumpProvider(this);
-
- {
- AutoLock lock(trace_log_->lock_);
- FlushWhileLocked();
- trace_log_->thread_message_loops_.erase(MessageLoop::current());
- }
- trace_log_->thread_local_event_buffer_.Set(nullptr);
-}
-
-TraceEvent* TraceLog::ThreadLocalEventBuffer::AddTraceEvent(
- TraceEventHandle* handle) {
- CheckThisIsCurrentBuffer();
-
- if (chunk_ && chunk_->IsFull()) {
- AutoLock lock(trace_log_->lock_);
- FlushWhileLocked();
- chunk_.reset();
- }
- if (!chunk_) {
- AutoLock lock(trace_log_->lock_);
- chunk_ = trace_log_->logged_events_->GetChunk(&chunk_index_);
- trace_log_->CheckIfBufferIsFullWhileLocked();
- }
- if (!chunk_)
- return nullptr;
-
- size_t event_index;
- TraceEvent* trace_event = chunk_->AddTraceEvent(&event_index);
- if (trace_event && handle)
- MakeHandle(chunk_->seq(), chunk_index_, event_index, handle);
-
- return trace_event;
-}
-
-void TraceLog::ThreadLocalEventBuffer::WillDestroyCurrentMessageLoop() {
- delete this;
-}
-
-bool TraceLog::ThreadLocalEventBuffer::OnMemoryDump(const MemoryDumpArgs& args,
- ProcessMemoryDump* pmd) {
- if (!chunk_)
- return true;
- std::string dump_base_name = StringPrintf(
- "tracing/thread_%d", static_cast<int>(PlatformThread::CurrentId()));
- TraceEventMemoryOverhead overhead;
- chunk_->EstimateTraceMemoryOverhead(&overhead);
- overhead.DumpInto(dump_base_name.c_str(), pmd);
- return true;
-}
-
-void TraceLog::ThreadLocalEventBuffer::FlushWhileLocked() {
- if (!chunk_)
- return;
-
- trace_log_->lock_.AssertAcquired();
- if (trace_log_->CheckGeneration(generation_)) {
- // Return the chunk to the buffer only if the generation matches.
- trace_log_->logged_events_->ReturnChunk(chunk_index_, std::move(chunk_));
- }
- // Otherwise this method may be called from the destructor, or TraceLog will
- // find the generation mismatch and delete this buffer soon.
-}
-
-void TraceLog::SetAddTraceEventOverride(
- const AddTraceEventOverrideCallback& override) {
- subtle::NoBarrier_Store(&trace_event_override_,
- reinterpret_cast<subtle::AtomicWord>(override));
-}
-
-struct TraceLog::RegisteredAsyncObserver {
- explicit RegisteredAsyncObserver(WeakPtr<AsyncEnabledStateObserver> observer)
- : observer(observer), task_runner(ThreadTaskRunnerHandle::Get()) {}
- ~RegisteredAsyncObserver() = default;
-
- WeakPtr<AsyncEnabledStateObserver> observer;
- scoped_refptr<SequencedTaskRunner> task_runner;
-};
-
-TraceLogStatus::TraceLogStatus() : event_capacity(0), event_count(0) {}
-
-TraceLogStatus::~TraceLogStatus() = default;
-
-// static
-TraceLog* TraceLog::GetInstance() {
- static base::NoDestructor<TraceLog> instance;
- return instance.get();
-}
-
-// static
-void TraceLog::ResetForTesting() {
- if (!g_trace_log_for_testing)
- return;
- CategoryRegistry::ResetForTesting();
- g_trace_log_for_testing->~TraceLog();
- new (g_trace_log_for_testing) TraceLog;
-}
-
-TraceLog::TraceLog()
- : enabled_modes_(0),
- num_traces_recorded_(0),
- dispatching_to_observer_list_(false),
- process_sort_index_(0),
- process_id_hash_(0),
- process_id_(0),
- trace_options_(kInternalRecordUntilFull),
- trace_config_(TraceConfig()),
- thread_shared_chunk_index_(0),
- generation_(0),
- use_worker_thread_(false),
- trace_event_override_(0),
- filter_factory_for_testing_(nullptr) {
- CategoryRegistry::Initialize();
-
-#if defined(OS_NACL) // NaCl shouldn't expose the process id.
- SetProcessID(0);
-#else
- SetProcessID(static_cast<int>(GetCurrentProcId()));
-#endif
-
-// Linux renderer processes and Android O processes are not allowed to read
-// "proc/stat" file, crbug.com/788870.
-#if defined(OS_WIN) || (defined(OS_MACOSX) && !defined(OS_IOS))
- process_creation_time_ = CurrentProcessInfo::CreationTime();
-#else
- // Use approximate time when creation time is not available.
- process_creation_time_ = TRACE_TIME_NOW();
-#endif
-
- logged_events_.reset(CreateTraceBuffer());
-
- MemoryDumpManager::GetInstance()->RegisterDumpProvider(this, "TraceLog",
- nullptr);
- g_trace_log_for_testing = this;
-}
-
-TraceLog::~TraceLog() = default;
-
-void TraceLog::InitializeThreadLocalEventBufferIfSupported() {
- // A ThreadLocalEventBuffer needs the message loop
- // - to know when the thread exits;
- // - to handle the final flush.
- // For a thread without a message loop or the message loop may be blocked, the
- // trace events will be added into the main buffer directly.
- if (thread_blocks_message_loop_.Get() || !MessageLoopCurrent::IsSet())
- return;
- HEAP_PROFILER_SCOPED_IGNORE;
- auto* thread_local_event_buffer = thread_local_event_buffer_.Get();
- if (thread_local_event_buffer &&
- !CheckGeneration(thread_local_event_buffer->generation())) {
- delete thread_local_event_buffer;
- thread_local_event_buffer = nullptr;
- }
- if (!thread_local_event_buffer) {
- thread_local_event_buffer = new ThreadLocalEventBuffer(this);
- thread_local_event_buffer_.Set(thread_local_event_buffer);
- }
-}
-
-bool TraceLog::OnMemoryDump(const MemoryDumpArgs& args,
- ProcessMemoryDump* pmd) {
- // TODO(ssid): Use MemoryDumpArgs to create light dumps when requested
- // (crbug.com/499731).
- TraceEventMemoryOverhead overhead;
- overhead.Add(TraceEventMemoryOverhead::kOther, sizeof(*this));
- {
- AutoLock lock(lock_);
- if (logged_events_)
- logged_events_->EstimateTraceMemoryOverhead(&overhead);
-
- for (auto& metadata_event : metadata_events_)
- metadata_event->EstimateTraceMemoryOverhead(&overhead);
- }
- overhead.AddSelf();
- overhead.DumpInto("tracing/main_trace_log", pmd);
- return true;
-}
-
-const unsigned char* TraceLog::GetCategoryGroupEnabled(
- const char* category_group) {
- TraceLog* tracelog = GetInstance();
- if (!tracelog) {
- DCHECK(!CategoryRegistry::kCategoryAlreadyShutdown->is_enabled());
- return CategoryRegistry::kCategoryAlreadyShutdown->state_ptr();
- }
- TraceCategory* category = CategoryRegistry::GetCategoryByName(category_group);
- if (!category) {
- // Slow path: in the case of a new category we have to repeat the check
- // holding the lock, as multiple threads might have reached this point
- // at the same time.
- auto category_initializer = [](TraceCategory* category) {
- TraceLog::GetInstance()->UpdateCategoryState(category);
- };
- AutoLock lock(tracelog->lock_);
- CategoryRegistry::GetOrCreateCategoryLocked(
- category_group, category_initializer, &category);
- }
- DCHECK(category->state_ptr());
- return category->state_ptr();
-}
-
-const char* TraceLog::GetCategoryGroupName(
- const unsigned char* category_group_enabled) {
- return CategoryRegistry::GetCategoryByStatePtr(category_group_enabled)
- ->name();
-}
-
-void TraceLog::UpdateCategoryState(TraceCategory* category) {
- lock_.AssertAcquired();
- DCHECK(category->is_valid());
- unsigned char state_flags = 0;
- if (enabled_modes_ & RECORDING_MODE &&
- trace_config_.IsCategoryGroupEnabled(category->name())) {
- state_flags |= TraceCategory::ENABLED_FOR_RECORDING;
- }
-
- // TODO(primiano): this is a temporary workaround for catapult:#2341,
- // to guarantee that metadata events are always added even if the category
- // filter is "-*". See crbug.com/618054 for more details and long-term fix.
- if (enabled_modes_ & RECORDING_MODE &&
- category == CategoryRegistry::kCategoryMetadata) {
- state_flags |= TraceCategory::ENABLED_FOR_RECORDING;
- }
-
- uint32_t enabled_filters_bitmap = 0;
- int index = 0;
- for (const auto& event_filter : enabled_event_filters_) {
- if (event_filter.IsCategoryGroupEnabled(category->name())) {
- state_flags |= TraceCategory::ENABLED_FOR_FILTERING;
- DCHECK(GetCategoryGroupFilters()[index]);
- enabled_filters_bitmap |= 1 << index;
- }
- if (index++ >= MAX_TRACE_EVENT_FILTERS) {
- NOTREACHED();
- break;
- }
- }
- category->set_enabled_filters(enabled_filters_bitmap);
- category->set_state(state_flags);
-}
-
-void TraceLog::UpdateCategoryRegistry() {
- lock_.AssertAcquired();
- CreateFiltersForTraceConfig();
- for (TraceCategory& category : CategoryRegistry::GetAllCategories()) {
- UpdateCategoryState(&category);
- }
-}
-
-void TraceLog::CreateFiltersForTraceConfig() {
- if (!(enabled_modes_ & FILTERING_MODE))
- return;
-
- // Filters were already added and tracing could be enabled. Filters list
- // cannot be changed when trace events are using them.
- if (GetCategoryGroupFilters().size())
- return;
-
- for (auto& filter_config : enabled_event_filters_) {
- if (GetCategoryGroupFilters().size() >= MAX_TRACE_EVENT_FILTERS) {
- NOTREACHED()
- << "Too many trace event filters installed in the current session";
- break;
- }
-
- std::unique_ptr<TraceEventFilter> new_filter;
- const std::string& predicate_name = filter_config.predicate_name();
- if (predicate_name == EventNameFilter::kName) {
- auto whitelist = std::make_unique<std::unordered_set<std::string>>();
- CHECK(filter_config.GetArgAsSet("event_name_whitelist", &*whitelist));
- new_filter = std::make_unique<EventNameFilter>(std::move(whitelist));
- } else if (predicate_name == HeapProfilerEventFilter::kName) {
- new_filter = std::make_unique<HeapProfilerEventFilter>();
- } else {
- if (filter_factory_for_testing_)
- new_filter = filter_factory_for_testing_(predicate_name);
- CHECK(new_filter) << "Unknown trace filter " << predicate_name;
- }
- GetCategoryGroupFilters().push_back(std::move(new_filter));
- }
-}
-
-void TraceLog::GetKnownCategoryGroups(
- std::vector<std::string>* category_groups) {
- for (const auto& category : CategoryRegistry::GetAllCategories()) {
- if (!CategoryRegistry::IsBuiltinCategory(&category))
- category_groups->push_back(category.name());
- }
-}
-
-void TraceLog::SetEnabled(const TraceConfig& trace_config,
- uint8_t modes_to_enable) {
- std::vector<EnabledStateObserver*> observer_list;
- std::map<AsyncEnabledStateObserver*, RegisteredAsyncObserver> observer_map;
- {
- AutoLock lock(lock_);
-
- // Can't enable tracing when Flush() is in progress.
- DCHECK(!flush_task_runner_);
-
- InternalTraceOptions new_options =
- GetInternalOptionsFromTraceConfig(trace_config);
-
- InternalTraceOptions old_options = trace_options();
-
- if (dispatching_to_observer_list_) {
- // TODO(ssid): Change to NOTREACHED after fixing crbug.com/625170.
- DLOG(ERROR)
- << "Cannot manipulate TraceLog::Enabled state from an observer.";
- return;
- }
-
- // Clear all filters from previous tracing session. These filters are not
- // cleared at the end of tracing because some threads which hit trace event
- // when disabling, could try to use the filters.
- if (!enabled_modes_)
- GetCategoryGroupFilters().clear();
-
- // Update trace config for recording.
- const bool already_recording = enabled_modes_ & RECORDING_MODE;
- if (modes_to_enable & RECORDING_MODE) {
- if (already_recording) {
- // TODO(ssid): Stop suporting enabling of RECODING_MODE when already
- // enabled crbug.com/625170.
- DCHECK_EQ(new_options, old_options) << "Attempting to re-enable "
- "tracing with a different set "
- "of options.";
- trace_config_.Merge(trace_config);
- } else {
- trace_config_ = trace_config;
- }
- }
-
- // Update event filters only if filtering was not enabled.
- if (modes_to_enable & FILTERING_MODE && enabled_event_filters_.empty()) {
- DCHECK(!trace_config.event_filters().empty());
- enabled_event_filters_ = trace_config.event_filters();
- }
- // Keep the |trace_config_| updated with only enabled filters in case anyone
- // tries to read it using |GetCurrentTraceConfig| (even if filters are
- // empty).
- trace_config_.SetEventFilters(enabled_event_filters_);
-
- enabled_modes_ |= modes_to_enable;
- UpdateCategoryRegistry();
-
- // Do not notify observers or create trace buffer if only enabled for
- // filtering or if recording was already enabled.
- if (!(modes_to_enable & RECORDING_MODE) || already_recording)
- return;
-
- if (new_options != old_options) {
- subtle::NoBarrier_Store(&trace_options_, new_options);
- UseNextTraceBuffer();
- }
-
- num_traces_recorded_++;
-
- UpdateCategoryRegistry();
-
- dispatching_to_observer_list_ = true;
- observer_list = enabled_state_observer_list_;
- observer_map = async_observers_;
- }
- // Notify observers outside the lock in case they trigger trace events.
- for (EnabledStateObserver* observer : observer_list)
- observer->OnTraceLogEnabled();
- for (const auto& it : observer_map) {
- it.second.task_runner->PostTask(
- FROM_HERE, BindOnce(&AsyncEnabledStateObserver::OnTraceLogEnabled,
- it.second.observer));
- }
-
- {
- AutoLock lock(lock_);
- dispatching_to_observer_list_ = false;
- }
-}
-
-void TraceLog::SetArgumentFilterPredicate(
- const ArgumentFilterPredicate& argument_filter_predicate) {
- AutoLock lock(lock_);
- DCHECK(!argument_filter_predicate.is_null());
- DCHECK(argument_filter_predicate_.is_null());
- argument_filter_predicate_ = argument_filter_predicate;
-}
-
-TraceLog::InternalTraceOptions TraceLog::GetInternalOptionsFromTraceConfig(
- const TraceConfig& config) {
- InternalTraceOptions ret = config.IsArgumentFilterEnabled()
- ? kInternalEnableArgumentFilter
- : kInternalNone;
- switch (config.GetTraceRecordMode()) {
- case RECORD_UNTIL_FULL:
- return ret | kInternalRecordUntilFull;
- case RECORD_CONTINUOUSLY:
- return ret | kInternalRecordContinuously;
- case ECHO_TO_CONSOLE:
- return ret | kInternalEchoToConsole;
- case RECORD_AS_MUCH_AS_POSSIBLE:
- return ret | kInternalRecordAsMuchAsPossible;
- }
- NOTREACHED();
- return kInternalNone;
-}
-
-TraceConfig TraceLog::GetCurrentTraceConfig() const {
- AutoLock lock(lock_);
- return trace_config_;
-}
-
-void TraceLog::SetDisabled() {
- AutoLock lock(lock_);
- SetDisabledWhileLocked(RECORDING_MODE);
-}
-
-void TraceLog::SetDisabled(uint8_t modes_to_disable) {
- AutoLock lock(lock_);
- SetDisabledWhileLocked(modes_to_disable);
-}
-
-void TraceLog::SetDisabledWhileLocked(uint8_t modes_to_disable) {
- lock_.AssertAcquired();
-
- if (!(enabled_modes_ & modes_to_disable))
- return;
-
- if (dispatching_to_observer_list_) {
- // TODO(ssid): Change to NOTREACHED after fixing crbug.com/625170.
- DLOG(ERROR)
- << "Cannot manipulate TraceLog::Enabled state from an observer.";
- return;
- }
-
- bool is_recording_mode_disabled =
- (enabled_modes_ & RECORDING_MODE) && (modes_to_disable & RECORDING_MODE);
- enabled_modes_ &= ~modes_to_disable;
-
- if (modes_to_disable & FILTERING_MODE)
- enabled_event_filters_.clear();
-
- if (modes_to_disable & RECORDING_MODE)
- trace_config_.Clear();
-
- UpdateCategoryRegistry();
-
- // Add metadata events and notify observers only if recording mode was
- // disabled now.
- if (!is_recording_mode_disabled)
- return;
-
- AddMetadataEventsWhileLocked();
-
- // Remove metadata events so they will not get added to a subsequent trace.
- metadata_events_.clear();
-
- dispatching_to_observer_list_ = true;
- std::vector<EnabledStateObserver*> observer_list =
- enabled_state_observer_list_;
- std::map<AsyncEnabledStateObserver*, RegisteredAsyncObserver> observer_map =
- async_observers_;
-
- {
- // Dispatch to observers outside the lock in case the observer triggers a
- // trace event.
- AutoUnlock unlock(lock_);
- for (EnabledStateObserver* observer : observer_list)
- observer->OnTraceLogDisabled();
- for (const auto& it : observer_map) {
- it.second.task_runner->PostTask(
- FROM_HERE, BindOnce(&AsyncEnabledStateObserver::OnTraceLogDisabled,
- it.second.observer));
- }
- }
- dispatching_to_observer_list_ = false;
-}
-
-int TraceLog::GetNumTracesRecorded() {
- AutoLock lock(lock_);
- if (!IsEnabled())
- return -1;
- return num_traces_recorded_;
-}
-
-void TraceLog::AddEnabledStateObserver(EnabledStateObserver* listener) {
- AutoLock lock(lock_);
- enabled_state_observer_list_.push_back(listener);
-}
-
-void TraceLog::RemoveEnabledStateObserver(EnabledStateObserver* listener) {
- AutoLock lock(lock_);
- std::vector<EnabledStateObserver*>::iterator it =
- std::find(enabled_state_observer_list_.begin(),
- enabled_state_observer_list_.end(), listener);
- if (it != enabled_state_observer_list_.end())
- enabled_state_observer_list_.erase(it);
-}
-
-bool TraceLog::HasEnabledStateObserver(EnabledStateObserver* listener) const {
- AutoLock lock(lock_);
- return ContainsValue(enabled_state_observer_list_, listener);
-}
-
-TraceLogStatus TraceLog::GetStatus() const {
- AutoLock lock(lock_);
- TraceLogStatus result;
- result.event_capacity = static_cast<uint32_t>(logged_events_->Capacity());
- result.event_count = static_cast<uint32_t>(logged_events_->Size());
- return result;
-}
-
-bool TraceLog::BufferIsFull() const {
- AutoLock lock(lock_);
- return logged_events_->IsFull();
-}
-
-TraceEvent* TraceLog::AddEventToThreadSharedChunkWhileLocked(
- TraceEventHandle* handle,
- bool check_buffer_is_full) {
- lock_.AssertAcquired();
-
- if (thread_shared_chunk_ && thread_shared_chunk_->IsFull()) {
- logged_events_->ReturnChunk(thread_shared_chunk_index_,
- std::move(thread_shared_chunk_));
- }
-
- if (!thread_shared_chunk_) {
- thread_shared_chunk_ =
- logged_events_->GetChunk(&thread_shared_chunk_index_);
- if (check_buffer_is_full)
- CheckIfBufferIsFullWhileLocked();
- }
- if (!thread_shared_chunk_)
- return nullptr;
-
- size_t event_index;
- TraceEvent* trace_event = thread_shared_chunk_->AddTraceEvent(&event_index);
- if (trace_event && handle) {
- MakeHandle(thread_shared_chunk_->seq(), thread_shared_chunk_index_,
- event_index, handle);
- }
- return trace_event;
-}
-
-void TraceLog::CheckIfBufferIsFullWhileLocked() {
- lock_.AssertAcquired();
- if (logged_events_->IsFull()) {
- if (buffer_limit_reached_timestamp_.is_null()) {
- buffer_limit_reached_timestamp_ = OffsetNow();
- }
- SetDisabledWhileLocked(RECORDING_MODE);
- }
-}
-
-// Flush() works as the following:
-// 1. Flush() is called in thread A whose task runner is saved in
-// flush_task_runner_;
-// 2. If thread_message_loops_ is not empty, thread A posts task to each message
-// loop to flush the thread local buffers; otherwise finish the flush;
-// 3. FlushCurrentThread() deletes the thread local event buffer:
-// - The last batch of events of the thread are flushed into the main buffer;
-// - The message loop will be removed from thread_message_loops_;
-// If this is the last message loop, finish the flush;
-// 4. If any thread hasn't finish its flush in time, finish the flush.
-void TraceLog::Flush(const TraceLog::OutputCallback& cb,
- bool use_worker_thread) {
- FlushInternal(cb, use_worker_thread, false);
-}
-
-void TraceLog::CancelTracing(const OutputCallback& cb) {
- SetDisabled();
- FlushInternal(cb, false, true);
-}
-
-void TraceLog::FlushInternal(const TraceLog::OutputCallback& cb,
- bool use_worker_thread,
- bool discard_events) {
- use_worker_thread_ = use_worker_thread;
- if (IsEnabled()) {
- // Can't flush when tracing is enabled because otherwise PostTask would
- // - generate more trace events;
- // - deschedule the calling thread on some platforms causing inaccurate
- // timing of the trace events.
- scoped_refptr<RefCountedString> empty_result = new RefCountedString;
- if (!cb.is_null())
- cb.Run(empty_result, false);
- LOG(WARNING) << "Ignored TraceLog::Flush called when tracing is enabled";
- return;
- }
-
- int gen = generation();
- // Copy of thread_message_loops_ to be used without locking.
- std::vector<scoped_refptr<SingleThreadTaskRunner>>
- thread_message_loop_task_runners;
- {
- AutoLock lock(lock_);
- DCHECK(!flush_task_runner_);
- flush_task_runner_ = ThreadTaskRunnerHandle::IsSet()
- ? ThreadTaskRunnerHandle::Get()
- : nullptr;
- DCHECK(thread_message_loops_.empty() || flush_task_runner_);
- flush_output_callback_ = cb;
-
- if (thread_shared_chunk_) {
- logged_events_->ReturnChunk(thread_shared_chunk_index_,
- std::move(thread_shared_chunk_));
- }
-
- for (MessageLoop* loop : thread_message_loops_)
- thread_message_loop_task_runners.push_back(loop->task_runner());
- }
-
- if (!thread_message_loop_task_runners.empty()) {
- for (auto& task_runner : thread_message_loop_task_runners) {
- task_runner->PostTask(
- FROM_HERE, BindOnce(&TraceLog::FlushCurrentThread, Unretained(this),
- gen, discard_events));
- }
- flush_task_runner_->PostDelayedTask(
- FROM_HERE,
- BindOnce(&TraceLog::OnFlushTimeout, Unretained(this), gen,
- discard_events),
- TimeDelta::FromMilliseconds(kThreadFlushTimeoutMs));
- return;
- }
-
- FinishFlush(gen, discard_events);
-}
-
-// Usually it runs on a different thread.
-void TraceLog::ConvertTraceEventsToTraceFormat(
- std::unique_ptr<TraceBuffer> logged_events,
- const OutputCallback& flush_output_callback,
- const ArgumentFilterPredicate& argument_filter_predicate) {
- if (flush_output_callback.is_null())
- return;
-
- HEAP_PROFILER_SCOPED_IGNORE;
- // The callback need to be called at least once even if there is no events
- // to let the caller know the completion of flush.
- scoped_refptr<RefCountedString> json_events_str_ptr = new RefCountedString();
- const size_t kReserveCapacity = kTraceEventBufferSizeInBytes * 5 / 4;
- json_events_str_ptr->data().reserve(kReserveCapacity);
- while (const TraceBufferChunk* chunk = logged_events->NextChunk()) {
- for (size_t j = 0; j < chunk->size(); ++j) {
- size_t size = json_events_str_ptr->size();
- if (size > kTraceEventBufferSizeInBytes) {
- flush_output_callback.Run(json_events_str_ptr, true);
- json_events_str_ptr = new RefCountedString();
- json_events_str_ptr->data().reserve(kReserveCapacity);
- } else if (size) {
- json_events_str_ptr->data().append(",\n");
- }
- chunk->GetEventAt(j)->AppendAsJSON(&(json_events_str_ptr->data()),
- argument_filter_predicate);
- }
- }
- flush_output_callback.Run(json_events_str_ptr, false);
-}
-
-void TraceLog::FinishFlush(int generation, bool discard_events) {
- std::unique_ptr<TraceBuffer> previous_logged_events;
- OutputCallback flush_output_callback;
- ArgumentFilterPredicate argument_filter_predicate;
-
- if (!CheckGeneration(generation))
- return;
-
- {
- AutoLock lock(lock_);
-
- previous_logged_events.swap(logged_events_);
- UseNextTraceBuffer();
- thread_message_loops_.clear();
-
- flush_task_runner_ = nullptr;
- flush_output_callback = flush_output_callback_;
- flush_output_callback_.Reset();
-
- if (trace_options() & kInternalEnableArgumentFilter) {
- CHECK(!argument_filter_predicate_.is_null());
- argument_filter_predicate = argument_filter_predicate_;
- }
- }
-
- if (discard_events) {
- if (!flush_output_callback.is_null()) {
- scoped_refptr<RefCountedString> empty_result = new RefCountedString;
- flush_output_callback.Run(empty_result, false);
- }
- return;
- }
-
- if (use_worker_thread_) {
- base::PostTaskWithTraits(
- FROM_HERE,
- {MayBlock(), TaskPriority::BACKGROUND,
- TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN},
- BindOnce(&TraceLog::ConvertTraceEventsToTraceFormat,
- std::move(previous_logged_events), flush_output_callback,
- argument_filter_predicate));
- return;
- }
-
- ConvertTraceEventsToTraceFormat(std::move(previous_logged_events),
- flush_output_callback,
- argument_filter_predicate);
-}
-
-// Run in each thread holding a local event buffer.
-void TraceLog::FlushCurrentThread(int generation, bool discard_events) {
- {
- AutoLock lock(lock_);
- if (!CheckGeneration(generation) || !flush_task_runner_) {
- // This is late. The corresponding flush has finished.
- return;
- }
- }
-
- // This will flush the thread local buffer.
- delete thread_local_event_buffer_.Get();
-
- // Scheduler uses TRACE_EVENT macros when posting a task, which can lead
- // to acquiring a tracing lock. Given that posting a task requires grabbing
- // a scheduler lock, we need to post this task outside tracing lock to avoid
- // deadlocks.
- scoped_refptr<SingleThreadTaskRunner> cached_flush_task_runner;
- {
- AutoLock lock(lock_);
- cached_flush_task_runner = flush_task_runner_;
- if (!CheckGeneration(generation) || !flush_task_runner_ ||
- !thread_message_loops_.empty())
- return;
- }
- cached_flush_task_runner->PostTask(
- FROM_HERE, BindOnce(&TraceLog::FinishFlush, Unretained(this), generation,
- discard_events));
-}
-
-void TraceLog::OnFlushTimeout(int generation, bool discard_events) {
- {
- AutoLock lock(lock_);
- if (!CheckGeneration(generation) || !flush_task_runner_) {
- // Flush has finished before timeout.
- return;
- }
-
- LOG(WARNING)
- << "The following threads haven't finished flush in time. "
- "If this happens stably for some thread, please call "
- "TraceLog::GetInstance()->SetCurrentThreadBlocksMessageLoop() from "
- "the thread to avoid its trace events from being lost.";
- for (hash_set<MessageLoop*>::const_iterator it =
- thread_message_loops_.begin();
- it != thread_message_loops_.end(); ++it) {
- LOG(WARNING) << "Thread: " << (*it)->GetThreadName();
- }
- }
- FinishFlush(generation, discard_events);
-}
-
-void TraceLog::UseNextTraceBuffer() {
- logged_events_.reset(CreateTraceBuffer());
- subtle::NoBarrier_AtomicIncrement(&generation_, 1);
- thread_shared_chunk_.reset();
- thread_shared_chunk_index_ = 0;
-}
-
-TraceEventHandle TraceLog::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) {
- 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,
- trace_event_internal::kNoId, // bind_id
- thread_id,
- now,
- num_args,
- arg_names,
- arg_types,
- arg_values,
- convertable_values,
- flags);
-}
-
-TraceEventHandle TraceLog::AddTraceEventWithBindId(
- 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) {
- 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,
- num_args,
- arg_names,
- arg_types,
- arg_values,
- convertable_values,
- flags | TRACE_EVENT_FLAG_HAS_CONTEXT_ID);
-}
-
-TraceEventHandle TraceLog::AddTraceEventWithProcessId(
- char phase,
- const unsigned char* category_group_enabled,
- const char* name,
- const char* scope,
- unsigned long long id,
- int process_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) {
- base::TimeTicks now = TRACE_TIME_TICKS_NOW();
- return AddTraceEventWithThreadIdAndTimestamp(
- phase,
- category_group_enabled,
- name,
- scope,
- id,
- trace_event_internal::kNoId, // bind_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
-// with kNoId as bind_id
-TraceEventHandle TraceLog::AddTraceEventWithThreadIdAndTimestamp(
- char phase,
- const unsigned char* category_group_enabled,
- const char* name,
- const char* scope,
- unsigned long long id,
- int thread_id,
- const TimeTicks& timestamp,
- 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,
- trace_event_internal::kNoId, // bind_id
- thread_id,
- timestamp,
- num_args,
- arg_names,
- arg_types,
- arg_values,
- convertable_values,
- flags);
-}
-
-TraceEventHandle TraceLog::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 TimeTicks& timestamp,
- 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)
- return handle;
-
- // Avoid re-entrance of AddTraceEvent. This may happen in GPU process when
- // ECHO_TO_CONSOLE is enabled: AddTraceEvent -> LOG(ERROR) ->
- // GpuProcessLogMessageHandler -> PostPendingTask -> TRACE_EVENT ...
- if (thread_is_in_trace_event_.Get())
- return handle;
-
- AutoThreadLocalBoolean thread_is_in_trace_event(&thread_is_in_trace_event_);
-
- DCHECK(name);
- DCHECK(!timestamp.is_null());
-
- if (flags & TRACE_EVENT_FLAG_MANGLE_ID) {
- if ((flags & TRACE_EVENT_FLAG_FLOW_IN) ||
- (flags & TRACE_EVENT_FLAG_FLOW_OUT))
- bind_id = MangleEventId(bind_id);
- id = MangleEventId(id);
- }
-
- TimeTicks offset_event_timestamp = OffsetTimestamp(timestamp);
- ThreadTicks thread_now = ThreadNow();
-
- ThreadLocalEventBuffer* thread_local_event_buffer = nullptr;
- if (*category_group_enabled & RECORDING_MODE) {
- // |thread_local_event_buffer_| can be null if the current thread doesn't
- // have a message loop or the message loop is blocked.
- InitializeThreadLocalEventBufferIfSupported();
- thread_local_event_buffer = thread_local_event_buffer_.Get();
- }
-
- // Check and update the current thread name only if the event is for the
- // current thread to avoid locks in most cases.
- if (thread_id == static_cast<int>(PlatformThread::CurrentId())) {
- const char* new_name =
- ThreadIdNameManager::GetInstance()->GetName(thread_id);
- // Check if the thread name has been set or changed since the previous
- // call (if any), but don't bother if the new name is empty. Note this will
- // not detect a thread name change within the same char* buffer address: we
- // favor common case performance over corner case correctness.
- static auto* current_thread_name = new ThreadLocalPointer<const char>();
- if (new_name != current_thread_name->Get() && new_name && *new_name) {
- current_thread_name->Set(new_name);
-
- AutoLock thread_info_lock(thread_info_lock_);
-
- auto existing_name = thread_names_.find(thread_id);
- if (existing_name == thread_names_.end()) {
- // This is a new thread id, and a new name.
- thread_names_[thread_id] = new_name;
- } else {
- // This is a thread id that we've seen before, but potentially with a
- // new name.
- std::vector<StringPiece> existing_names = base::SplitStringPiece(
- existing_name->second, ",", base::KEEP_WHITESPACE,
- base::SPLIT_WANT_NONEMPTY);
- if (!ContainsValue(existing_names, new_name)) {
- if (!existing_names.empty())
- existing_name->second.push_back(',');
- existing_name->second.append(new_name);
- }
- }
- }
- }
-
- AddTraceEventOverrideCallback trace_event_override =
- reinterpret_cast<AddTraceEventOverrideCallback>(
- subtle::NoBarrier_Load(&trace_event_override_));
- if (trace_event_override) {
- TraceEvent new_trace_event;
- // If we have an override in place for events, rather than sending
- // them to the tracelog, we don't have a way of going back and updating
- // the duration of _COMPLETE events. Instead, we emit separate _BEGIN
- // and _END events.
- if (phase == TRACE_EVENT_PHASE_COMPLETE)
- phase = TRACE_EVENT_PHASE_BEGIN;
-
- new_trace_event.Initialize(thread_id, offset_event_timestamp, thread_now,
- phase, category_group_enabled, name, scope, id,
- bind_id, num_args, arg_names, arg_types,
- arg_values, convertable_values, flags);
-
- trace_event_override(new_trace_event);
- return handle;
- }
-
- std::string console_message;
- std::unique_ptr<TraceEvent> filtered_trace_event;
- bool disabled_by_filters = false;
- if (*category_group_enabled & TraceCategory::ENABLED_FOR_FILTERING) {
- std::unique_ptr<TraceEvent> new_trace_event(new TraceEvent);
- new_trace_event->Initialize(thread_id, offset_event_timestamp, thread_now,
- phase, category_group_enabled, name, scope, id,
- bind_id, num_args, arg_names, arg_types,
- arg_values, convertable_values, flags);
-
- disabled_by_filters = true;
- ForEachCategoryFilter(
- category_group_enabled, [&new_trace_event, &disabled_by_filters](
- TraceEventFilter* trace_event_filter) {
- if (trace_event_filter->FilterTraceEvent(*new_trace_event))
- disabled_by_filters = false;
- });
- if (!disabled_by_filters)
- filtered_trace_event = std::move(new_trace_event);
- }
-
- // If enabled for recording, the event should be added only if one of the
- // filters indicates or category is not enabled for filtering.
- if ((*category_group_enabled & TraceCategory::ENABLED_FOR_RECORDING) &&
- !disabled_by_filters) {
- OptionalAutoLock lock(&lock_);
-
- TraceEvent* trace_event = nullptr;
- if (thread_local_event_buffer) {
- trace_event = thread_local_event_buffer->AddTraceEvent(&handle);
- } else {
- lock.EnsureAcquired();
- trace_event = AddEventToThreadSharedChunkWhileLocked(&handle, true);
- }
-
- if (trace_event) {
- if (filtered_trace_event) {
- trace_event->MoveFrom(std::move(filtered_trace_event));
- } else {
- trace_event->Initialize(thread_id, offset_event_timestamp, thread_now,
- phase, category_group_enabled, name, scope, id,
- bind_id, num_args, arg_names, arg_types,
- arg_values, convertable_values, flags);
- }
-
-#if defined(OS_ANDROID)
- trace_event->SendToATrace();
-#endif
- }
-
- if (trace_options() & kInternalEchoToConsole) {
- console_message = EventToConsoleMessage(
- phase == TRACE_EVENT_PHASE_COMPLETE ? TRACE_EVENT_PHASE_BEGIN : phase,
- timestamp, trace_event);
- }
- }
-
- if (!console_message.empty())
- LOG(ERROR) << console_message;
-
- return handle;
-}
-
-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;
- std::unique_ptr<TraceEvent> trace_event(new TraceEvent);
- int thread_id = static_cast<int>(base::PlatformThread::CurrentId());
- ThreadTicks thread_now = ThreadNow();
- TimeTicks now = OffsetNow();
- AutoLock lock(lock_);
- trace_event->Initialize(
- thread_id, now, thread_now, TRACE_EVENT_PHASE_METADATA,
- category_group_enabled, name,
- trace_event_internal::kGlobalScope, // scope
- trace_event_internal::kNoId, // id
- trace_event_internal::kNoId, // bind_id
- num_args, arg_names, arg_types, arg_values, convertable_values, flags);
- metadata_events_.push_back(std::move(trace_event));
-}
-
-// May be called when a COMPELETE event ends and the unfinished event has been
-// recycled (phase == TRACE_EVENT_PHASE_END and trace_event == NULL).
-std::string TraceLog::EventToConsoleMessage(unsigned char phase,
- const TimeTicks& timestamp,
- TraceEvent* trace_event) {
- HEAP_PROFILER_SCOPED_IGNORE;
- AutoLock thread_info_lock(thread_info_lock_);
-
- // The caller should translate TRACE_EVENT_PHASE_COMPLETE to
- // TRACE_EVENT_PHASE_BEGIN or TRACE_EVENT_END.
- DCHECK(phase != TRACE_EVENT_PHASE_COMPLETE);
-
- TimeDelta duration;
- int thread_id =
- trace_event ? trace_event->thread_id() : PlatformThread::CurrentId();
- if (phase == TRACE_EVENT_PHASE_END) {
- duration = timestamp - thread_event_start_times_[thread_id].top();
- thread_event_start_times_[thread_id].pop();
- }
-
- std::string thread_name = thread_names_[thread_id];
- if (thread_colors_.find(thread_name) == thread_colors_.end()) {
- size_t next_color = (thread_colors_.size() % 6) + 1;
- thread_colors_[thread_name] = next_color;
- }
-
- std::ostringstream log;
- log << base::StringPrintf("%s: \x1b[0;3%dm", thread_name.c_str(),
- thread_colors_[thread_name]);
-
- size_t depth = 0;
- auto it = thread_event_start_times_.find(thread_id);
- if (it != thread_event_start_times_.end())
- depth = it->second.size();
-
- for (size_t i = 0; i < depth; ++i)
- log << "| ";
-
- if (trace_event)
- trace_event->AppendPrettyPrinted(&log);
- if (phase == TRACE_EVENT_PHASE_END)
- log << base::StringPrintf(" (%.3f ms)", duration.InMillisecondsF());
-
- log << "\x1b[0;m";
-
- if (phase == TRACE_EVENT_PHASE_BEGIN)
- thread_event_start_times_[thread_id].push(timestamp);
-
- return log.str();
-}
-
-void TraceLog::EndFilteredEvent(const unsigned char* category_group_enabled,
- const char* name,
- TraceEventHandle handle) {
- const char* category_name = GetCategoryGroupName(category_group_enabled);
- ForEachCategoryFilter(
- category_group_enabled,
- [name, category_name](TraceEventFilter* trace_event_filter) {
- trace_event_filter->EndEvent(category_name, name);
- });
-}
-
-void TraceLog::UpdateTraceEventDuration(
- const unsigned char* category_group_enabled,
- const char* name,
- TraceEventHandle handle) {
- char category_group_enabled_local = *category_group_enabled;
- if (!category_group_enabled_local)
- return;
-
- UpdateTraceEventDurationExplicit(category_group_enabled, name, handle,
- OffsetNow(), ThreadNow());
-}
-
-void TraceLog::UpdateTraceEventDurationExplicit(
- const unsigned char* category_group_enabled,
- const char* name,
- TraceEventHandle handle,
- const TimeTicks& now,
- const ThreadTicks& thread_now) {
- char category_group_enabled_local = *category_group_enabled;
- if (!category_group_enabled_local)
- return;
-
- // Avoid re-entrance of AddTraceEvent. This may happen in GPU process when
- // ECHO_TO_CONSOLE is enabled: AddTraceEvent -> LOG(ERROR) ->
- // GpuProcessLogMessageHandler -> PostPendingTask -> TRACE_EVENT ...
- if (thread_is_in_trace_event_.Get())
- return;
- AutoThreadLocalBoolean thread_is_in_trace_event(&thread_is_in_trace_event_);
-
- std::string console_message;
- if (category_group_enabled_local & TraceCategory::ENABLED_FOR_RECORDING) {
- AddTraceEventOverrideCallback trace_event_override =
- reinterpret_cast<AddTraceEventOverrideCallback>(
- subtle::NoBarrier_Load(&trace_event_override_));
-
- // If we send events off to an override instead of the TraceBuffer,
- // we don't have way of updating the prior event so we'll emit a
- // separate _END event instead.
- if (trace_event_override) {
- TraceEvent new_trace_event;
- new_trace_event.Initialize(
- static_cast<int>(base::PlatformThread::CurrentId()), now, thread_now,
- TRACE_EVENT_PHASE_END, category_group_enabled, name,
- trace_event_internal::kGlobalScope,
- trace_event_internal::kNoId /* id */,
- trace_event_internal::kNoId /* bind_id */, 0, nullptr, nullptr,
- nullptr, nullptr, TRACE_EVENT_FLAG_NONE);
- trace_event_override(new_trace_event);
- return;
- }
-
- OptionalAutoLock lock(&lock_);
-
- TraceEvent* trace_event = GetEventByHandleInternal(handle, &lock);
- if (trace_event) {
- DCHECK(trace_event->phase() == TRACE_EVENT_PHASE_COMPLETE);
- // TEMP(oysteine) to debug crbug.com/638744
- if (trace_event->duration().ToInternalValue() != -1) {
- DVLOG(1) << "TraceHandle: chunk_seq " << handle.chunk_seq
- << ", chunk_index " << handle.chunk_index << ", event_index "
- << handle.event_index;
-
- std::string serialized_event;
- trace_event->AppendAsJSON(&serialized_event, ArgumentFilterPredicate());
- DVLOG(1) << "TraceEvent: " << serialized_event;
- lock_.AssertAcquired();
- }
-
- trace_event->UpdateDuration(now, thread_now);
-#if defined(OS_ANDROID)
- trace_event->SendToATrace();
-#endif
- }
-
- if (trace_options() & kInternalEchoToConsole) {
- console_message =
- EventToConsoleMessage(TRACE_EVENT_PHASE_END, now, trace_event);
- }
- }
-
- if (!console_message.empty())
- LOG(ERROR) << console_message;
-
- if (category_group_enabled_local & TraceCategory::ENABLED_FOR_FILTERING)
- EndFilteredEvent(category_group_enabled, name, handle);
-}
-
-uint64_t TraceLog::MangleEventId(uint64_t id) {
- return id ^ process_id_hash_;
-}
-
-void TraceLog::AddMetadataEventsWhileLocked() {
- lock_.AssertAcquired();
-
- // Move metadata added by |AddMetadataEvent| into the trace log.
- while (!metadata_events_.empty()) {
- TraceEvent* event = AddEventToThreadSharedChunkWhileLocked(nullptr, false);
- event->MoveFrom(std::move(metadata_events_.back()));
- metadata_events_.pop_back();
- }
-
-#if !defined(OS_NACL) // NaCl shouldn't expose the process id.
- InitializeMetadataEvent(
- AddEventToThreadSharedChunkWhileLocked(nullptr, false), 0, "num_cpus",
- "number", base::SysInfo::NumberOfProcessors());
-#endif
-
- int current_thread_id = static_cast<int>(base::PlatformThread::CurrentId());
- if (process_sort_index_ != 0) {
- InitializeMetadataEvent(
- AddEventToThreadSharedChunkWhileLocked(nullptr, false),
- current_thread_id, "process_sort_index", "sort_index",
- process_sort_index_);
- }
-
- if (!process_name_.empty()) {
- InitializeMetadataEvent(
- AddEventToThreadSharedChunkWhileLocked(nullptr, false),
- current_thread_id, "process_name", "name", process_name_);
- }
-
- TimeDelta process_uptime = TRACE_TIME_NOW() - process_creation_time_;
- InitializeMetadataEvent(
- AddEventToThreadSharedChunkWhileLocked(nullptr, false), current_thread_id,
- "process_uptime_seconds", "uptime", process_uptime.InSeconds());
-
-#if defined(OS_ANDROID)
- InitializeMetadataEvent(
- AddEventToThreadSharedChunkWhileLocked(nullptr, false), current_thread_id,
- "chrome_library_address", "start_address",
- base::StringPrintf("%p", &__executable_start));
-#endif
-
- if (!process_labels_.empty()) {
- std::vector<base::StringPiece> labels;
- for (const auto& it : process_labels_)
- labels.push_back(it.second);
- InitializeMetadataEvent(
- AddEventToThreadSharedChunkWhileLocked(nullptr, false),
- current_thread_id, "process_labels", "labels",
- base::JoinString(labels, ","));
- }
-
- // Thread sort indices.
- for (const auto& it : thread_sort_indices_) {
- if (it.second == 0)
- continue;
- InitializeMetadataEvent(
- AddEventToThreadSharedChunkWhileLocked(nullptr, false), it.first,
- "thread_sort_index", "sort_index", it.second);
- }
-
- // Thread names.
- AutoLock thread_info_lock(thread_info_lock_);
- for (const auto& it : thread_names_) {
- if (it.second.empty())
- continue;
- InitializeMetadataEvent(
- AddEventToThreadSharedChunkWhileLocked(nullptr, false), it.first,
- "thread_name", "name", it.second);
- }
-
- // If buffer is full, add a metadata record to report this.
- if (!buffer_limit_reached_timestamp_.is_null()) {
- InitializeMetadataEvent(
- AddEventToThreadSharedChunkWhileLocked(nullptr, false),
- current_thread_id, "trace_buffer_overflowed", "overflowed_at_ts",
- buffer_limit_reached_timestamp_);
- }
-}
-
-TraceEvent* TraceLog::GetEventByHandle(TraceEventHandle handle) {
- return GetEventByHandleInternal(handle, nullptr);
-}
-
-TraceEvent* TraceLog::GetEventByHandleInternal(TraceEventHandle handle,
- OptionalAutoLock* lock) {
- if (!handle.chunk_seq)
- return nullptr;
-
- DCHECK(handle.chunk_seq);
- DCHECK(handle.chunk_index <= TraceBufferChunk::kMaxChunkIndex);
- DCHECK(handle.event_index <= TraceBufferChunk::kTraceBufferChunkSize - 1);
-
- if (thread_local_event_buffer_.Get()) {
- TraceEvent* trace_event =
- thread_local_event_buffer_.Get()->GetEventByHandle(handle);
- if (trace_event)
- return trace_event;
- }
-
- // The event has been out-of-control of the thread local buffer.
- // Try to get the event from the main buffer with a lock.
- if (lock)
- lock->EnsureAcquired();
-
- if (thread_shared_chunk_ &&
- handle.chunk_index == thread_shared_chunk_index_) {
- return handle.chunk_seq == thread_shared_chunk_->seq()
- ? thread_shared_chunk_->GetEventAt(handle.event_index)
- : nullptr;
- }
-
- return logged_events_->GetEventByHandle(handle);
-}
-
-void TraceLog::SetProcessID(int process_id) {
- process_id_ = process_id;
- // Create a FNV hash from the process ID for XORing.
- // See http://isthe.com/chongo/tech/comp/fnv/ for algorithm details.
- const unsigned long long kOffsetBasis = 14695981039346656037ull;
- const unsigned long long kFnvPrime = 1099511628211ull;
- const unsigned long long pid = static_cast<unsigned long long>(process_id_);
- process_id_hash_ = (kOffsetBasis ^ pid) * kFnvPrime;
-}
-
-void TraceLog::SetProcessSortIndex(int sort_index) {
- AutoLock lock(lock_);
- process_sort_index_ = sort_index;
-}
-
-void TraceLog::UpdateProcessLabel(int label_id,
- const std::string& current_label) {
- if (!current_label.length())
- return RemoveProcessLabel(label_id);
-
- AutoLock lock(lock_);
- process_labels_[label_id] = current_label;
-}
-
-void TraceLog::RemoveProcessLabel(int label_id) {
- AutoLock lock(lock_);
- process_labels_.erase(label_id);
-}
-
-void TraceLog::SetThreadSortIndex(PlatformThreadId thread_id, int sort_index) {
- AutoLock lock(lock_);
- thread_sort_indices_[static_cast<int>(thread_id)] = sort_index;
-}
-
-void TraceLog::SetTimeOffset(TimeDelta offset) {
- time_offset_ = offset;
-}
-
-size_t TraceLog::GetObserverCountForTest() const {
- return enabled_state_observer_list_.size();
-}
-
-void TraceLog::SetCurrentThreadBlocksMessageLoop() {
- thread_blocks_message_loop_.Set(true);
- // This will flush the thread local buffer.
- delete thread_local_event_buffer_.Get();
-}
-
-TraceBuffer* TraceLog::CreateTraceBuffer() {
- HEAP_PROFILER_SCOPED_IGNORE;
- InternalTraceOptions options = trace_options();
- if (options & kInternalRecordContinuously) {
- return TraceBuffer::CreateTraceBufferRingBuffer(
- kTraceEventRingBufferChunks);
- }
- if (options & kInternalEchoToConsole) {
- return TraceBuffer::CreateTraceBufferRingBuffer(
- kEchoToConsoleTraceEventBufferChunks);
- }
- if (options & kInternalRecordAsMuchAsPossible) {
- return TraceBuffer::CreateTraceBufferVectorOfSize(
- kTraceEventVectorBigBufferChunks);
- }
- return TraceBuffer::CreateTraceBufferVectorOfSize(
- kTraceEventVectorBufferChunks);
-}
-
-void TraceLog::SetTraceBufferForTesting(
- std::unique_ptr<TraceBuffer> trace_buffer) {
- AutoLock lock(lock_);
- logged_events_ = std::move(trace_buffer);
-}
-
-void ConvertableToTraceFormat::EstimateTraceMemoryOverhead(
- TraceEventMemoryOverhead* overhead) {
- overhead->Add(TraceEventMemoryOverhead::kConvertableToTraceFormat,
- sizeof(*this));
-}
-
-void TraceLog::AddAsyncEnabledStateObserver(
- WeakPtr<AsyncEnabledStateObserver> listener) {
- AutoLock lock(lock_);
- async_observers_.insert(
- std::make_pair(listener.get(), RegisteredAsyncObserver(listener)));
-}
-
-void TraceLog::RemoveAsyncEnabledStateObserver(
- AsyncEnabledStateObserver* listener) {
- AutoLock lock(lock_);
- async_observers_.erase(listener);
-}
-
-bool TraceLog::HasAsyncEnabledStateObserver(
- AsyncEnabledStateObserver* listener) const {
- AutoLock lock(lock_);
- return ContainsKey(async_observers_, listener);
-}
-
-} // namespace trace_event
-} // namespace base
-
-namespace trace_event_internal {
-
-ScopedTraceBinaryEfficient::ScopedTraceBinaryEfficient(
- const char* category_group,
- const char* name) {
- // The single atom works because for now the category_group can only be "gpu".
- DCHECK_EQ(strcmp(category_group, "gpu"), 0);
- static TRACE_EVENT_API_ATOMIC_WORD atomic = 0;
- INTERNAL_TRACE_EVENT_GET_CATEGORY_INFO_CUSTOM_VARIABLES(
- category_group, atomic, category_group_enabled_);
- name_ = name;
- if (*category_group_enabled_) {
- event_handle_ =
- TRACE_EVENT_API_ADD_TRACE_EVENT_WITH_THREAD_ID_AND_TIMESTAMP(
- TRACE_EVENT_PHASE_COMPLETE, category_group_enabled_, name,
- trace_event_internal::kGlobalScope, // scope
- trace_event_internal::kNoId, // id
- static_cast<int>(base::PlatformThread::CurrentId()), // thread_id
- TRACE_TIME_TICKS_NOW(), trace_event_internal::kZeroNumArgs, nullptr,
- nullptr, nullptr, nullptr, TRACE_EVENT_FLAG_NONE);
- }
-}
-
-ScopedTraceBinaryEfficient::~ScopedTraceBinaryEfficient() {
- if (*category_group_enabled_) {
- TRACE_EVENT_API_UPDATE_TRACE_EVENT_DURATION(category_group_enabled_, name_,
- event_handle_);
- }
-}
-
-} // namespace trace_event_internal
diff --git a/base/trace_event/trace_log.h b/base/trace_event/trace_log.h
deleted file mode 100644
index e480323..0000000
--- a/base/trace_event/trace_log.h
+++ /dev/null
@@ -1,521 +0,0 @@
-// Copyright 2015 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_LOG_H_
-#define BASE_TRACE_EVENT_TRACE_LOG_H_
-
-#include <stddef.h>
-#include <stdint.h>
-
-#include <memory>
-#include <string>
-#include <unordered_map>
-#include <vector>
-
-#include "base/atomicops.h"
-#include "base/containers/stack.h"
-#include "base/gtest_prod_util.h"
-#include "base/macros.h"
-#include "base/time/time_override.h"
-#include "base/trace_event/memory_dump_provider.h"
-#include "base/trace_event/trace_config.h"
-#include "base/trace_event/trace_event_impl.h"
-#include "build_config.h"
-
-namespace base {
-
-class MessageLoop;
-class RefCountedString;
-
-template <typename T>
-class NoDestructor;
-
-namespace trace_event {
-
-struct TraceCategory;
-class TraceBuffer;
-class TraceBufferChunk;
-class TraceEvent;
-class TraceEventFilter;
-class TraceEventMemoryOverhead;
-
-struct BASE_EXPORT TraceLogStatus {
- TraceLogStatus();
- ~TraceLogStatus();
- uint32_t event_capacity;
- uint32_t event_count;
-};
-
-class BASE_EXPORT TraceLog : public MemoryDumpProvider {
- public:
- // Argument passed to TraceLog::SetEnabled.
- enum Mode : uint8_t {
- // Enables normal tracing (recording trace events in the trace buffer).
- RECORDING_MODE = 1 << 0,
-
- // Trace events are enabled just for filtering but not for recording. Only
- // event filters config of |trace_config| argument is used.
- FILTERING_MODE = 1 << 1
- };
-
- static TraceLog* GetInstance();
-
- // Get set of known category groups. This can change as new code paths are
- // reached. The known category groups are inserted into |category_groups|.
- void GetKnownCategoryGroups(std::vector<std::string>* category_groups);
-
- // Retrieves a copy (for thread-safety) of the current TraceConfig.
- TraceConfig GetCurrentTraceConfig() const;
-
- // Initializes the thread-local event buffer, if not already initialized and
- // if the current thread supports that (has a message loop).
- void InitializeThreadLocalEventBufferIfSupported();
-
- // See TraceConfig comments for details on how to control which categories
- // will be traced. SetDisabled must be called distinctly for each mode that is
- // enabled. If tracing has already been enabled for recording, category filter
- // (enabled and disabled categories) will be merged into the current category
- // filter. Enabling RECORDING_MODE does not enable filters. Trace event
- // filters will be used only if FILTERING_MODE is set on |modes_to_enable|.
- // Conversely to RECORDING_MODE, FILTERING_MODE doesn't support upgrading,
- // i.e. filters can only be enabled if not previously enabled.
- void SetEnabled(const TraceConfig& trace_config, uint8_t modes_to_enable);
-
- // TODO(ssid): Remove the default SetEnabled and IsEnabled. They should take
- // Mode as argument.
-
- // Disables tracing for all categories for the specified |modes_to_disable|
- // only. Only RECORDING_MODE is taken as default |modes_to_disable|.
- void SetDisabled();
- void SetDisabled(uint8_t modes_to_disable);
-
- // Returns true if TraceLog is enabled on recording mode.
- // Note: Returns false even if FILTERING_MODE is enabled.
- bool IsEnabled() { return enabled_modes_ & RECORDING_MODE; }
-
- // Returns a bitmap of enabled modes from TraceLog::Mode.
- uint8_t enabled_modes() { return enabled_modes_; }
-
- // The number of times we have begun recording traces. If tracing is off,
- // returns -1. If tracing is on, then it returns the number of times we have
- // recorded a trace. By watching for this number to increment, you can
- // passively discover when a new trace has begun. This is then used to
- // implement the TRACE_EVENT_IS_NEW_TRACE() primitive.
- int GetNumTracesRecorded();
-
-#if defined(OS_ANDROID)
- void StartATrace();
- void StopATrace();
- void AddClockSyncMetadataEvent();
-#endif
-
- // Enabled state listeners give a callback when tracing is enabled or
- // disabled. This can be used to tie into other library's tracing systems
- // on-demand.
- class BASE_EXPORT EnabledStateObserver {
- public:
- virtual ~EnabledStateObserver() = default;
-
- // Called just after the tracing system becomes enabled, outside of the
- // |lock_|. TraceLog::IsEnabled() is true at this point.
- virtual void OnTraceLogEnabled() = 0;
-
- // Called just after the tracing system disables, outside of the |lock_|.
- // TraceLog::IsEnabled() is false at this point.
- virtual void OnTraceLogDisabled() = 0;
- };
- void AddEnabledStateObserver(EnabledStateObserver* listener);
- void RemoveEnabledStateObserver(EnabledStateObserver* listener);
- bool HasEnabledStateObserver(EnabledStateObserver* listener) const;
-
- // Asynchronous enabled state listeners. When tracing is enabled or disabled,
- // for each observer, a task for invoking its appropriate callback is posted
- // to the thread from which AddAsyncEnabledStateObserver() was called. This
- // allows the observer to be safely destroyed, provided that it happens on the
- // same thread that invoked AddAsyncEnabledStateObserver().
- class BASE_EXPORT AsyncEnabledStateObserver {
- public:
- virtual ~AsyncEnabledStateObserver() = default;
-
- // Posted just after the tracing system becomes enabled, outside |lock_|.
- // TraceLog::IsEnabled() is true at this point.
- virtual void OnTraceLogEnabled() = 0;
-
- // Posted just after the tracing system becomes disabled, outside |lock_|.
- // TraceLog::IsEnabled() is false at this point.
- virtual void OnTraceLogDisabled() = 0;
- };
- void AddAsyncEnabledStateObserver(
- WeakPtr<AsyncEnabledStateObserver> listener);
- void RemoveAsyncEnabledStateObserver(AsyncEnabledStateObserver* listener);
- bool HasAsyncEnabledStateObserver(AsyncEnabledStateObserver* listener) const;
-
- TraceLogStatus GetStatus() const;
- bool BufferIsFull() const;
-
- // Computes an estimate of the size of the TraceLog including all the retained
- // objects.
- void EstimateTraceMemoryOverhead(TraceEventMemoryOverhead* overhead);
-
- void SetArgumentFilterPredicate(
- const ArgumentFilterPredicate& argument_filter_predicate);
-
- // Flush all collected events to the given output callback. The callback will
- // be called one or more times either synchronously or asynchronously from
- // the current thread with IPC-bite-size chunks. The string format is
- // undefined. Use TraceResultBuffer to convert one or more trace strings to
- // JSON. The callback can be null if the caller doesn't want any data.
- // Due to the implementation of thread-local buffers, flush can't be
- // done when tracing is enabled. If called when tracing is enabled, the
- // callback will be called directly with (empty_string, false) to indicate
- // the end of this unsuccessful flush. Flush does the serialization
- // on the same thread if the caller doesn't set use_worker_thread explicitly.
- typedef base::Callback<void(const scoped_refptr<base::RefCountedString>&,
- bool has_more_events)> OutputCallback;
- void Flush(const OutputCallback& cb, bool use_worker_thread = false);
-
- // Cancels tracing and discards collected data.
- void CancelTracing(const OutputCallback& cb);
-
- typedef void (*AddTraceEventOverrideCallback)(const TraceEvent&);
- // The callback will be called up until the point where the flush is
- // finished, i.e. must be callable until OutputCallback is called with
- // has_more_events==false.
- void SetAddTraceEventOverride(const AddTraceEventOverrideCallback& override);
-
- // Called by TRACE_EVENT* macros, don't call this directly.
- // The name parameter is a category group for example:
- // TRACE_EVENT0("renderer,webkit", "WebViewImpl::HandleInputEvent")
- static const unsigned char* GetCategoryGroupEnabled(const char* name);
- static const char* GetCategoryGroupName(
- const unsigned char* category_group_enabled);
-
- // 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,
- 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,
- 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);
- TraceEventHandle AddTraceEventWithProcessId(
- char phase,
- const unsigned char* category_group_enabled,
- const char* name,
- const char* scope,
- unsigned long long id,
- int process_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 AddTraceEventWithThreadIdAndTimestamp(
- char phase,
- const unsigned char* category_group_enabled,
- const char* name,
- const char* scope,
- unsigned long long id,
- int thread_id,
- const TimeTicks& timestamp,
- 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,
- 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 TimeTicks& timestamp,
- 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,
- 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,
- TraceEventHandle handle);
-
- void UpdateTraceEventDurationExplicit(
- const unsigned char* category_group_enabled,
- const char* name,
- TraceEventHandle handle,
- const TimeTicks& now,
- const ThreadTicks& thread_now);
-
- void EndFilteredEvent(const unsigned char* category_group_enabled,
- const char* name,
- TraceEventHandle handle);
-
- int process_id() const { return process_id_; }
-
- uint64_t MangleEventId(uint64_t id);
-
- // Exposed for unittesting:
-
- // Testing factory for TraceEventFilter.
- typedef std::unique_ptr<TraceEventFilter> (*FilterFactoryForTesting)(
- const std::string& /* predicate_name */);
- void SetFilterFactoryForTesting(FilterFactoryForTesting factory) {
- filter_factory_for_testing_ = factory;
- }
-
- // Allows clearing up our singleton instance.
- static void ResetForTesting();
-
- // Allow tests to inspect TraceEvents.
- TraceEvent* GetEventByHandle(TraceEventHandle handle);
-
- void SetProcessID(int process_id);
-
- // Process sort indices, if set, override the order of a process will appear
- // relative to other processes in the trace viewer. Processes are sorted first
- // on their sort index, ascending, then by their name, and then tid.
- void SetProcessSortIndex(int sort_index);
-
- // Sets the name of the process.
- void set_process_name(const std::string& process_name) {
- AutoLock lock(lock_);
- process_name_ = process_name;
- }
-
- bool IsProcessNameEmpty() const { return process_name_.empty(); }
-
- // Processes can have labels in addition to their names. Use labels, for
- // instance, to list out the web page titles that a process is handling.
- void UpdateProcessLabel(int label_id, const std::string& current_label);
- void RemoveProcessLabel(int label_id);
-
- // Thread sort indices, if set, override the order of a thread will appear
- // within its process in the trace viewer. Threads are sorted first on their
- // sort index, ascending, then by their name, and then tid.
- void SetThreadSortIndex(PlatformThreadId thread_id, int sort_index);
-
- // Allow setting an offset between the current TimeTicks time and the time
- // that should be reported.
- void SetTimeOffset(TimeDelta offset);
-
- size_t GetObserverCountForTest() const;
-
- // Call this method if the current thread may block the message loop to
- // prevent the thread from using the thread-local buffer because the thread
- // may not handle the flush request in time causing lost of unflushed events.
- void SetCurrentThreadBlocksMessageLoop();
-
- // Replaces |logged_events_| with a new TraceBuffer for testing.
- void SetTraceBufferForTesting(std::unique_ptr<TraceBuffer> trace_buffer);
-
- private:
- typedef unsigned int InternalTraceOptions;
-
- FRIEND_TEST_ALL_PREFIXES(TraceEventTestFixture,
- TraceBufferRingBufferGetReturnChunk);
- FRIEND_TEST_ALL_PREFIXES(TraceEventTestFixture,
- TraceBufferRingBufferHalfIteration);
- FRIEND_TEST_ALL_PREFIXES(TraceEventTestFixture,
- TraceBufferRingBufferFullIteration);
- FRIEND_TEST_ALL_PREFIXES(TraceEventTestFixture, TraceBufferVectorReportFull);
- FRIEND_TEST_ALL_PREFIXES(TraceEventTestFixture,
- ConvertTraceConfigToInternalOptions);
- FRIEND_TEST_ALL_PREFIXES(TraceEventTestFixture,
- TraceRecordAsMuchAsPossibleMode);
-
- friend class base::NoDestructor<TraceLog>;
-
- // MemoryDumpProvider implementation.
- bool OnMemoryDump(const MemoryDumpArgs& args,
- ProcessMemoryDump* pmd) override;
-
- // Enable/disable each category group based on the current mode_,
- // category_filter_ and event_filters_enabled_.
- // Enable the category group in the recording mode if category_filter_ matches
- // the category group, is not null. Enable category for filtering if any
- // filter in event_filters_enabled_ enables it.
- void UpdateCategoryRegistry();
- void UpdateCategoryState(TraceCategory* category);
-
- void CreateFiltersForTraceConfig();
-
- InternalTraceOptions GetInternalOptionsFromTraceConfig(
- const TraceConfig& config);
-
- class ThreadLocalEventBuffer;
- class OptionalAutoLock;
- struct RegisteredAsyncObserver;
-
- TraceLog();
- ~TraceLog() override;
- void AddMetadataEventsWhileLocked();
-
- InternalTraceOptions trace_options() const {
- return static_cast<InternalTraceOptions>(
- subtle::NoBarrier_Load(&trace_options_));
- }
-
- TraceBuffer* trace_buffer() const { return logged_events_.get(); }
- TraceBuffer* CreateTraceBuffer();
-
- std::string EventToConsoleMessage(unsigned char phase,
- const TimeTicks& timestamp,
- TraceEvent* trace_event);
-
- TraceEvent* AddEventToThreadSharedChunkWhileLocked(TraceEventHandle* handle,
- bool check_buffer_is_full);
- void CheckIfBufferIsFullWhileLocked();
- void SetDisabledWhileLocked(uint8_t modes);
-
- TraceEvent* GetEventByHandleInternal(TraceEventHandle handle,
- OptionalAutoLock* lock);
-
- void FlushInternal(const OutputCallback& cb,
- bool use_worker_thread,
- bool discard_events);
-
- // |generation| is used in the following callbacks to check if the callback
- // is called for the flush of the current |logged_events_|.
- void FlushCurrentThread(int generation, bool discard_events);
- // Usually it runs on a different thread.
- static void ConvertTraceEventsToTraceFormat(
- std::unique_ptr<TraceBuffer> logged_events,
- const TraceLog::OutputCallback& flush_output_callback,
- const ArgumentFilterPredicate& argument_filter_predicate);
- void FinishFlush(int generation, bool discard_events);
- void OnFlushTimeout(int generation, bool discard_events);
-
- int generation() const {
- return static_cast<int>(subtle::NoBarrier_Load(&generation_));
- }
- bool CheckGeneration(int generation) const {
- return generation == this->generation();
- }
- void UseNextTraceBuffer();
-
- TimeTicks OffsetNow() const {
- // This should be TRACE_TIME_TICKS_NOW but include order makes that hard.
- return OffsetTimestamp(base::subtle::TimeTicksNowIgnoringOverride());
- }
- TimeTicks OffsetTimestamp(const TimeTicks& timestamp) const {
- return timestamp - time_offset_;
- }
-
- // Internal representation of trace options since we store the currently used
- // trace option as an AtomicWord.
- static const InternalTraceOptions kInternalNone;
- static const InternalTraceOptions kInternalRecordUntilFull;
- static const InternalTraceOptions kInternalRecordContinuously;
- static const InternalTraceOptions kInternalEchoToConsole;
- static const InternalTraceOptions kInternalRecordAsMuchAsPossible;
- static const InternalTraceOptions kInternalEnableArgumentFilter;
-
- // This lock protects TraceLog member accesses (except for members protected
- // by thread_info_lock_) from arbitrary threads.
- mutable Lock lock_;
- // This lock protects accesses to thread_names_, thread_event_start_times_
- // and thread_colors_.
- Lock thread_info_lock_;
- uint8_t enabled_modes_; // See TraceLog::Mode.
- int num_traces_recorded_;
- std::unique_ptr<TraceBuffer> logged_events_;
- std::vector<std::unique_ptr<TraceEvent>> metadata_events_;
- bool dispatching_to_observer_list_;
- std::vector<EnabledStateObserver*> enabled_state_observer_list_;
- std::map<AsyncEnabledStateObserver*, RegisteredAsyncObserver>
- async_observers_;
-
- std::string process_name_;
- std::unordered_map<int, std::string> process_labels_;
- int process_sort_index_;
- std::unordered_map<int, int> thread_sort_indices_;
- std::unordered_map<int, std::string> thread_names_;
- base::Time process_creation_time_;
-
- // The following two maps are used only when ECHO_TO_CONSOLE.
- std::unordered_map<int, base::stack<TimeTicks>> thread_event_start_times_;
- std::unordered_map<std::string, int> thread_colors_;
-
- TimeTicks buffer_limit_reached_timestamp_;
-
- // XORed with TraceID to make it unlikely to collide with other processes.
- unsigned long long process_id_hash_;
-
- int process_id_;
-
- TimeDelta time_offset_;
-
- subtle::AtomicWord /* Options */ trace_options_;
-
- TraceConfig trace_config_;
- TraceConfig::EventFilters enabled_event_filters_;
-
- ThreadLocalPointer<ThreadLocalEventBuffer> thread_local_event_buffer_;
- ThreadLocalBoolean thread_blocks_message_loop_;
- ThreadLocalBoolean thread_is_in_trace_event_;
-
- // Contains the message loops of threads that have had at least one event
- // added into the local event buffer. Not using SingleThreadTaskRunner
- // because we need to know the life time of the message loops.
- hash_set<MessageLoop*> thread_message_loops_;
-
- // For events which can't be added into the thread local buffer, e.g. events
- // from threads without a message loop.
- std::unique_ptr<TraceBufferChunk> thread_shared_chunk_;
- size_t thread_shared_chunk_index_;
-
- // Set when asynchronous Flush is in progress.
- OutputCallback flush_output_callback_;
- scoped_refptr<SingleThreadTaskRunner> flush_task_runner_;
- ArgumentFilterPredicate argument_filter_predicate_;
- subtle::AtomicWord generation_;
- bool use_worker_thread_;
- subtle::AtomicWord trace_event_override_;
-
- FilterFactoryForTesting filter_factory_for_testing_;
-
- DISALLOW_COPY_AND_ASSIGN(TraceLog);
-};
-
-} // namespace trace_event
-} // namespace base
-
-#endif // BASE_TRACE_EVENT_TRACE_LOG_H_
diff --git a/base/trace_event/trace_log_constants.cc b/base/trace_event/trace_log_constants.cc
deleted file mode 100644
index 65dca2e..0000000
--- a/base/trace_event/trace_log_constants.cc
+++ /dev/null
@@ -1,26 +0,0 @@
-// Copyright (c) 2013 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_log.h"
-
-namespace base {
-namespace trace_event {
-
-// Constant used by TraceLog's internal implementation of trace_option.
-const TraceLog::InternalTraceOptions
- TraceLog::kInternalNone = 0;
-const TraceLog::InternalTraceOptions
- TraceLog::kInternalRecordUntilFull = 1 << 0;
-const TraceLog::InternalTraceOptions
- TraceLog::kInternalRecordContinuously = 1 << 1;
-// 1 << 2 is reserved for the DEPRECATED kInternalEnableSampling. DO NOT USE.
-const TraceLog::InternalTraceOptions
- TraceLog::kInternalEchoToConsole = 1 << 3;
-const TraceLog::InternalTraceOptions
- TraceLog::kInternalRecordAsMuchAsPossible = 1 << 4;
-const TraceLog::InternalTraceOptions
- TraceLog::kInternalEnableArgumentFilter = 1 << 5;
-
-} // namespace trace_event
-} // namespace base
diff --git a/base/trace_event/tracing_agent.cc b/base/trace_event/tracing_agent.cc
deleted file mode 100644
index e48feff..0000000
--- a/base/trace_event/tracing_agent.cc
+++ /dev/null
@@ -1,24 +0,0 @@
-// Copyright 2015 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/tracing_agent.h"
-
-namespace base {
-namespace trace_event {
-
-TracingAgent::~TracingAgent() = default;
-
-bool TracingAgent::SupportsExplicitClockSync() {
- return false;
-}
-
-void TracingAgent::RecordClockSyncMarker(
- const std::string& sync_id,
- RecordClockSyncMarkerCallback callback) {
- DCHECK(SupportsExplicitClockSync());
-}
-
-
-} // namespace trace_event
-} // namespace base
diff --git a/base/trace_event/tracing_agent.h b/base/trace_event/tracing_agent.h
deleted file mode 100644
index f818457..0000000
--- a/base/trace_event/tracing_agent.h
+++ /dev/null
@@ -1,96 +0,0 @@
-// Copyright 2015 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_TRACING_AGENT_H_
-#define BASE_TRACE_EVENT_TRACING_AGENT_H_
-
-#include "base/base_export.h"
-#include "base/callback.h"
-#include "base/memory/ref_counted_memory.h"
-#include "base/values.h"
-
-namespace base {
-
-class TimeTicks;
-
-namespace trace_event {
-
-class TraceConfig;
-
-// A tracing agent is an entity that records its own sort of trace. Each
-// tracing method that produces its own trace log should implement this
-// interface. All tracing agents must only be controlled by TracingController.
-// Some existing examples include TracingControllerImpl for Chrome trace events,
-// DebugDaemonClient for CrOs system trace, EtwTracingAgent for Windows system
-// trace and PowerTracingAgent for BattOr power trace.
-class BASE_EXPORT TracingAgent {
- public:
- using StartAgentTracingCallback =
- base::OnceCallback<void(const std::string& agent_name, bool success)>;
- // Passing a null or empty events_str_ptr indicates that no trace data is
- // available for the specified agent.
- using StopAgentTracingCallback = base::OnceCallback<void(
- const std::string& agent_name,
- const std::string& events_label,
- const scoped_refptr<base::RefCountedString>& events_str_ptr)>;
- using RecordClockSyncMarkerCallback =
- base::OnceCallback<void(const std::string& sync_id,
- const TimeTicks& issue_ts,
- const TimeTicks& issue_end_ts)>;
-
- virtual ~TracingAgent();
-
- // Gets the name of the tracing agent. Each tracing agent's name should be
- // unique.
- virtual std::string GetTracingAgentName() = 0;
-
- // Gets the trace event label of this tracing agent. The label will be used to
- // label this agent's trace when all traces from different tracing agents are
- // combined. Multiple tracing agents could have the same label. The tracing
- // agents using the same label should not be able to run at the same time. For
- // example, ETW on Windows and CrOS system tracing both use
- // "systemTraceEvents" as the label. Those two agents never run at the same
- // time because they are for different platforms.
- virtual std::string GetTraceEventLabel() = 0;
-
- // Starts tracing on the tracing agent with the trace configuration.
- virtual void StartAgentTracing(const TraceConfig& trace_config,
- StartAgentTracingCallback callback) = 0;
-
- // Stops tracing on the tracing agent. The trace data will be passed back to
- // the TracingController via the callback.
- virtual void StopAgentTracing(StopAgentTracingCallback callback) = 0;
-
- // Checks if the tracing agent supports explicit clock synchronization.
- virtual bool SupportsExplicitClockSync();
-
- // Records a clock sync marker issued by another tracing agent. This is only
- // used if the tracing agent supports explicit clock synchronization.
- //
- // Two things need to be done:
- // 1. The issuer asks the receiver to record the clock sync marker.
- // 2. The issuer records how long the receiver takes to do the recording.
- //
- // In Chrome, the receiver thread also runs in Chrome and it will talk to the
- // real receiver entity, e.g., power monitor or Android device system, via
- // different communication methods, e.g., through USB or file reading/writing.
- // The 2nd task measures that communication latency.
- //
- // Having a reliable timing measurement for the 2nd task requires synchronous
- // function call without any cross-thread or cross-process activity. However,
- // tracing agents in Chrome run in their own threads. Therefore, the issuer
- // needs to dedicate the 2nd task to the receiver to take time measurements
- // in the receiver thread, and the receiver thread needs to pass them back to
- // the issuer in the callback.
- //
- // The assumption is that the receiver thread knows the issuer's clock, which
- // is true in Chrome because all agent threads' clocks are Chrome clock.
- virtual void RecordClockSyncMarker(const std::string& sync_id,
- RecordClockSyncMarkerCallback callback);
-};
-
-} // namespace trace_event
-} // namespace base
-
-#endif // BASE_TRACE_EVENT_TRACING_AGENT_H_
diff --git a/base/values.cc b/base/values.cc
index 085f0f0..df12c29 100644
--- a/base/values.cc
+++ b/base/values.cc
@@ -18,7 +18,6 @@
#include "base/stl_util.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
-#include "base/trace_event/memory_usage_estimator.h"
namespace base {
@@ -632,21 +631,6 @@
return *this == *other;
}
-size_t Value::EstimateMemoryUsage() const {
- switch (type_) {
- case Type::STRING:
- return base::trace_event::EstimateMemoryUsage(string_value_);
- case Type::BINARY:
- return base::trace_event::EstimateMemoryUsage(binary_value_);
- case Type::DICTIONARY:
- return base::trace_event::EstimateMemoryUsage(dict_);
- case Type::LIST:
- return base::trace_event::EstimateMemoryUsage(list_);
- default:
- return 0;
- }
-}
-
void Value::InternalMoveConstructFrom(Value&& that) {
type_ = that.type_;
diff --git a/build/gen.py b/build/gen.py
index 0534e1a..5b81ca6 100755
--- a/build/gen.py
+++ b/build/gen.py
@@ -370,36 +370,6 @@
'base/time/time.cc',
'base/timer/elapsed_timer.cc',
'base/timer/timer.cc',
- 'base/trace_event/category_registry.cc',
- 'base/trace_event/event_name_filter.cc',
- 'base/trace_event/heap_profiler_allocation_context.cc',
- 'base/trace_event/heap_profiler_allocation_context_tracker.cc',
- 'base/trace_event/heap_profiler_event_filter.cc',
- 'base/trace_event/heap_profiler_heap_dump_writer.cc',
- 'base/trace_event/heap_profiler_serialization_state.cc',
- 'base/trace_event/heap_profiler_stack_frame_deduplicator.cc',
- 'base/trace_event/heap_profiler_type_name_deduplicator.cc',
- 'base/trace_event/malloc_dump_provider.cc',
- 'base/trace_event/memory_allocator_dump.cc',
- 'base/trace_event/memory_allocator_dump_guid.cc',
- 'base/trace_event/memory_dump_manager.cc',
- 'base/trace_event/memory_dump_provider_info.cc',
- 'base/trace_event/memory_dump_request_args.cc',
- 'base/trace_event/memory_dump_scheduler.cc',
- 'base/trace_event/memory_infra_background_whitelist.cc',
- 'base/trace_event/memory_peak_detector.cc',
- 'base/trace_event/memory_usage_estimator.cc',
- 'base/trace_event/process_memory_dump.cc',
- 'base/trace_event/trace_buffer.cc',
- 'base/trace_event/trace_config.cc',
- 'base/trace_event/trace_config_category_filter.cc',
- 'base/trace_event/trace_event_argument.cc',
- 'base/trace_event/trace_event_filter.cc',
- 'base/trace_event/trace_event_impl.cc',
- 'base/trace_event/trace_event_memory_overhead.cc',
- 'base/trace_event/trace_log.cc',
- 'base/trace_event/trace_log_constants.cc',
- 'base/trace_event/tracing_agent.cc',
'base/unguessable_token.cc',
'base/value_iterators.cc',
'base/values.cc',