mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1183231 - Maintain a list of timeline-observed docshells outside of nsDocShell, r=smaug
This commit is contained in:
parent
2f1e820cee
commit
18ba8c2e6d
@ -2929,26 +2929,17 @@ nsDocShell::HistoryTransactionRemoved(int32_t aIndex)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
mozilla::LinkedList<nsDocShell::ObservedDocShell>* nsDocShell::gObservedDocShells = nullptr;
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDocShell::SetRecordProfileTimelineMarkers(bool aValue)
|
||||
{
|
||||
bool currentValue = nsIDocShell::GetRecordProfileTimelineMarkers();
|
||||
if (currentValue != aValue) {
|
||||
if (aValue) {
|
||||
TimelineConsumers::AddConsumer();
|
||||
TimelineConsumers::AddConsumer(this, mObserved);
|
||||
UseEntryScriptProfiling();
|
||||
|
||||
MOZ_ASSERT(!mObserved);
|
||||
mObserved.reset(new ObservedDocShell(this));
|
||||
GetOrCreateObservedDocShells().insertFront(mObserved.get());
|
||||
} else {
|
||||
TimelineConsumers::RemoveConsumer();
|
||||
TimelineConsumers::RemoveConsumer(this, mObserved);
|
||||
UnuseEntryScriptProfiling();
|
||||
|
||||
mObserved.reset(nullptr);
|
||||
|
||||
ClearProfileTimelineMarkers();
|
||||
}
|
||||
}
|
||||
|
@ -35,6 +35,7 @@
|
||||
#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
|
||||
@ -263,43 +264,12 @@ public:
|
||||
void AddProfileTimelineMarker(const char* aName, TracingMetadata aMetaData);
|
||||
void AddProfileTimelineMarker(mozilla::UniquePtr<TimelineMarker>&& aMarker);
|
||||
|
||||
class ObservedDocShell : public mozilla::LinkedListElement<ObservedDocShell>
|
||||
{
|
||||
public:
|
||||
explicit ObservedDocShell(nsDocShell* aDocShell)
|
||||
: mDocShell(aDocShell)
|
||||
{ }
|
||||
|
||||
nsDocShell* operator*() const { return mDocShell.get(); }
|
||||
|
||||
private:
|
||||
nsRefPtr<nsDocShell> mDocShell;
|
||||
};
|
||||
|
||||
private:
|
||||
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.
|
||||
// An observed docshell wrapper is created when recording markers is enabled.
|
||||
mozilla::UniquePtr<mozilla::ObservedDocShell> mObserved;
|
||||
bool IsObserved() const { return !!mObserved; }
|
||||
|
||||
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,
|
||||
|
@ -12,28 +12,11 @@
|
||||
|
||||
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)
|
||||
: mOk(true)
|
||||
: mName(aName)
|
||||
, mDocShells()
|
||||
, mName(aName)
|
||||
, mDocShellsRetrieved(false)
|
||||
{
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
@ -42,8 +25,8 @@ AutoGlobalTimelineMarker::AutoGlobalTimelineMarker(const char* aName
|
||||
return;
|
||||
}
|
||||
|
||||
PopulateDocShells();
|
||||
if (!mOk) {
|
||||
mDocShellsRetrieved = TimelineConsumers::GetKnownDocShells(mDocShells);
|
||||
if (!mDocShellsRetrieved) {
|
||||
// If we don't successfully populate our vector with *all* docshells being
|
||||
// observed, don't add markers to *any* of them.
|
||||
return;
|
||||
@ -58,7 +41,7 @@ AutoGlobalTimelineMarker::AutoGlobalTimelineMarker(const char* aName
|
||||
|
||||
AutoGlobalTimelineMarker::~AutoGlobalTimelineMarker()
|
||||
{
|
||||
if (!mOk) {
|
||||
if (!mDocShellsRetrieved) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -34,21 +34,18 @@ 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();
|
||||
// The set of docshells that will get the marker.
|
||||
Vector<nsRefPtr<nsDocShell>> mDocShells;
|
||||
|
||||
// True as long as no operation has failed, eg due to OOM.
|
||||
bool mDocShellsRetrieved;
|
||||
|
||||
public:
|
||||
explicit AutoGlobalTimelineMarker(const char* aName
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_PARAM);
|
||||
|
||||
~AutoGlobalTimelineMarker();
|
||||
|
||||
AutoGlobalTimelineMarker(const AutoGlobalTimelineMarker& aOther) = delete;
|
||||
|
@ -11,26 +11,23 @@
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
bool
|
||||
AutoTimelineMarker::DocShellIsRecording(nsDocShell& aDocShell)
|
||||
{
|
||||
bool isRecording = false;
|
||||
if (!TimelineConsumers::IsEmpty()) {
|
||||
aDocShell.GetRecordProfileTimelineMarkers(&isRecording);
|
||||
}
|
||||
return isRecording;
|
||||
}
|
||||
|
||||
AutoTimelineMarker::AutoTimelineMarker(nsIDocShell* aDocShell, const char* aName
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_PARAM_IN_IMPL)
|
||||
: mDocShell(nullptr)
|
||||
, mName(aName)
|
||||
: mName(aName)
|
||||
, mDocShell(nullptr)
|
||||
{
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
if (TimelineConsumers::IsEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
bool isRecordingEnabledForDocShell = false;
|
||||
nsDocShell* docShell = static_cast<nsDocShell*>(aDocShell);
|
||||
if (docShell && DocShellIsRecording(*docShell)) {
|
||||
aDocShell->GetRecordProfileTimelineMarkers(&isRecordingEnabledForDocShell);
|
||||
|
||||
if (isRecordingEnabledForDocShell) {
|
||||
mDocShell = docShell;
|
||||
mDocShell->AddProfileTimelineMarker(mName, TRACING_INTERVAL_START);
|
||||
}
|
||||
|
@ -32,10 +32,11 @@ class MOZ_STACK_CLASS AutoTimelineMarker
|
||||
{
|
||||
MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER;
|
||||
|
||||
nsRefPtr<nsDocShell> mDocShell;
|
||||
// The name of the marker we are adding.
|
||||
const char* mName;
|
||||
|
||||
bool DocShellIsRecording(nsDocShell& aDocShell);
|
||||
// The docshell that is associated with this marker.
|
||||
nsRefPtr<nsDocShell> mDocShell;
|
||||
|
||||
public:
|
||||
explicit AutoTimelineMarker(nsIDocShell* aDocShell, const char* aName
|
||||
|
15
docshell/base/timeline/ObservedDocShell.cpp
Normal file
15
docshell/base/timeline/ObservedDocShell.cpp
Normal file
@ -0,0 +1,15 @@
|
||||
/* -*- 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"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
ObservedDocShell::ObservedDocShell(nsDocShell* aDocShell)
|
||||
: mDocShell(aDocShell)
|
||||
{}
|
||||
|
||||
} // namespace mozilla
|
32
docshell/base/timeline/ObservedDocShell.h
Normal file
32
docshell/base/timeline/ObservedDocShell.h
Normal file
@ -0,0 +1,32 @@
|
||||
/* -*- 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 "nsRefPtr.h"
|
||||
|
||||
class nsDocShell;
|
||||
|
||||
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;
|
||||
|
||||
public:
|
||||
explicit ObservedDocShell(nsDocShell* aDocShell);
|
||||
nsDocShell* operator*() const { return mDocShell.get(); }
|
||||
};
|
||||
|
||||
} // namespace mozilla
|
||||
|
||||
#endif /* ObservedDocShell_h_ */
|
@ -9,17 +9,35 @@
|
||||
namespace mozilla {
|
||||
|
||||
unsigned long TimelineConsumers::sActiveConsumers = 0;
|
||||
LinkedList<ObservedDocShell>* TimelineConsumers::sObservedDocShells = nullptr;
|
||||
|
||||
void
|
||||
TimelineConsumers::AddConsumer()
|
||||
LinkedList<ObservedDocShell>&
|
||||
TimelineConsumers::GetOrCreateObservedDocShellsList()
|
||||
{
|
||||
sActiveConsumers++;
|
||||
if (!sObservedDocShells) {
|
||||
sObservedDocShells = new LinkedList<ObservedDocShell>();
|
||||
}
|
||||
return *sObservedDocShells;
|
||||
}
|
||||
|
||||
void
|
||||
TimelineConsumers::RemoveConsumer()
|
||||
TimelineConsumers::AddConsumer(nsDocShell* aDocShell,
|
||||
UniquePtr<ObservedDocShell>& aObservedPtr)
|
||||
{
|
||||
MOZ_ASSERT(!aObservedPtr);
|
||||
sActiveConsumers++;
|
||||
aObservedPtr.reset(new ObservedDocShell(aDocShell));
|
||||
GetOrCreateObservedDocShellsList().insertFront(aObservedPtr.get());
|
||||
}
|
||||
|
||||
void
|
||||
TimelineConsumers::RemoveConsumer(nsDocShell* aDocShell,
|
||||
UniquePtr<ObservedDocShell>& aObservedPtr)
|
||||
{
|
||||
MOZ_ASSERT(aObservedPtr);
|
||||
sActiveConsumers--;
|
||||
aObservedPtr.get()->remove();
|
||||
aObservedPtr.reset(nullptr);
|
||||
}
|
||||
|
||||
bool
|
||||
@ -28,4 +46,20 @@ 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;
|
||||
}
|
||||
|
||||
} // namespace mozilla
|
||||
|
@ -7,24 +7,29 @@
|
||||
#ifndef mozilla_TimelineConsumers_h_
|
||||
#define mozilla_TimelineConsumers_h_
|
||||
|
||||
#include "mozilla/LinkedList.h"
|
||||
#include "mozilla/UniquePtr.h"
|
||||
#include "timeline/ObservedDocShell.h"
|
||||
|
||||
class nsDocShell;
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
// # TimelineConsumers
|
||||
//
|
||||
// A class to trace how many frontends are interested in markers. Whenever
|
||||
// interest is expressed in markers, these fields will keep track of that.
|
||||
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();
|
||||
static void RemoveConsumer();
|
||||
static void AddConsumer(nsDocShell* aDocShell,
|
||||
UniquePtr<ObservedDocShell>& aObservedPtr);
|
||||
static void RemoveConsumer(nsDocShell* aDocShell,
|
||||
UniquePtr<ObservedDocShell>& aObservedPtr);
|
||||
static bool IsEmpty();
|
||||
static bool GetKnownDocShells(Vector<nsRefPtr<nsDocShell>>& aStore);
|
||||
};
|
||||
|
||||
} // namespace mozilla
|
||||
|
@ -13,6 +13,7 @@ EXPORTS.mozilla += [
|
||||
UNIFIED_SOURCES += [
|
||||
'AutoGlobalTimelineMarker.cpp',
|
||||
'AutoTimelineMarker.cpp',
|
||||
'ObservedDocShell.cpp',
|
||||
'TimelineConsumers.cpp',
|
||||
'TimelineMarker.cpp',
|
||||
]
|
||||
|
Loading…
Reference in New Issue
Block a user