mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1183219 - Backed out last 5 changesets for bustage, r=me on a CLOSED TREE
This commit is contained in:
parent
6609b1944f
commit
0267134d00
@ -2929,17 +2929,29 @@ nsDocShell::HistoryTransactionRemoved(int32_t aIndex)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
unsigned long nsDocShell::gProfileTimelineRecordingsCount = 0;
|
||||
|
||||
mozilla::LinkedList<nsDocShell::ObservedDocShell>* nsDocShell::gObservedDocShells = nullptr;
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDocShell::SetRecordProfileTimelineMarkers(bool aValue)
|
||||
{
|
||||
bool currentValue = nsIDocShell::GetRecordProfileTimelineMarkers();
|
||||
if (currentValue != aValue) {
|
||||
if (aValue) {
|
||||
TimelineConsumers::AddConsumer(this);
|
||||
++gProfileTimelineRecordingsCount;
|
||||
UseEntryScriptProfiling();
|
||||
|
||||
MOZ_ASSERT(!mObserved);
|
||||
mObserved.reset(new ObservedDocShell(this));
|
||||
GetOrCreateObservedDocShells().insertFront(mObserved.get());
|
||||
} else {
|
||||
TimelineConsumers::RemoveConsumer(this);
|
||||
--gProfileTimelineRecordingsCount;
|
||||
UnuseEntryScriptProfiling();
|
||||
|
||||
mObserved.reset(nullptr);
|
||||
|
||||
ClearProfileTimelineMarkers();
|
||||
}
|
||||
}
|
||||
|
||||
@ -2955,13 +2967,124 @@ nsDocShell::GetRecordProfileTimelineMarkers(bool* aValue)
|
||||
|
||||
nsresult
|
||||
nsDocShell::PopProfileTimelineMarkers(
|
||||
JSContext* aCx,
|
||||
JS::MutableHandle<JS::Value> aStore)
|
||||
JSContext* aCx,
|
||||
JS::MutableHandle<JS::Value> aProfileTimelineMarkers)
|
||||
{
|
||||
if (!mObserved->PopMarkers(aCx, aStore)) {
|
||||
// Looping over all markers gathered so far at the docShell level, whenever a
|
||||
// START marker is found, look for the corresponding END marker and build a
|
||||
// {name,start,end} JS object.
|
||||
// Paint markers are different because paint is handled at root docShell level
|
||||
// in the information that a paint was done is then stored at each sub
|
||||
// docShell level but we can only be sure that a paint did happen in a
|
||||
// docShell if an Layer marker type was recorded too.
|
||||
|
||||
nsTArray<mozilla::dom::ProfileTimelineMarker> profileTimelineMarkers;
|
||||
SequenceRooter<mozilla::dom::ProfileTimelineMarker> rooter(
|
||||
aCx, &profileTimelineMarkers);
|
||||
|
||||
// If we see an unpaired START, we keep it around for the next call
|
||||
// to PopProfileTimelineMarkers. We store the kept START objects in
|
||||
// this array.
|
||||
nsTArray<UniquePtr<TimelineMarker>> keptMarkers;
|
||||
|
||||
for (uint32_t i = 0; i < mProfileTimelineMarkers.Length(); ++i) {
|
||||
UniquePtr<TimelineMarker>& startPayload = mProfileTimelineMarkers[i];
|
||||
const char* startMarkerName = startPayload->GetName();
|
||||
|
||||
bool hasSeenPaintedLayer = false;
|
||||
bool isPaint = strcmp(startMarkerName, "Paint") == 0;
|
||||
|
||||
// If we are processing a Paint marker, we append information from
|
||||
// all the embedded Layer markers to this array.
|
||||
dom::Sequence<dom::ProfileTimelineLayerRect> layerRectangles;
|
||||
|
||||
// If this is a TRACING_TIMESTAMP marker, there's no corresponding "end"
|
||||
// marker, as it's a single unit of time, not a duration, create the final
|
||||
// marker here.
|
||||
if (startPayload->GetMetaData() == TRACING_TIMESTAMP) {
|
||||
mozilla::dom::ProfileTimelineMarker* marker =
|
||||
profileTimelineMarkers.AppendElement();
|
||||
|
||||
marker->mName = NS_ConvertUTF8toUTF16(startPayload->GetName());
|
||||
marker->mStart = startPayload->GetTime();
|
||||
marker->mEnd = startPayload->GetTime();
|
||||
marker->mStack = startPayload->GetStack();
|
||||
startPayload->AddDetails(aCx, *marker);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (startPayload->GetMetaData() == TRACING_INTERVAL_START) {
|
||||
bool hasSeenEnd = false;
|
||||
|
||||
// DOM events can be nested, so we must take care when searching
|
||||
// for the matching end. It doesn't hurt to apply this logic to
|
||||
// all event types.
|
||||
uint32_t markerDepth = 0;
|
||||
|
||||
// The assumption is that the devtools timeline flushes markers frequently
|
||||
// enough for the amount of markers to always be small enough that the
|
||||
// nested for loop isn't going to be a performance problem.
|
||||
for (uint32_t j = i + 1; j < mProfileTimelineMarkers.Length(); ++j) {
|
||||
UniquePtr<TimelineMarker>& endPayload = mProfileTimelineMarkers[j];
|
||||
const char* endMarkerName = endPayload->GetName();
|
||||
|
||||
// Look for Layer markers to stream out paint markers.
|
||||
if (isPaint && strcmp(endMarkerName, "Layer") == 0) {
|
||||
hasSeenPaintedLayer = true;
|
||||
endPayload->AddLayerRectangles(layerRectangles);
|
||||
}
|
||||
|
||||
if (!startPayload->Equals(*endPayload)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Pair start and end markers.
|
||||
if (endPayload->GetMetaData() == TRACING_INTERVAL_START) {
|
||||
++markerDepth;
|
||||
} else if (endPayload->GetMetaData() == TRACING_INTERVAL_END) {
|
||||
if (markerDepth > 0) {
|
||||
--markerDepth;
|
||||
} else {
|
||||
// But ignore paint start/end if no layer has been painted.
|
||||
if (!isPaint || (isPaint && hasSeenPaintedLayer)) {
|
||||
mozilla::dom::ProfileTimelineMarker* marker =
|
||||
profileTimelineMarkers.AppendElement();
|
||||
|
||||
marker->mName = NS_ConvertUTF8toUTF16(startPayload->GetName());
|
||||
marker->mStart = startPayload->GetTime();
|
||||
marker->mEnd = endPayload->GetTime();
|
||||
marker->mStack = startPayload->GetStack();
|
||||
if (isPaint) {
|
||||
marker->mRectangles.Construct(layerRectangles);
|
||||
}
|
||||
startPayload->AddDetails(aCx, *marker);
|
||||
endPayload->AddDetails(aCx, *marker);
|
||||
}
|
||||
|
||||
// We want the start to be dropped either way.
|
||||
hasSeenEnd = true;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If we did not see the corresponding END, keep the START.
|
||||
if (!hasSeenEnd) {
|
||||
keptMarkers.AppendElement(Move(mProfileTimelineMarkers[i]));
|
||||
mProfileTimelineMarkers.RemoveElementAt(i);
|
||||
--i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mProfileTimelineMarkers.SwapElements(keptMarkers);
|
||||
|
||||
if (!ToJSValue(aCx, profileTimelineMarkers, aProfileTimelineMarkers)) {
|
||||
JS_ClearPendingException(aCx);
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -2974,6 +3097,24 @@ nsDocShell::Now(DOMHighResTimeStamp* aWhen)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
nsDocShell::AddProfileTimelineMarker(const char* aName,
|
||||
TracingMetadata aMetaData)
|
||||
{
|
||||
if (IsObserved()) {
|
||||
TimelineMarker* marker = new TimelineMarker(this, aName, aMetaData);
|
||||
mProfileTimelineMarkers.AppendElement(marker);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsDocShell::AddProfileTimelineMarker(UniquePtr<TimelineMarker>&& aMarker)
|
||||
{
|
||||
if (IsObserved()) {
|
||||
mProfileTimelineMarkers.AppendElement(Move(aMarker));
|
||||
}
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDocShell::SetWindowDraggingAllowed(bool aValue)
|
||||
{
|
||||
@ -3003,6 +3144,12 @@ nsDocShell::GetWindowDraggingAllowed(bool* aValue)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
nsDocShell::ClearProfileTimelineMarkers()
|
||||
{
|
||||
mProfileTimelineMarkers.Clear();
|
||||
}
|
||||
|
||||
nsIDOMStorageManager*
|
||||
nsDocShell::TopSessionStorageManager()
|
||||
{
|
||||
@ -13840,7 +13987,7 @@ nsDocShell::NotifyJSRunToCompletionStart(const char* aReason,
|
||||
MakeUnique<JavascriptTimelineMarker>(this, "Javascript", aReason,
|
||||
aFunctionName, aFilename,
|
||||
aLineNumber);
|
||||
TimelineConsumers::AddMarkerForDocShell(this, Move(marker));
|
||||
AddProfileTimelineMarker(Move(marker));
|
||||
}
|
||||
mJSRunToCompletionDepth++;
|
||||
}
|
||||
@ -13853,7 +14000,7 @@ nsDocShell::NotifyJSRunToCompletionStop()
|
||||
// If last stop, mark interval end.
|
||||
mJSRunToCompletionDepth--;
|
||||
if (timelineOn && mJSRunToCompletionDepth == 0) {
|
||||
TimelineConsumers::AddMarkerForDocShell(this, "Javascript", TRACING_INTERVAL_END);
|
||||
AddProfileTimelineMarker("Javascript", TRACING_INTERVAL_END);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -34,8 +34,6 @@
|
||||
#include "nsThreadUtils.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "timeline/TimelineMarker.h"
|
||||
#include "timeline/TimelineConsumers.h"
|
||||
#include "timeline/ObservedDocShell.h"
|
||||
|
||||
// Threshold value in ms for META refresh based redirects
|
||||
#define REFRESH_REDIRECT_TIMER 15000
|
||||
@ -258,24 +256,53 @@ public:
|
||||
// is no longer applied
|
||||
void NotifyAsyncPanZoomStopped();
|
||||
|
||||
// Add new profile timeline markers to this docShell. This will only add
|
||||
// markers if the docShell is currently recording profile timeline markers.
|
||||
// See nsIDocShell::recordProfileTimelineMarkers
|
||||
void AddProfileTimelineMarker(const char* aName, TracingMetadata aMetaData);
|
||||
void AddProfileTimelineMarker(mozilla::UniquePtr<TimelineMarker>&& aMarker);
|
||||
|
||||
// Global counter for how many docShells are currently recording profile
|
||||
// timeline markers
|
||||
static unsigned long gProfileTimelineRecordingsCount;
|
||||
|
||||
class ObservedDocShell : public mozilla::LinkedListElement<ObservedDocShell>
|
||||
{
|
||||
public:
|
||||
explicit ObservedDocShell(nsDocShell* aDocShell)
|
||||
: mDocShell(aDocShell)
|
||||
{ }
|
||||
|
||||
nsDocShell* operator*() const { return mDocShell.get(); }
|
||||
|
||||
private:
|
||||
nsRefPtr<nsDocShell> mDocShell;
|
||||
};
|
||||
|
||||
private:
|
||||
// An observed docshell wrapper is created when recording markers is enabled.
|
||||
mozilla::UniquePtr<mozilla::ObservedDocShell> mObserved;
|
||||
static mozilla::LinkedList<ObservedDocShell>* gObservedDocShells;
|
||||
|
||||
static mozilla::LinkedList<ObservedDocShell>& GetOrCreateObservedDocShells()
|
||||
{
|
||||
if (!gObservedDocShells) {
|
||||
gObservedDocShells = new mozilla::LinkedList<ObservedDocShell>();
|
||||
}
|
||||
return *gObservedDocShells;
|
||||
}
|
||||
|
||||
// Never null if timeline markers are being observed.
|
||||
mozilla::UniquePtr<ObservedDocShell> mObserved;
|
||||
|
||||
// Return true if timeline markers are being observed for this docshell. False
|
||||
// otherwise.
|
||||
bool IsObserved() const { return !!mObserved; }
|
||||
|
||||
// It is necessary to allow adding a timeline marker wherever a docshell
|
||||
// instance is available. This operation happens frequently and needs to
|
||||
// be very fast, so instead of using a Map or having to search for some
|
||||
// docshell-specific markers storage, a pointer to an `ObservedDocShell` is
|
||||
// is stored on docshells directly.
|
||||
friend void mozilla::TimelineConsumers::AddConsumer(nsDocShell* aDocShell);
|
||||
friend void mozilla::TimelineConsumers::RemoveConsumer(nsDocShell* aDocShell);
|
||||
friend void mozilla::TimelineConsumers::AddMarkerForDocShell(
|
||||
nsDocShell* aDocShell, UniquePtr<TimelineMarker>&& aMarker);
|
||||
friend void mozilla::TimelineConsumers::AddMarkerForDocShell(
|
||||
nsDocShell* aDocShell, const char* aName, TracingMetadata aMetaData);
|
||||
|
||||
public:
|
||||
static const mozilla::LinkedList<ObservedDocShell>& GetObservedDocShells()
|
||||
{
|
||||
return GetOrCreateObservedDocShells();
|
||||
}
|
||||
|
||||
// Tell the favicon service that aNewURI has the same favicon as aOldURI.
|
||||
static void CopyFavicon(nsIURI* aOldURI,
|
||||
nsIURI* aNewURI,
|
||||
@ -983,6 +1010,11 @@ private:
|
||||
// has been called without a matching NotifyRunToCompletionStop.
|
||||
uint32_t mJSRunToCompletionDepth;
|
||||
|
||||
nsTArray<mozilla::UniquePtr<TimelineMarker>> mProfileTimelineMarkers;
|
||||
|
||||
// Get rid of all the timeline markers accumulated so far
|
||||
void ClearProfileTimelineMarkers();
|
||||
|
||||
// Separate function to do the actual name (i.e. not _top, _self etc.)
|
||||
// searching for FindItemWithName.
|
||||
nsresult DoFindItemWithName(const char16_t* aName,
|
||||
|
@ -6,32 +6,66 @@
|
||||
|
||||
#include "mozilla/AutoGlobalTimelineMarker.h"
|
||||
|
||||
#include "mozilla/TimelineConsumers.h"
|
||||
#include "MainThreadUtils.h"
|
||||
#include "nsDocShell.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
void
|
||||
AutoGlobalTimelineMarker::PopulateDocShells()
|
||||
{
|
||||
const LinkedList<nsDocShell::ObservedDocShell>& docShells =
|
||||
nsDocShell::GetObservedDocShells();
|
||||
MOZ_ASSERT(!docShells.isEmpty());
|
||||
|
||||
for (const nsDocShell::ObservedDocShell* ds = docShells.getFirst();
|
||||
ds;
|
||||
ds = ds->getNext()) {
|
||||
mOk = mDocShells.append(**ds);
|
||||
if (!mOk) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
AutoGlobalTimelineMarker::AutoGlobalTimelineMarker(const char* aName
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_PARAM_IN_IMPL)
|
||||
: mName(aName)
|
||||
: mOk(true)
|
||||
, mDocShells()
|
||||
, mName(aName)
|
||||
{
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
if (TimelineConsumers::IsEmpty()) {
|
||||
if (nsDocShell::gProfileTimelineRecordingsCount == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
TimelineConsumers::AddMarkerToAllObservedDocShells(mName, TRACING_INTERVAL_START);
|
||||
PopulateDocShells();
|
||||
if (!mOk) {
|
||||
// If we don't successfully populate our vector with *all* docshells being
|
||||
// observed, don't add markers to *any* of them.
|
||||
return;
|
||||
}
|
||||
|
||||
for (Vector<nsRefPtr<nsDocShell>>::Range range = mDocShells.all();
|
||||
!range.empty();
|
||||
range.popFront()) {
|
||||
range.front()->AddProfileTimelineMarker(mName, TRACING_INTERVAL_START);
|
||||
}
|
||||
}
|
||||
|
||||
AutoGlobalTimelineMarker::~AutoGlobalTimelineMarker()
|
||||
{
|
||||
if (TimelineConsumers::IsEmpty()) {
|
||||
if (!mOk) {
|
||||
return;
|
||||
}
|
||||
|
||||
TimelineConsumers::AddMarkerToAllObservedDocShells(mName, TRACING_INTERVAL_END);
|
||||
for (Vector<nsRefPtr<nsDocShell>>::Range range = mDocShells.all();
|
||||
!range.empty();
|
||||
range.popFront()) {
|
||||
range.front()->AddProfileTimelineMarker(mName, TRACING_INTERVAL_END);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace mozilla
|
||||
|
@ -8,6 +8,7 @@
|
||||
#define mozilla_AutoGlobalTimelineMarker_h_
|
||||
|
||||
#include "mozilla/GuardObjects.h"
|
||||
#include "mozilla/Vector.h"
|
||||
#include "nsRefPtr.h"
|
||||
|
||||
class nsDocShell;
|
||||
@ -33,12 +34,21 @@ class MOZ_STACK_CLASS AutoGlobalTimelineMarker
|
||||
{
|
||||
MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER;
|
||||
|
||||
// True as long as no operation has failed, eg due to OOM.
|
||||
bool mOk;
|
||||
|
||||
// The set of docshells that are being observed and will get markers.
|
||||
mozilla::Vector<nsRefPtr<nsDocShell>> mDocShells;
|
||||
|
||||
// The name of the marker we are adding.
|
||||
const char* mName;
|
||||
|
||||
void PopulateDocShells();
|
||||
|
||||
public:
|
||||
explicit AutoGlobalTimelineMarker(const char* aName
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_PARAM);
|
||||
|
||||
~AutoGlobalTimelineMarker();
|
||||
|
||||
AutoGlobalTimelineMarker(const AutoGlobalTimelineMarker& aOther) = delete;
|
||||
|
@ -6,36 +6,41 @@
|
||||
|
||||
#include "mozilla/AutoTimelineMarker.h"
|
||||
|
||||
#include "mozilla/TimelineConsumers.h"
|
||||
#include "MainThreadUtils.h"
|
||||
#include "nsDocShell.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
bool
|
||||
AutoTimelineMarker::DocShellIsRecording(nsDocShell& aDocShell)
|
||||
{
|
||||
bool isRecording = false;
|
||||
if (nsDocShell::gProfileTimelineRecordingsCount > 0) {
|
||||
aDocShell.GetRecordProfileTimelineMarkers(&isRecording);
|
||||
}
|
||||
return isRecording;
|
||||
}
|
||||
|
||||
AutoTimelineMarker::AutoTimelineMarker(nsIDocShell* aDocShell, const char* aName
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_PARAM_IN_IMPL)
|
||||
: mName(aName)
|
||||
, mDocShell(nullptr)
|
||||
: mDocShell(nullptr)
|
||||
, mName(aName)
|
||||
{
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(aDocShell);
|
||||
|
||||
if (TimelineConsumers::IsEmpty()) {
|
||||
return;
|
||||
nsDocShell* docShell = static_cast<nsDocShell*>(aDocShell);
|
||||
if (docShell && DocShellIsRecording(*docShell)) {
|
||||
mDocShell = docShell;
|
||||
mDocShell->AddProfileTimelineMarker(mName, TRACING_INTERVAL_START);
|
||||
}
|
||||
|
||||
mDocShell = static_cast<nsDocShell*>(aDocShell);
|
||||
TimelineConsumers::AddMarkerForDocShell(mDocShell, mName, TRACING_INTERVAL_START);
|
||||
}
|
||||
|
||||
AutoTimelineMarker::~AutoTimelineMarker()
|
||||
{
|
||||
if (TimelineConsumers::IsEmpty()) {
|
||||
return;
|
||||
if (mDocShell) {
|
||||
mDocShell->AddProfileTimelineMarker(mName, TRACING_INTERVAL_END);
|
||||
}
|
||||
|
||||
TimelineConsumers::AddMarkerForDocShell(mDocShell, mName, TRACING_INTERVAL_END);
|
||||
}
|
||||
|
||||
} // namespace mozilla
|
||||
|
@ -32,11 +32,10 @@ class MOZ_STACK_CLASS AutoTimelineMarker
|
||||
{
|
||||
MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER;
|
||||
|
||||
// The name of the marker we are adding.
|
||||
nsRefPtr<nsDocShell> mDocShell;
|
||||
const char* mName;
|
||||
|
||||
// The docshell that is associated with this marker.
|
||||
nsRefPtr<nsDocShell> mDocShell;
|
||||
bool DocShellIsRecording(nsDocShell& aDocShell);
|
||||
|
||||
public:
|
||||
explicit AutoTimelineMarker(nsIDocShell* aDocShell, const char* aName
|
||||
|
@ -1,144 +0,0 @@
|
||||
/* -*- 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 "ObservedDocShell.h"
|
||||
|
||||
#include "TimelineMarker.h"
|
||||
#include "mozilla/Move.h"
|
||||
#include "mozilla/dom/BindingUtils.h"
|
||||
#include "mozilla/dom/ToJSValue.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
using dom::ProfileTimelineMarker;
|
||||
using dom::ProfileTimelineLayerRect;
|
||||
|
||||
ObservedDocShell::ObservedDocShell(nsDocShell* aDocShell)
|
||||
: mDocShell(aDocShell)
|
||||
{}
|
||||
|
||||
void
|
||||
ObservedDocShell::AddMarker(const char* aName, TracingMetadata aMetaData)
|
||||
{
|
||||
TimelineMarker* marker = new TimelineMarker(mDocShell, aName, aMetaData);
|
||||
mTimelineMarkers.AppendElement(marker);
|
||||
}
|
||||
|
||||
void
|
||||
ObservedDocShell::AddMarker(UniquePtr<TimelineMarker>&& aMarker)
|
||||
{
|
||||
mTimelineMarkers.AppendElement(Move(aMarker));
|
||||
}
|
||||
|
||||
void
|
||||
ObservedDocShell::ClearMarkers()
|
||||
{
|
||||
mTimelineMarkers.Clear();
|
||||
}
|
||||
|
||||
bool
|
||||
ObservedDocShell::PopMarkers(JSContext* aCx,
|
||||
JS::MutableHandle<JS::Value> aStore)
|
||||
{
|
||||
nsTArray<ProfileTimelineMarker> webidlStore;
|
||||
dom::SequenceRooter<ProfileTimelineMarker> rooter(aCx, &webidlStore);
|
||||
|
||||
// If we see an unpaired START, we keep it around for the next call
|
||||
// to ObservedDocShell::PopMarkers. We store the kept START objects here.
|
||||
nsTArray<UniquePtr<TimelineMarker>> keptStartMarkers;
|
||||
|
||||
for (uint32_t i = 0; i < mTimelineMarkers.Length(); ++i) {
|
||||
UniquePtr<TimelineMarker>& startPayload = mTimelineMarkers[i];
|
||||
|
||||
// If this is a TRACING_TIMESTAMP marker, there's no corresponding END
|
||||
// as it's a single unit of time, not a duration.
|
||||
if (startPayload->GetMetaData() == TRACING_TIMESTAMP) {
|
||||
ProfileTimelineMarker* marker = webidlStore.AppendElement();
|
||||
marker->mName = NS_ConvertUTF8toUTF16(startPayload->GetName());
|
||||
marker->mStart = startPayload->GetTime();
|
||||
marker->mEnd = startPayload->GetTime();
|
||||
marker->mStack = startPayload->GetStack();
|
||||
startPayload->AddDetails(aCx, *marker);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Whenever a START marker is found, look for the corresponding END
|
||||
// and build a {name,start,end} JS object.
|
||||
if (startPayload->GetMetaData() == TRACING_INTERVAL_START) {
|
||||
bool hasSeenEnd = false;
|
||||
|
||||
// "Paint" markers are different because painting is handled at root
|
||||
// docshell level. The information that a paint was done is stored at
|
||||
// sub-docshell level, but we can only be sure that a paint did actually
|
||||
// happen in if a "Layer" marker was recorded too.
|
||||
bool startIsPaintType = strcmp(startPayload->GetName(), "Paint") == 0;
|
||||
bool hasSeenLayerType = false;
|
||||
|
||||
// If we are processing a "Paint" marker, we append information from
|
||||
// all the embedded "Layer" markers to this array.
|
||||
dom::Sequence<ProfileTimelineLayerRect> layerRectangles;
|
||||
|
||||
// DOM events can be nested, so we must take care when searching
|
||||
// for the matching end. It doesn't hurt to apply this logic to
|
||||
// all event types.
|
||||
uint32_t markerDepth = 0;
|
||||
|
||||
// The assumption is that the devtools timeline flushes markers frequently
|
||||
// enough for the amount of markers to always be small enough that the
|
||||
// nested for loop isn't going to be a performance problem.
|
||||
for (uint32_t j = i + 1; j < mTimelineMarkers.Length(); ++j) {
|
||||
UniquePtr<TimelineMarker>& endPayload = mTimelineMarkers[j];
|
||||
bool endIsLayerType = strcmp(endPayload->GetName(), "Layer") == 0;
|
||||
|
||||
// Look for "Layer" markers to stream out "Paint" markers.
|
||||
if (startIsPaintType && endIsLayerType) {
|
||||
hasSeenLayerType = true;
|
||||
endPayload->AddLayerRectangles(layerRectangles);
|
||||
}
|
||||
if (!startPayload->Equals(*endPayload)) {
|
||||
continue;
|
||||
}
|
||||
if (endPayload->GetMetaData() == TRACING_INTERVAL_START) {
|
||||
++markerDepth;
|
||||
continue;
|
||||
}
|
||||
if (endPayload->GetMetaData() == TRACING_INTERVAL_END) {
|
||||
if (markerDepth > 0) {
|
||||
--markerDepth;
|
||||
continue;
|
||||
}
|
||||
if (!startIsPaintType || (startIsPaintType && hasSeenLayerType)) {
|
||||
ProfileTimelineMarker* marker = webidlStore.AppendElement();
|
||||
marker->mName = NS_ConvertUTF8toUTF16(startPayload->GetName());
|
||||
marker->mStart = startPayload->GetTime();
|
||||
marker->mEnd = endPayload->GetTime();
|
||||
marker->mStack = startPayload->GetStack();
|
||||
if (hasSeenLayerType) {
|
||||
marker->mRectangles.Construct(layerRectangles);
|
||||
}
|
||||
startPayload->AddDetails(aCx, *marker);
|
||||
endPayload->AddDetails(aCx, *marker);
|
||||
}
|
||||
hasSeenEnd = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// If we did not see the corresponding END, keep the START.
|
||||
if (!hasSeenEnd) {
|
||||
keptStartMarkers.AppendElement(Move(mTimelineMarkers[i]));
|
||||
mTimelineMarkers.RemoveElementAt(i);
|
||||
--i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mTimelineMarkers.SwapElements(keptStartMarkers);
|
||||
|
||||
return ToJSValue(aCx, webidlStore, aStore);
|
||||
}
|
||||
|
||||
} // namespace mozilla
|
@ -1,41 +0,0 @@
|
||||
/* -*- 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/. */
|
||||
|
||||
#ifndef ObservedDocShell_h_
|
||||
#define ObservedDocShell_h_
|
||||
|
||||
#include "GeckoProfiler.h"
|
||||
#include "nsTArray.h"
|
||||
#include "nsRefPtr.h"
|
||||
|
||||
class nsDocShell;
|
||||
class TimelineMarker;
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
// # ObservedDocShell
|
||||
//
|
||||
// A wrapper around a docshell for which docshell-specific markers are
|
||||
// allowed to exist. See TimelineConsumers for register/unregister logic.
|
||||
class ObservedDocShell : public LinkedListElement<ObservedDocShell>
|
||||
{
|
||||
private:
|
||||
nsRefPtr<nsDocShell> mDocShell;
|
||||
nsTArray<UniquePtr<TimelineMarker>> mTimelineMarkers;
|
||||
|
||||
public:
|
||||
explicit ObservedDocShell(nsDocShell* aDocShell);
|
||||
nsDocShell* operator*() const { return mDocShell.get(); }
|
||||
|
||||
void AddMarker(const char* aName, TracingMetadata aMetaData);
|
||||
void AddMarker(UniquePtr<TimelineMarker>&& aMarker);
|
||||
void ClearMarkers();
|
||||
bool PopMarkers(JSContext* aCx, JS::MutableHandle<JS::Value> aStore);
|
||||
};
|
||||
|
||||
} // namespace mozilla
|
||||
|
||||
#endif /* ObservedDocShell_h_ */
|
@ -1,110 +0,0 @@
|
||||
/* -*- 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/TimelineConsumers.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
unsigned long TimelineConsumers::sActiveConsumers = 0;
|
||||
LinkedList<ObservedDocShell>* TimelineConsumers::sObservedDocShells = nullptr;
|
||||
|
||||
LinkedList<ObservedDocShell>&
|
||||
TimelineConsumers::GetOrCreateObservedDocShellsList()
|
||||
{
|
||||
if (!sObservedDocShells) {
|
||||
sObservedDocShells = new LinkedList<ObservedDocShell>();
|
||||
}
|
||||
return *sObservedDocShells;
|
||||
}
|
||||
|
||||
void
|
||||
TimelineConsumers::AddConsumer(nsDocShell* aDocShell)
|
||||
{
|
||||
UniquePtr<ObservedDocShell>& observed = aDocShell->mObserved;
|
||||
|
||||
MOZ_ASSERT(!observed);
|
||||
sActiveConsumers++;
|
||||
observed.reset(new ObservedDocShell(aDocShell));
|
||||
GetOrCreateObservedDocShellsList().insertFront(observed.get());
|
||||
}
|
||||
|
||||
void
|
||||
TimelineConsumers::RemoveConsumer(nsDocShell* aDocShell)
|
||||
{
|
||||
UniquePtr<ObservedDocShell>& observed = aDocShell->mObserved;
|
||||
|
||||
MOZ_ASSERT(observed);
|
||||
sActiveConsumers--;
|
||||
observed.get()->ClearMarkers();
|
||||
observed.get()->remove();
|
||||
observed.reset(nullptr);
|
||||
}
|
||||
|
||||
bool
|
||||
TimelineConsumers::IsEmpty()
|
||||
{
|
||||
return sActiveConsumers == 0;
|
||||
}
|
||||
|
||||
bool
|
||||
TimelineConsumers::GetKnownDocShells(Vector<nsRefPtr<nsDocShell>>& aStore)
|
||||
{
|
||||
const LinkedList<ObservedDocShell>& docShells = GetOrCreateObservedDocShellsList();
|
||||
|
||||
for (const ObservedDocShell* rds = docShells.getFirst();
|
||||
rds != nullptr;
|
||||
rds = rds->getNext()) {
|
||||
if (!aStore.append(**rds)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
TimelineConsumers::AddMarkerForDocShell(nsDocShell* aDocShell,
|
||||
UniquePtr<TimelineMarker>&& aMarker)
|
||||
{
|
||||
if (aDocShell->IsObserved()) {
|
||||
aDocShell->mObserved->AddMarker(Move(aMarker));
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
TimelineConsumers::AddMarkerForDocShell(nsDocShell* aDocShell,
|
||||
const char* aName, TracingMetadata aMetaData)
|
||||
{
|
||||
if (aDocShell->IsObserved()) {
|
||||
aDocShell->mObserved->AddMarker(aName, aMetaData);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
TimelineConsumers::AddMarkerToDocShellsList(Vector<nsRefPtr<nsDocShell>>& aDocShells,
|
||||
const char* aName, TracingMetadata aMetaData)
|
||||
{
|
||||
for (Vector<nsRefPtr<nsDocShell>>::Range range = aDocShells.all();
|
||||
!range.empty();
|
||||
range.popFront()) {
|
||||
AddMarkerForDocShell(range.front(), aName, aMetaData);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
TimelineConsumers::AddMarkerToAllObservedDocShells(const char* aName, TracingMetadata aMetaData)
|
||||
{
|
||||
Vector<nsRefPtr<nsDocShell>> docShells;
|
||||
if (!GetKnownDocShells(docShells)) {
|
||||
// If we don't successfully populate our vector with *all* docshells being
|
||||
// observed, don't add the marker to *any* of them.
|
||||
return;
|
||||
}
|
||||
|
||||
AddMarkerToDocShellsList(docShells, aName, aMetaData);
|
||||
}
|
||||
|
||||
} // namespace mozilla
|
@ -1,47 +0,0 @@
|
||||
/* -*- 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/. */
|
||||
|
||||
#ifndef mozilla_TimelineConsumers_h_
|
||||
#define mozilla_TimelineConsumers_h_
|
||||
|
||||
#include "mozilla/UniquePtr.h"
|
||||
#include "mozilla/LinkedList.h"
|
||||
#include "mozilla/Vector.h"
|
||||
#include "timeline/ObservedDocShell.h"
|
||||
|
||||
class nsDocShell;
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
class TimelineConsumers
|
||||
{
|
||||
private:
|
||||
// Counter for how many timelines are currently interested in markers.
|
||||
static unsigned long sActiveConsumers;
|
||||
static LinkedList<ObservedDocShell>* sObservedDocShells;
|
||||
static LinkedList<ObservedDocShell>& GetOrCreateObservedDocShellsList();
|
||||
|
||||
public:
|
||||
static void AddConsumer(nsDocShell* aDocShell);
|
||||
static void RemoveConsumer(nsDocShell* aDocShell);
|
||||
static bool IsEmpty();
|
||||
static bool GetKnownDocShells(Vector<nsRefPtr<nsDocShell>>& aStore);
|
||||
|
||||
// Methods for adding markers to appropriate docshells. These will only add
|
||||
// markers if the docshell is currently being observed by a timeline.
|
||||
// See nsIDocShell::recordProfileTimelineMarkers
|
||||
static void AddMarkerForDocShell(nsDocShell* aDocShell,
|
||||
UniquePtr<TimelineMarker>&& aMarker);
|
||||
static void AddMarkerForDocShell(nsDocShell* aDocShell,
|
||||
const char* aName, TracingMetadata aMetaData);
|
||||
static void AddMarkerToDocShellsList(Vector<nsRefPtr<nsDocShell>>& aDocShells,
|
||||
const char* aName, TracingMetadata aMetaData);
|
||||
static void AddMarkerToAllObservedDocShells(const char* aName, TracingMetadata aMetaData);
|
||||
};
|
||||
|
||||
} // namespace mozilla
|
||||
|
||||
#endif /* mozilla_TimelineConsumers_h_ */
|
@ -7,14 +7,11 @@
|
||||
EXPORTS.mozilla += [
|
||||
'AutoGlobalTimelineMarker.h',
|
||||
'AutoTimelineMarker.h',
|
||||
'TimelineConsumers.h',
|
||||
]
|
||||
|
||||
UNIFIED_SOURCES += [
|
||||
'AutoGlobalTimelineMarker.cpp',
|
||||
'AutoTimelineMarker.cpp',
|
||||
'ObservedDocShell.cpp',
|
||||
'TimelineConsumers.cpp',
|
||||
'TimelineMarker.cpp',
|
||||
]
|
||||
|
||||
|
@ -1185,7 +1185,7 @@ Console::Method(JSContext* aCx, MethodName aMethodName,
|
||||
|
||||
mozilla::UniquePtr<TimelineMarker> marker =
|
||||
MakeUnique<TimestampTimelineMarker>(docShell, TRACING_TIMESTAMP, key);
|
||||
TimelineConsumers::AddMarkerForDocShell(docShell, Move(marker));
|
||||
docShell->AddProfileTimelineMarker(Move(marker));
|
||||
}
|
||||
// For `console.time(foo)` and `console.timeEnd(foo)`
|
||||
else if (isTimelineRecording && aData.Length() == 1) {
|
||||
@ -1198,7 +1198,7 @@ Console::Method(JSContext* aCx, MethodName aMethodName,
|
||||
MakeUnique<ConsoleTimelineMarker>(docShell,
|
||||
aMethodName == MethodTime ? TRACING_INTERVAL_START : TRACING_INTERVAL_END,
|
||||
key);
|
||||
TimelineConsumers::AddMarkerForDocShell(docShell, Move(marker));
|
||||
docShell->AddProfileTimelineMarker(Move(marker));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -23,7 +23,6 @@
|
||||
#include "mozilla/dom/BindingUtils.h"
|
||||
#include "mozilla/dom/Element.h"
|
||||
#include "mozilla/dom/Event.h"
|
||||
#include "mozilla/TimelineConsumers.h"
|
||||
|
||||
#include "EventListenerService.h"
|
||||
#include "nsCOMArray.h"
|
||||
@ -1123,7 +1122,7 @@ EventListenerManager::HandleEventInternal(nsPresContext* aPresContext,
|
||||
nsCOMPtr<nsIDocShell> docShell;
|
||||
bool isTimelineRecording = false;
|
||||
if (mIsMainThreadELM &&
|
||||
!TimelineConsumers::IsEmpty() &&
|
||||
nsDocShell::gProfileTimelineRecordingsCount > 0 &&
|
||||
listener->mListenerType != Listener::eNativeListener) {
|
||||
docShell = GetDocShellForTarget();
|
||||
if (docShell) {
|
||||
@ -1138,7 +1137,7 @@ EventListenerManager::HandleEventInternal(nsPresContext* aPresContext,
|
||||
mozilla::UniquePtr<TimelineMarker> marker =
|
||||
MakeUnique<EventTimelineMarker>(ds, TRACING_INTERVAL_START,
|
||||
phase, typeStr);
|
||||
TimelineConsumers::AddMarkerForDocShell(ds, Move(marker));
|
||||
ds->AddProfileTimelineMarker(Move(marker));
|
||||
}
|
||||
}
|
||||
|
||||
@ -1149,7 +1148,7 @@ EventListenerManager::HandleEventInternal(nsPresContext* aPresContext,
|
||||
|
||||
if (isTimelineRecording) {
|
||||
nsDocShell* ds = static_cast<nsDocShell*>(docShell.get());
|
||||
TimelineConsumers::AddMarkerForDocShell(ds, "DOMEvent", TRACING_INTERVAL_END);
|
||||
ds->AddProfileTimelineMarker("DOMEvent", TRACING_INTERVAL_END);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3075,7 +3075,7 @@ void ContainerState::FinishPaintedLayerData(PaintedLayerData& aData, FindOpaqueB
|
||||
data->mLayer->SetEventRegions(EventRegions());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (!layer) {
|
||||
// We couldn't optimize to an image layer or a color layer above.
|
||||
layer = data->mLayer;
|
||||
@ -5657,7 +5657,7 @@ FrameLayerBuilder::DrawPaintedLayer(PaintedLayer* aLayer,
|
||||
if (isRecording) {
|
||||
mozilla::UniquePtr<TimelineMarker> marker =
|
||||
MakeUnique<LayerTimelineMarker>(docShell, aRegionToDraw);
|
||||
TimelineConsumers::AddMarkerForDocShell(docShell, Move(marker));
|
||||
docShell->AddProfileTimelineMarker(Move(marker));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -358,7 +358,7 @@ RestyleTracker::DoProcessRestyles()
|
||||
MakeUnique<RestyleTimelineMarker>(docShell,
|
||||
TRACING_INTERVAL_START,
|
||||
data->mRestyleHint);
|
||||
TimelineConsumers::AddMarkerForDocShell(docShell, Move(marker));
|
||||
docShell->AddProfileTimelineMarker(Move(marker));
|
||||
}
|
||||
|
||||
#if defined(MOZ_ENABLE_PROFILER_SPS) && !defined(MOZILLA_XPCOMRT_API)
|
||||
@ -375,7 +375,7 @@ RestyleTracker::DoProcessRestyles()
|
||||
MakeUnique<RestyleTimelineMarker>(docShell,
|
||||
TRACING_INTERVAL_END,
|
||||
data->mRestyleHint);
|
||||
TimelineConsumers::AddMarkerForDocShell(docShell, Move(marker));
|
||||
docShell->AddProfileTimelineMarker(Move(marker));
|
||||
}
|
||||
}
|
||||
|
||||
@ -422,7 +422,7 @@ RestyleTracker::DoProcessRestyles()
|
||||
MakeUnique<RestyleTimelineMarker>(docShell,
|
||||
TRACING_INTERVAL_START,
|
||||
currentRestyle->mRestyleHint);
|
||||
TimelineConsumers::AddMarkerForDocShell(docShell, Move(marker));
|
||||
docShell->AddProfileTimelineMarker(Move(marker));
|
||||
}
|
||||
|
||||
ProcessOneRestyle(currentRestyle->mElement,
|
||||
@ -434,7 +434,7 @@ RestyleTracker::DoProcessRestyles()
|
||||
MakeUnique<RestyleTimelineMarker>(docShell,
|
||||
TRACING_INTERVAL_END,
|
||||
currentRestyle->mRestyleHint);
|
||||
TimelineConsumers::AddMarkerForDocShell(docShell, Move(marker));
|
||||
docShell->AddProfileTimelineMarker(Move(marker));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -8923,7 +8923,7 @@ PresShell::DoReflow(nsIFrame* target, bool aInterruptible)
|
||||
|
||||
nsDocShell* docShell = static_cast<nsDocShell*>(GetPresContext()->GetDocShell());
|
||||
if (docShell) {
|
||||
TimelineConsumers::AddMarkerForDocShell(docShell, "Reflow", TRACING_INTERVAL_START);
|
||||
docShell->AddProfileTimelineMarker("Reflow", TRACING_INTERVAL_START);
|
||||
}
|
||||
|
||||
if (mReflowContinueTimer) {
|
||||
@ -9100,7 +9100,7 @@ PresShell::DoReflow(nsIFrame* target, bool aInterruptible)
|
||||
}
|
||||
|
||||
if (docShell) {
|
||||
TimelineConsumers::AddMarkerForDocShell(docShell, "Reflow", TRACING_INTERVAL_END);
|
||||
docShell->AddProfileTimelineMarker("Reflow", TRACING_INTERVAL_END);
|
||||
}
|
||||
return !interrupted;
|
||||
}
|
||||
|
@ -64,7 +64,6 @@
|
||||
#include "mozilla/VsyncDispatcher.h"
|
||||
#include "nsThreadUtils.h"
|
||||
#include "mozilla/unused.h"
|
||||
#include "mozilla/TimelineConsumers.h"
|
||||
|
||||
#ifdef MOZ_NUWA_PROCESS
|
||||
#include "ipc/Nuwa.h"
|
||||
@ -994,7 +993,7 @@ RefreshDriverTimer*
|
||||
nsRefreshDriver::ChooseTimer() const
|
||||
{
|
||||
if (mThrottled) {
|
||||
if (!sThrottledRateTimer)
|
||||
if (!sThrottledRateTimer)
|
||||
sThrottledRateTimer = new InactiveRefreshDriverTimer(GetThrottledTimerInterval(),
|
||||
DEFAULT_INACTIVE_TIMER_DISABLE_SECONDS * 1000.0);
|
||||
return sThrottledRateTimer;
|
||||
@ -1052,7 +1051,7 @@ nsRefreshDriver::~nsRefreshDriver()
|
||||
MOZ_ASSERT(ObserverCount() == 0,
|
||||
"observers should have unregistered");
|
||||
MOZ_ASSERT(!mActiveTimer, "timer should be gone");
|
||||
|
||||
|
||||
if (mRootRefresh) {
|
||||
mRootRefresh->RemoveRefreshObserver(this, Flush_Style);
|
||||
mRootRefresh = nullptr;
|
||||
@ -1437,7 +1436,7 @@ HasPendingAnimations(nsIPresShell* aShell)
|
||||
static void GetProfileTimelineSubDocShells(nsDocShell* aRootDocShell,
|
||||
nsTArray<nsDocShell*>& aShells)
|
||||
{
|
||||
if (!aRootDocShell || TimelineConsumers::IsEmpty()) {
|
||||
if (!aRootDocShell || nsDocShell::gProfileTimelineRecordingsCount == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1819,7 +1818,7 @@ nsRefreshDriver::Tick(int64_t aNowEpoch, TimeStamp aNowTime)
|
||||
for (nsDocShell* docShell : profilingDocShells) {
|
||||
// For the sake of the profile timeline's simplicity, this is flagged as
|
||||
// paint even if it includes creating display lists
|
||||
TimelineConsumers::AddMarkerForDocShell(docShell, "Paint", TRACING_INTERVAL_START);
|
||||
docShell->AddProfileTimelineMarker("Paint", TRACING_INTERVAL_START);
|
||||
}
|
||||
#ifdef MOZ_DUMP_PAINTING
|
||||
if (nsLayoutUtils::InvalidationDebuggingIsEnabled()) {
|
||||
@ -1836,7 +1835,7 @@ nsRefreshDriver::Tick(int64_t aNowEpoch, TimeStamp aNowTime)
|
||||
}
|
||||
#endif
|
||||
for (nsDocShell* docShell : profilingDocShells) {
|
||||
TimelineConsumers::AddMarkerForDocShell(docShell, "Paint", TRACING_INTERVAL_END);
|
||||
docShell->AddProfileTimelineMarker("Paint", TRACING_INTERVAL_END);
|
||||
}
|
||||
|
||||
if (nsContentUtils::XPConnect()) {
|
||||
|
Loading…
Reference in New Issue
Block a user