gecko-dev/layout/base/LayoutTelemetryTools.cpp
Daniel Holbert ae192ec3a5 Bug 1613192: Fix non-unified build bustage in layout/{base,generic} directories. r=TYLin
Summary of the changes/reasons:

- LayoutTelemetryTools.h directly uses several types whose headers it needs to
  include. (These includes were present in its .cpp file; I'm migrating them
  from there to the .h file, and I'm adding a new include for "Saturate.h" to
  provide the SaturateUint8 type.)

- LayoutTelemetryTools.cpp needs an include for MainThreadUtils.h, to provide
  NS_IsMainThread().

- StaticPresData.cpp needs an include for ServoUtils.h, to provide
  AssertIsMainThreadOrServoFontMetricsLocked().

- ZoomConstraintsClient.h needs a forward-decl for mozilla::dom::Document since
  it uses a pointer of that type in a function-decl.

- ScrollSnap.h needs forward-decls of nsPoint/nsRect for some references to
  those types in a method signature.

- nsGridContainerFrame.cpp needs an include for nsBoxLayoutState.h since it
  uses that type (it instantiates a nsBoxLayoutState instance).

- nsPlaceholderFrame.cpp needs a "using" decl for the mozilla::dom namespace in
  order to use the un-namespace-prefixed "Element" type.

Differential Revision: https://phabricator.services.mozilla.com/D61603

--HG--
extra : moz-landing-system : lando
2020-02-04 19:34:51 +00:00

