tools/profiler/tasktracer/TracedTaskCommon.cpp
author Victor Porof <vporof@mozilla.com>
Mon, 14 Jan 2019 09:38:24 +0100
changeset 454319 dae7a246b32daf628361e3fce4d5f56f4cf5b177
parent 448947 6f3709b3878117466168c40affa7bca0b60cf75b
child 457693 58654f30db8e02f1776a1f3b5b158f206c35628e
permissions -rw-r--r--
Bug 1507704 - Migrate the columnpicker binding into a custom element, r=bgrins

/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#include "GeckoTaskTracerImpl.h"
#include "TracedTaskCommon.h"

// NS_ENSURE_TRUE_VOID() without the warning on the debug build.
#define ENSURE_TRUE_VOID(x)   \
  do {                        \
    if (MOZ_UNLIKELY(!(x))) { \
      return;                 \
    }                         \
  } while (0)

namespace mozilla {
namespace tasktracer {

TracedTaskCommon::TracedTaskCommon()
    : mSourceEventType(SourceEventType::Unknown),
      mSourceEventId(0),
      mParentTaskId(0),
      mTaskId(0),
      mIsTraceInfoInit(false) {}

TracedTaskCommon::~TracedTaskCommon() {}

void TracedTaskCommon::Init() {
  // Keep the following line before GetOrCreateTraceInfo() to avoid a
  // deadlock.
  uint64_t taskid = GenNewUniqueTaskId();

  TraceInfoHolder info = GetOrCreateTraceInfo();
  ENSURE_TRUE_VOID(info);

  mTaskId = taskid;
  mSourceEventId = info->mCurTraceSourceId;
  mSourceEventType = info->mCurTraceSourceType;
  mParentTaskId = info->mCurTaskId;
  mIsTraceInfoInit = true;
}

void TracedTaskCommon::DispatchTask(int aDelayTimeMs) {
  LogDispatch(mTaskId, mParentTaskId, mSourceEventId, mSourceEventType,
              aDelayTimeMs);
}

void TracedTaskCommon::DoGetTLSTraceInfo() {
  TraceInfoHolder info = GetOrCreateTraceInfo();
  ENSURE_TRUE_VOID(info);
  MOZ_ASSERT(!mIsTraceInfoInit);

  mSourceEventType = info->mCurTraceSourceType;
  mSourceEventId = info->mCurTraceSourceId;
  mTaskId = info->mCurTaskId;
  mIsTraceInfoInit = true;
}

void TracedTaskCommon::DoSetTLSTraceInfo() {
  TraceInfoHolder info = GetOrCreateTraceInfo();
  ENSURE_TRUE_VOID(info);

  if (mIsTraceInfoInit) {
    info->mCurTraceSourceId = mSourceEventId;
    info->mCurTraceSourceType = mSourceEventType;
    info->mCurTaskId = mTaskId;
  }
}

void TracedTaskCommon::ClearTLSTraceInfo() {
  TraceInfoHolder info = GetOrCreateTraceInfo();
  ENSURE_TRUE_VOID(info);

  info->mCurTraceSourceId = 0;
  info->mCurTraceSourceType = SourceEventType::Unknown;
  info->mCurTaskId = 0;
}

/**
 * Implementation of class TracedRunnable.
 */

NS_IMPL_ISUPPORTS(TracedRunnable, nsIRunnable);

TracedRunnable::TracedRunnable(already_AddRefed<nsIRunnable>&& aOriginalObj)
    : TracedTaskCommon(), mOriginalObj(std::move(aOriginalObj)) {
  Init();
  LogVirtualTablePtr(mTaskId, mSourceEventId,
                     *reinterpret_cast<uintptr_t**>(mOriginalObj.get()));
}

TracedRunnable::~TracedRunnable() {}

NS_IMETHODIMP
TracedRunnable::Run() {
  SetTLSTraceInfo();
  LogBegin(mTaskId, mSourceEventId);
  nsresult rv = mOriginalObj->Run();
  LogEnd(mTaskId, mSourceEventId);
  ClearTLSTraceInfo();

  return rv;
}

/**
 * CreateTracedRunnable() returns a TracedRunnable wrapping the original
 * nsIRunnable object, aRunnable.
 */
already_AddRefed<nsIRunnable> CreateTracedRunnable(
    already_AddRefed<nsIRunnable>&& aRunnable) {
  RefPtr<nsIRunnable> runnable = new TracedRunnable(std::move(aRunnable));
  return runnable.forget();
}

void VirtualTask::AutoRunTask::StartScope(VirtualTask* aTask) {
  mTask->SetTLSTraceInfo();
  LogBegin(mTask->mTaskId, mTask->mSourceEventId);
}

void VirtualTask::AutoRunTask::StopScope() {
  LogEnd(mTask->mTaskId, mTask->mSourceEventId);
}

}  // namespace tasktracer
}  // namespace mozilla