gecko-dev/dom/base/DocGroup.cpp
Tarek Ziadé 90bafd1f42 Bug 1452580 - remove RELEASE_OR_BETA defines for PerformanceCounter usage - r=baku,erahm,farre
PerformanceCounters are currently disabled in two ways:

- a preference that's off by default "dom.performance.enable_scheduler_timing"
- calls made only for nightly using #ifndef RELEASE_OR_BETA

In order to simplify the code, let's remove the #ifndef and rely only on the pref.
That will also allows us to use the feature in every version going forward.

The performance will not be impacted since the current code is already using
the (cached) pref value to determine if the counters are used.

MozReview-Commit-ID: 47t2M1O13aH

--HG--
extra : rebase_source : e129e1829f1dc37c019e50e156474c4876d6d6cb
2018-04-24 22:03:06 +02:00

181 lines
5.1 KiB
C++

/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* 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 "mozilla/dom/DocGroup.h"
#include "mozilla/dom/DOMPrefs.h"
#include "mozilla/dom/DOMTypes.h"
#include "mozilla/dom/TabGroup.h"
#include "mozilla/Telemetry.h"
#include "nsIDocShell.h"
#include "nsDOMMutationObserver.h"
#if defined(XP_WIN)
#include <processthreadsapi.h> // for GetCurrentProcessId()
#else
#include <unistd.h> // for getpid()
#endif // defined(XP_WIN)
namespace mozilla {
namespace dom {
AutoTArray<RefPtr<DocGroup>, 2>* DocGroup::sPendingDocGroups = nullptr;
/* static */ nsresult
DocGroup::GetKey(nsIPrincipal* aPrincipal, nsACString& aKey)
{
// Use GetBaseDomain() to handle things like file URIs, IP address URIs,
// etc. correctly.
nsresult rv = aPrincipal->GetBaseDomain(aKey);
if (NS_FAILED(rv)) {
// We don't really know what to do here. But we should be conservative,
// otherwise it would be possible to reorder two events incorrectly in the
// future if we interrupt at the DocGroup level, so to be safe, use an
// empty string to classify all such documents as belonging to the same
// DocGroup.
aKey.Truncate();
}
return rv;
}
void
DocGroup::RemoveDocument(nsIDocument* aDocument)
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(mDocuments.Contains(aDocument));
mDocuments.RemoveElement(aDocument);
}
DocGroup::DocGroup(TabGroup* aTabGroup, const nsACString& aKey)
: mKey(aKey), mTabGroup(aTabGroup)
{
// This method does not add itself to mTabGroup->mDocGroups as the caller does it for us.
if (mozilla::dom::DOMPrefs::SchedulerLoggingEnabled()) {
mPerformanceCounter = new mozilla::PerformanceCounter(aKey);
}
}
DocGroup::~DocGroup()
{
MOZ_ASSERT(mDocuments.IsEmpty());
if (!NS_IsMainThread()) {
nsIEventTarget* target = EventTargetFor(TaskCategory::Other);
NS_ProxyRelease("DocGroup::mReactionsStack", target, mReactionsStack.forget());
}
mTabGroup->mDocGroups.RemoveEntry(mKey);
}
PerformanceInfo
DocGroup::ReportPerformanceInfo()
{
AssertIsOnMainThread();
MOZ_ASSERT(mPerformanceCounter);
#if defined(XP_WIN)
uint32_t pid = GetCurrentProcessId();
#else
uint32_t pid = getpid();
#endif
uint64_t wid = 0;
uint64_t pwid = 0;
uint16_t count = 0;
uint64_t duration = 0;
nsCString host = NS_LITERAL_CSTRING("None");
for (const auto& document : *this) {
// grabbing the host name of the first document
nsCOMPtr<nsIDocument> doc = do_QueryInterface(document);
MOZ_ASSERT(doc);
nsCOMPtr<nsIURI> docURI = doc->GetDocumentURI();
if (!docURI) {
continue;
}
docURI->GetHost(host);
wid = doc->OuterWindowID();
// getting the top window id - if not possible
// pwid gets the same value than wid
pwid = wid;
nsPIDOMWindowInner* win = doc->GetInnerWindow();
if (win) {
nsPIDOMWindowOuter* outer = win->GetOuterWindow();
if (outer) {
nsCOMPtr<nsPIDOMWindowOuter> top = outer->GetTop();
if (top) {
pwid = top->WindowID();
}
}
}
}
duration = mPerformanceCounter->GetExecutionDuration();
FallibleTArray<CategoryDispatch> items;
// now that we have the host and window ids, let's look at the perf counters
for (uint32_t index = 0; index < (uint32_t)TaskCategory::Count; index++) {
TaskCategory category = static_cast<TaskCategory>(index);
count = mPerformanceCounter->GetDispatchCount(DispatchCategory(category));
CategoryDispatch item = CategoryDispatch(index, count);
if (!items.AppendElement(item, fallible)) {
NS_ERROR("Could not complete the operation");
return PerformanceInfo(host, pid, wid, pwid, duration, false, items);
}
}
// setting back all counters to zero
mPerformanceCounter->ResetPerformanceCounters();
return PerformanceInfo(host, pid, wid, pwid, duration, false, items);
}
nsresult
DocGroup::Dispatch(TaskCategory aCategory,
already_AddRefed<nsIRunnable>&& aRunnable)
{
if (mPerformanceCounter) {
mPerformanceCounter->IncrementDispatchCounter(DispatchCategory(aCategory));
}
return mTabGroup->DispatchWithDocGroup(aCategory, Move(aRunnable), this);
}
nsISerialEventTarget*
DocGroup::EventTargetFor(TaskCategory aCategory) const
{
return mTabGroup->EventTargetFor(aCategory);
}
AbstractThread*
DocGroup::AbstractMainThreadFor(TaskCategory aCategory)
{
MOZ_RELEASE_ASSERT(NS_IsMainThread());
return mTabGroup->AbstractMainThreadFor(aCategory);
}
bool*
DocGroup::GetValidAccessPtr()
{
return mTabGroup->GetValidAccessPtr();
}
void
DocGroup::SignalSlotChange(const HTMLSlotElement* aSlot)
{
if (mSignalSlotList.Contains(aSlot)) {
return;
}
mSignalSlotList.AppendElement(const_cast<HTMLSlotElement*>(aSlot));
if (!sPendingDocGroups) {
// Queue a mutation observer compound microtask.
nsDOMMutationObserver::QueueMutationObserverMicroTask();
sPendingDocGroups = new AutoTArray<RefPtr<DocGroup>, 2>;
}
sPendingDocGroups->AppendElement(this);
}
}
}