176 lines
5.9 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/layout/LayoutTelemetryTools.h"
#include "MainThreadUtils.h"
#include "mozilla/Atomics.h"
#include "mozilla/Telemetry.h"
using namespace mozilla;
using namespace mozilla::layout_telemetry;
// Returns the key name expected by telemetry. Keep to date with
// toolkits/components/telemetry/Histograms.json.
static nsLiteralCString SubsystemTelemetryKey(LayoutSubsystem aSubsystem) {
switch (aSubsystem) {
default:
MOZ_CRASH("Unexpected LayoutSubsystem value");
case LayoutSubsystem::Restyle:
return nsLiteralCString("Restyle");
case LayoutSubsystem::Reflow:
return nsLiteralCString("ReflowOther");
case LayoutSubsystem::ReflowFlex:
return nsLiteralCString("ReflowFlex");
case LayoutSubsystem::ReflowGrid:
return nsLiteralCString("ReflowGrid");
case LayoutSubsystem::ReflowTable:
return nsLiteralCString("ReflowTable");
case LayoutSubsystem::ReflowText:
return nsLiteralCString("ReflowText");
}
}
static AutoRecord* sCurrentRecord;
static FlushKind ToKind(FlushType aFlushType) {
switch (aFlushType) {
default:
MOZ_CRASH("Expected FlushType::Style or FlushType::Layout");
case FlushType::Style:
return FlushKind::Style;
case FlushType::Layout:
return FlushKind::Layout;
}
}
namespace mozilla {
namespace layout_telemetry {
Data::Data() {
PodZero(&mReqsPerFlush);
PodZero(&mFlushesPerTick);
PodZero(&mLayoutSubsystemDurationMs);
}
void Data::IncReqsPerFlush(FlushType aFlushType) {
mReqsPerFlush[ToKind(aFlushType)]++;
}
void Data::IncFlushesPerTick(FlushType aFlushType) {
mFlushesPerTick[ToKind(aFlushType)]++;
}
void Data::PingReqsPerFlushTelemetry(FlushType aFlushType) {
auto flushKind = ToKind(aFlushType);
if (flushKind == FlushKind::Layout) {
auto styleFlushReqs = mReqsPerFlush[FlushKind::Style].value();
auto layoutFlushReqs = mReqsPerFlush[FlushKind::Layout].value();
Telemetry::Accumulate(Telemetry::PRESSHELL_REQS_PER_LAYOUT_FLUSH,
NS_LITERAL_CSTRING("Style"), styleFlushReqs);
Telemetry::Accumulate(Telemetry::PRESSHELL_REQS_PER_LAYOUT_FLUSH,
NS_LITERAL_CSTRING("Layout"), layoutFlushReqs);
mReqsPerFlush[FlushKind::Style] = SaturateUint8(0);
mReqsPerFlush[FlushKind::Layout] = SaturateUint8(0);
} else {
auto styleFlushReqs = mReqsPerFlush[FlushKind::Style].value();
Telemetry::Accumulate(Telemetry::PRESSHELL_REQS_PER_STYLE_FLUSH,
styleFlushReqs);
mReqsPerFlush[FlushKind::Style] = SaturateUint8(0);
}
}
void Data::PingFlushPerTickTelemetry(FlushType aFlushType) {
auto flushKind = ToKind(aFlushType);
auto styleFlushes = mFlushesPerTick[FlushKind::Style].value();
if (styleFlushes > 0) {
Telemetry::Accumulate(Telemetry::PRESSHELL_FLUSHES_PER_TICK,
NS_LITERAL_CSTRING("Style"), styleFlushes);
mFlushesPerTick[FlushKind::Style] = SaturateUint8(0);
}
auto layoutFlushes = mFlushesPerTick[FlushKind::Layout].value();
if (flushKind == FlushKind::Layout && layoutFlushes > 0) {
Telemetry::Accumulate(Telemetry::PRESSHELL_FLUSHES_PER_TICK,
NS_LITERAL_CSTRING("Layout"), layoutFlushes);
mFlushesPerTick[FlushKind::Layout] = SaturateUint8(0);
}
}
void Data::PingTotalMsPerTickTelemetry(FlushType aFlushType) {
auto flushKind = ToKind(aFlushType);
auto range = (flushKind == FlushKind::Style)
? MakeEnumeratedRange(LayoutSubsystem::Restyle,
LayoutSubsystem::Reflow)
: MakeEnumeratedRange(LayoutSubsystem::Reflow,
LayoutSubsystem::Count);
for (auto subsystem : range) {
auto key = SubsystemTelemetryKey(subsystem);
double& duration = mLayoutSubsystemDurationMs[subsystem];
if (duration > 0.0) {
Telemetry::Accumulate(Telemetry::PRESSHELL_LAYOUT_TOTAL_MS_PER_TICK, key,
static_cast<uint32_t>(duration));
duration = 0.0;
}
}
}
void Data::PingPerTickTelemetry(FlushType aFlushType) {
PingFlushPerTickTelemetry(aFlushType);
PingTotalMsPerTickTelemetry(aFlushType);
}
AutoRecord::AutoRecord(LayoutSubsystem aSubsystem)
: AutoRecord(nullptr, aSubsystem) {}
AutoRecord::AutoRecord(Data* aLayoutTelemetry, LayoutSubsystem aSubsystem)
: mParentRecord(sCurrentRecord),
mLayoutTelemetry(aLayoutTelemetry),
mSubsystem(aSubsystem),
mStartTime(TimeStamp::Now()),
mDurationMs(0.0) {
MOZ_ASSERT(NS_IsMainThread());
// If we're re-entering the same subsystem, don't update the current record.
if (mParentRecord) {
if (mParentRecord->mSubsystem == mSubsystem) {
return;
}
mLayoutTelemetry = mParentRecord->mLayoutTelemetry;
MOZ_ASSERT(mLayoutTelemetry);
// If we're entering a new subsystem, record the amount of time spent in the
// parent record before setting the new current record.
mParentRecord->mDurationMs +=
(mStartTime - mParentRecord->mStartTime).ToMilliseconds();
}
sCurrentRecord = this;
}
AutoRecord::~AutoRecord() {
if (sCurrentRecord != this) {
// If this record is not head of the list, do nothing.
return;
}
TimeStamp now = TimeStamp::Now();
mDurationMs += (now - mStartTime).ToMilliseconds();
mLayoutTelemetry->mLayoutSubsystemDurationMs[mSubsystem] += mDurationMs;
if (mParentRecord) {
// Restart the parent recording from this point
mParentRecord->mStartTime = now;
}
// Unlink this record from the current record list
sCurrentRecord = mParentRecord;
}
} // namespace layout_telemetry
} // namespace mozilla