| Index: base/trace_event/memory_tracing_observer.cc
|
| diff --git a/base/trace_event/memory_tracing_observer.cc b/base/trace_event/memory_tracing_observer.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..3130b205f89c25f70f30c8dd11e0c02558dd3a1c
|
| --- /dev/null
|
| +++ b/base/trace_event/memory_tracing_observer.cc
|
| @@ -0,0 +1,96 @@
|
| +// 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_tracing_observer.h"
|
| +
|
| +#include "base/trace_event/memory_dump_manager.h"
|
| +#include "base/trace_event/trace_event_argument.h"
|
| +
|
| +namespace base {
|
| +namespace trace_event {
|
| +
|
| +namespace {
|
| +
|
| +const int kTraceEventNumArgs = 1;
|
| +const char* kTraceEventArgNames[] = {"dumps"};
|
| +const unsigned char kTraceEventArgTypes[] = {TRACE_VALUE_TYPE_CONVERTABLE};
|
| +
|
| +bool IsMemoryInfraTracingEnabled() {
|
| + bool enabled;
|
| + TRACE_EVENT_CATEGORY_GROUP_ENABLED(MemoryDumpManager::kTraceCategory,
|
| + &enabled);
|
| + return enabled;
|
| +}
|
| +
|
| +}; // namespace
|
| +
|
| +MemoryTracingObserver::MemoryTracingObserver(
|
| + TraceLog* trace_log,
|
| + MemoryDumpManager* memory_dump_manager)
|
| + : memory_dump_manager_(memory_dump_manager), trace_log_(trace_log) {
|
| + // If tracing was enabled before initializing MemoryDumpManager, we missed the
|
| + // OnTraceLogEnabled() event. Synthetize it so we can late-join the party.
|
| + // IsEnabled is called before adding observer to avoid calling
|
| + // OnTraceLogEnabled twice.
|
| + bool is_tracing_already_enabled = trace_log_->IsEnabled();
|
| + trace_log_->AddEnabledStateObserver(this);
|
| + if (is_tracing_already_enabled)
|
| + OnTraceLogEnabled();
|
| +}
|
| +
|
| +MemoryTracingObserver::~MemoryTracingObserver() {
|
| + trace_log_->RemoveEnabledStateObserver(this);
|
| +}
|
| +
|
| +void MemoryTracingObserver::OnTraceLogEnabled() {
|
| + if (!IsMemoryInfraTracingEnabled())
|
| + return;
|
| +
|
| + // Initialize the TraceLog for the current thread. This is to avoids that the
|
| + // TraceLog memory dump provider is registered lazily during the MDM Enable()
|
| + TraceLog::GetInstance()->InitializeThreadLocalEventBufferIfSupported();
|
| +
|
| + const TraceConfig& trace_config =
|
| + TraceLog::GetInstance()->GetCurrentTraceConfig();
|
| + const TraceConfig::MemoryDumpConfig& memory_dump_config =
|
| + trace_config.memory_dump_config();
|
| +
|
| + memory_dump_manager_->Enable(memory_dump_config);
|
| +}
|
| +
|
| +void MemoryTracingObserver::OnTraceLogDisabled() {
|
| + memory_dump_manager_->Disable();
|
| +}
|
| +
|
| +bool MemoryTracingObserver::AddDumpToTraceIfEnabled(
|
| + const MemoryDumpRequestArgs* req_args,
|
| + const ProcessId pid,
|
| + const ProcessMemoryDump* process_memory_dump) {
|
| + // If tracing has been disabled early out to avoid the cost of serializing the
|
| + // dump then ignoring the result.
|
| + if (!IsMemoryInfraTracingEnabled())
|
| + return false;
|
| +
|
| + const uint64_t dump_guid = req_args->dump_guid;
|
| +
|
| + std::unique_ptr<TracedValue> traced_value(new TracedValue);
|
| + process_memory_dump->AsValueInto(traced_value.get());
|
| + traced_value->SetString("level_of_detail", MemoryDumpLevelOfDetailToString(
|
| + req_args->level_of_detail));
|
| + const char* const event_name = MemoryDumpTypeToString(req_args->dump_type);
|
| +
|
| + std::unique_ptr<ConvertableToTraceFormat> event_value(
|
| + std::move(traced_value));
|
| + TRACE_EVENT_API_ADD_TRACE_EVENT_WITH_PROCESS_ID(
|
| + TRACE_EVENT_PHASE_MEMORY_DUMP,
|
| + TraceLog::GetCategoryGroupEnabled(MemoryDumpManager::kTraceCategory),
|
| + event_name, trace_event_internal::kGlobalScope, dump_guid, pid,
|
| + kTraceEventNumArgs, kTraceEventArgNames, kTraceEventArgTypes,
|
| + nullptr /* arg_values */, &event_value, TRACE_EVENT_FLAG_HAS_ID);
|
| +
|
| + return true;
|
| +}
|
| +
|
| +} // namespace trace_event
|
| +} // namespace base
|
|
|