blob: cc9a6fe092a97857b7586d41ff26698e2c2f47d2 [file] [log] [blame]
// 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"
#include "starboard/common/string.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 || !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