mirror of
https://github.com/roytam1/palemoon27.git
synced 2026-05-29 19:11:47 +00:00
import changes from `dev' branch of rmottola/Arctic-Fox:
- Bug 1158344 part 1 - Use the an instruction which is not a beta node for hoisting bounds checks. r=sunfish (2174d2c83) - Bug 1158344 part 2 - Do not produce upper bounds check if the condition is always verified. r=sunfish (dd93b1595) - Bug 1160911 - JIT: precise shift right derived result range for all int32 input ranges. r=sunfish (87589affe) - Bug 1055473 - Make WeakMap/Set.prototype a plain object. r=Waldo (07835bfde) - Bug 1055473 - Actually disable the web-platform test ON CLOSED TREE (3e8601a23) - Bug 1157239 - Give MGuardShape and friends a resultTypeSet. r=h4writer (63b4fedb7) - Bug 1124870 - Use LookupPropertyPure instead of LookupProperty in IsCacheableDOMProxyUnshadowedSetterCall. r=evilpie (57dc89ac7) - Bug 1162078 - Ignore timeouts for some CGC tests r=terrence DONTBUILD (ac4468c9d) - Bug 967544 - make gServiceInterrupt Atomic; r=Waldo (bb34afcc6) - Bug 1178998 - Identify which hang detector reports a hang. r=billm (b2f9d3184) - Bug 1133391 - Remove unused variables in TabParent::RecvDispatchAfterKeyboardEvent. r=smaug. (a7a9b985f) - Bug 1180125 part 0 - Fix an obvious bug in animation_utils.js; r=dbaron (f5729da0e) - Bug 1183223 - Create a markers directory temporarily inside docshell/base where all marker logic should go into, r=smaug (56b821e0a) - Bug 1183228 - Use separate files for AutoTimelineMarker and AutoGlobalTimelineMarker, r=smaug (38fbe5409) - Bug 1183229 - Add a way to count the number of timeline-observed docshells outside of nsDocShell, r=smaug (ee6e7d081) - Bug 1183231 - Maintain a list of timeline-observed docshells outside of nsDocShell, r=smaug (b2f6a778b) - Bug 1183235 - Keep the dochsell-specific markers inside a ObservedDocShell managed list instead of nsDocShell, r=smaug (50d45b9b2) - Bug 1137109 move the displaylist tracing inside nsViewManager::ProcessPendingUpdates, r=benwa, mattwoodrow (2bebfe820) - Bug 1184376 - Remove nsDocShell::AddProfileTimelineMarker, r=smaug (db31f7621)
This commit is contained in:
@@ -1,105 +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/AutoTimelineMarker.h"
|
|
||||||
|
|
||||||
#include "MainThreadUtils.h"
|
|
||||||
#include "nsDocShell.h"
|
|
||||||
#include "mozilla/Move.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)
|
|
||||||
: mDocShell(nullptr)
|
|
||||||
, mName(aName)
|
|
||||||
{
|
|
||||||
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
|
|
||||||
MOZ_ASSERT(NS_IsMainThread());
|
|
||||||
|
|
||||||
nsDocShell* docShell = static_cast<nsDocShell*>(aDocShell);
|
|
||||||
if (docShell && DocShellIsRecording(*docShell)) {
|
|
||||||
mDocShell = docShell;
|
|
||||||
mDocShell->AddProfileTimelineMarker(mName, TRACING_INTERVAL_START);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
AutoTimelineMarker::~AutoTimelineMarker()
|
|
||||||
{
|
|
||||||
if (mDocShell) {
|
|
||||||
mDocShell->AddProfileTimelineMarker(mName, TRACING_INTERVAL_END);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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)
|
|
||||||
, mDocShells()
|
|
||||||
, mName(aName)
|
|
||||||
{
|
|
||||||
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
|
|
||||||
MOZ_ASSERT(NS_IsMainThread());
|
|
||||||
|
|
||||||
if (nsDocShell::gProfileTimelineRecordingsCount == 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
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 (!mOk) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (Vector<nsRefPtr<nsDocShell>>::Range range = mDocShells.all();
|
|
||||||
!range.empty();
|
|
||||||
range.popFront()) {
|
|
||||||
range.front()->AddProfileTimelineMarker(mName, TRACING_INTERVAL_END);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
} // namespace mozilla
|
|
||||||
@@ -4,6 +4,10 @@
|
|||||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
# 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/.
|
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
|
||||||
|
DIRS += [
|
||||||
|
'timeline',
|
||||||
|
]
|
||||||
|
|
||||||
XPIDL_SOURCES += [
|
XPIDL_SOURCES += [
|
||||||
'nsCDefaultURIFixup.idl',
|
'nsCDefaultURIFixup.idl',
|
||||||
'nsIClipboardCommands.idl',
|
'nsIClipboardCommands.idl',
|
||||||
@@ -42,13 +46,11 @@ EXPORTS += [
|
|||||||
]
|
]
|
||||||
|
|
||||||
EXPORTS.mozilla += [
|
EXPORTS.mozilla += [
|
||||||
'AutoTimelineMarker.h',
|
|
||||||
'IHistory.h',
|
'IHistory.h',
|
||||||
'LoadContext.h',
|
'LoadContext.h',
|
||||||
]
|
]
|
||||||
|
|
||||||
UNIFIED_SOURCES += [
|
UNIFIED_SOURCES += [
|
||||||
'AutoTimelineMarker.cpp',
|
|
||||||
'LoadContext.cpp',
|
'LoadContext.cpp',
|
||||||
'nsAboutRedirector.cpp',
|
'nsAboutRedirector.cpp',
|
||||||
'nsDefaultURIFixup.cpp',
|
'nsDefaultURIFixup.cpp',
|
||||||
@@ -61,7 +63,6 @@ UNIFIED_SOURCES += [
|
|||||||
'nsDSURIContentListener.cpp',
|
'nsDSURIContentListener.cpp',
|
||||||
'nsWebNavigationInfo.cpp',
|
'nsWebNavigationInfo.cpp',
|
||||||
'SerializedLoadContext.cpp',
|
'SerializedLoadContext.cpp',
|
||||||
'TimelineMarker.cpp',
|
|
||||||
]
|
]
|
||||||
|
|
||||||
include('/ipc/chromium/chromium-config.mozbuild')
|
include('/ipc/chromium/chromium-config.mozbuild')
|
||||||
|
|||||||
@@ -2820,29 +2820,17 @@ nsDocShell::HistoryTransactionRemoved(int32_t aIndex)
|
|||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned long nsDocShell::gProfileTimelineRecordingsCount = 0;
|
|
||||||
|
|
||||||
mozilla::LinkedList<nsDocShell::ObservedDocShell>* nsDocShell::gObservedDocShells = nullptr;
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
nsDocShell::SetRecordProfileTimelineMarkers(bool aValue)
|
nsDocShell::SetRecordProfileTimelineMarkers(bool aValue)
|
||||||
{
|
{
|
||||||
bool currentValue = nsIDocShell::GetRecordProfileTimelineMarkers();
|
bool currentValue = nsIDocShell::GetRecordProfileTimelineMarkers();
|
||||||
if (currentValue != aValue) {
|
if (currentValue != aValue) {
|
||||||
if (aValue) {
|
if (aValue) {
|
||||||
++gProfileTimelineRecordingsCount;
|
TimelineConsumers::AddConsumer(this);
|
||||||
UseEntryScriptProfiling();
|
UseEntryScriptProfiling();
|
||||||
|
|
||||||
MOZ_ASSERT(!mObserved);
|
|
||||||
mObserved.reset(new ObservedDocShell(this));
|
|
||||||
GetOrCreateObservedDocShells().insertFront(mObserved.get());
|
|
||||||
} else {
|
} else {
|
||||||
--gProfileTimelineRecordingsCount;
|
TimelineConsumers::RemoveConsumer(this);
|
||||||
UnuseEntryScriptProfiling();
|
UnuseEntryScriptProfiling();
|
||||||
|
|
||||||
mObserved.reset(nullptr);
|
|
||||||
|
|
||||||
ClearProfileTimelineMarkers();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2873,13 +2861,23 @@ nsDocShell::PopProfileTimelineMarkers(
|
|||||||
SequenceRooter<mozilla::dom::ProfileTimelineMarker> rooter(
|
SequenceRooter<mozilla::dom::ProfileTimelineMarker> rooter(
|
||||||
aCx, &profileTimelineMarkers);
|
aCx, &profileTimelineMarkers);
|
||||||
|
|
||||||
|
if (!IsObserved()) {
|
||||||
|
if (!ToJSValue(aCx, profileTimelineMarkers, aProfileTimelineMarkers)) {
|
||||||
|
JS_ClearPendingException(aCx);
|
||||||
|
return NS_ERROR_UNEXPECTED;
|
||||||
|
}
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsTArray<UniquePtr<TimelineMarker>>& markersStore = mObserved.get()->mTimelineMarkers;
|
||||||
|
|
||||||
// If we see an unpaired START, we keep it around for the next call
|
// If we see an unpaired START, we keep it around for the next call
|
||||||
// to PopProfileTimelineMarkers. We store the kept START objects in
|
// to PopProfileTimelineMarkers. We store the kept START objects in
|
||||||
// this array.
|
// this array.
|
||||||
nsTArray<UniquePtr<TimelineMarker>> keptMarkers;
|
nsTArray<UniquePtr<TimelineMarker>> keptMarkers;
|
||||||
|
|
||||||
for (uint32_t i = 0; i < mProfileTimelineMarkers.Length(); ++i) {
|
for (uint32_t i = 0; i < markersStore.Length(); ++i) {
|
||||||
UniquePtr<TimelineMarker>& startPayload = mProfileTimelineMarkers[i];
|
UniquePtr<TimelineMarker>& startPayload = markersStore[i];
|
||||||
const char* startMarkerName = startPayload->GetName();
|
const char* startMarkerName = startPayload->GetName();
|
||||||
|
|
||||||
bool hasSeenPaintedLayer = false;
|
bool hasSeenPaintedLayer = false;
|
||||||
@@ -2915,8 +2913,8 @@ nsDocShell::PopProfileTimelineMarkers(
|
|||||||
// The assumption is that the devtools timeline flushes markers frequently
|
// The assumption is that the devtools timeline flushes markers frequently
|
||||||
// enough for the amount of markers to always be small enough that the
|
// enough for the amount of markers to always be small enough that the
|
||||||
// nested for loop isn't going to be a performance problem.
|
// nested for loop isn't going to be a performance problem.
|
||||||
for (uint32_t j = i + 1; j < mProfileTimelineMarkers.Length(); ++j) {
|
for (uint32_t j = i + 1; j < markersStore.Length(); ++j) {
|
||||||
UniquePtr<TimelineMarker>& endPayload = mProfileTimelineMarkers[j];
|
UniquePtr<TimelineMarker>& endPayload = markersStore[j];
|
||||||
const char* endMarkerName = endPayload->GetName();
|
const char* endMarkerName = endPayload->GetName();
|
||||||
|
|
||||||
// Look for Layer markers to stream out paint markers.
|
// Look for Layer markers to stream out paint markers.
|
||||||
@@ -2962,14 +2960,14 @@ nsDocShell::PopProfileTimelineMarkers(
|
|||||||
|
|
||||||
// If we did not see the corresponding END, keep the START.
|
// If we did not see the corresponding END, keep the START.
|
||||||
if (!hasSeenEnd) {
|
if (!hasSeenEnd) {
|
||||||
keptMarkers.AppendElement(Move(mProfileTimelineMarkers[i]));
|
keptMarkers.AppendElement(Move(markersStore[i]));
|
||||||
mProfileTimelineMarkers.RemoveElementAt(i);
|
markersStore.RemoveElementAt(i);
|
||||||
--i;
|
--i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mProfileTimelineMarkers.SwapElements(keptMarkers);
|
markersStore.SwapElements(keptMarkers);
|
||||||
|
|
||||||
if (!ToJSValue(aCx, profileTimelineMarkers, aProfileTimelineMarkers)) {
|
if (!ToJSValue(aCx, profileTimelineMarkers, aProfileTimelineMarkers)) {
|
||||||
JS_ClearPendingException(aCx);
|
JS_ClearPendingException(aCx);
|
||||||
@@ -2988,24 +2986,6 @@ nsDocShell::Now(DOMHighResTimeStamp* aWhen)
|
|||||||
return NS_OK;
|
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
|
NS_IMETHODIMP
|
||||||
nsDocShell::SetWindowDraggingAllowed(bool aValue)
|
nsDocShell::SetWindowDraggingAllowed(bool aValue)
|
||||||
{
|
{
|
||||||
@@ -3035,12 +3015,6 @@ nsDocShell::GetWindowDraggingAllowed(bool* aValue)
|
|||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
nsDocShell::ClearProfileTimelineMarkers()
|
|
||||||
{
|
|
||||||
mProfileTimelineMarkers.Clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
nsIDOMStorageManager*
|
nsIDOMStorageManager*
|
||||||
nsDocShell::TopSessionStorageManager()
|
nsDocShell::TopSessionStorageManager()
|
||||||
{
|
{
|
||||||
@@ -14082,7 +14056,7 @@ nsDocShell::NotifyJSRunToCompletionStart(const char* aReason,
|
|||||||
MakeUnique<JavascriptTimelineMarker>(this, "Javascript", aReason,
|
MakeUnique<JavascriptTimelineMarker>(this, "Javascript", aReason,
|
||||||
aFunctionName, aFilename,
|
aFunctionName, aFilename,
|
||||||
aLineNumber);
|
aLineNumber);
|
||||||
AddProfileTimelineMarker(Move(marker));
|
TimelineConsumers::AddMarkerForDocShell(this, Move(marker));
|
||||||
}
|
}
|
||||||
mJSRunToCompletionDepth++;
|
mJSRunToCompletionDepth++;
|
||||||
}
|
}
|
||||||
@@ -14095,7 +14069,7 @@ nsDocShell::NotifyJSRunToCompletionStop()
|
|||||||
// If last stop, mark interval end.
|
// If last stop, mark interval end.
|
||||||
mJSRunToCompletionDepth--;
|
mJSRunToCompletionDepth--;
|
||||||
if (timelineOn && mJSRunToCompletionDepth == 0) {
|
if (timelineOn && mJSRunToCompletionDepth == 0) {
|
||||||
AddProfileTimelineMarker("Javascript", TRACING_INTERVAL_END);
|
TimelineConsumers::AddMarkerForDocShell(this, "Javascript", TRACING_INTERVAL_END);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+17
-49
@@ -33,7 +33,9 @@
|
|||||||
#include "nsAutoPtr.h"
|
#include "nsAutoPtr.h"
|
||||||
#include "nsThreadUtils.h"
|
#include "nsThreadUtils.h"
|
||||||
#include "nsContentUtils.h"
|
#include "nsContentUtils.h"
|
||||||
#include "TimelineMarker.h"
|
#include "timeline/TimelineMarker.h"
|
||||||
|
#include "timeline/TimelineConsumers.h"
|
||||||
|
#include "timeline/ObservedDocShell.h"
|
||||||
|
|
||||||
// Threshold value in ms for META refresh based redirects
|
// Threshold value in ms for META refresh based redirects
|
||||||
#define REFRESH_REDIRECT_TIMER 15000
|
#define REFRESH_REDIRECT_TIMER 15000
|
||||||
@@ -260,53 +262,24 @@ public:
|
|||||||
// is no longer applied
|
// is no longer applied
|
||||||
void NotifyAsyncPanZoomStopped();
|
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:
|
private:
|
||||||
static mozilla::LinkedList<ObservedDocShell>* gObservedDocShells;
|
// An observed docshell wrapper is created when recording markers is enabled.
|
||||||
|
mozilla::UniquePtr<mozilla::ObservedDocShell> mObserved;
|
||||||
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; }
|
bool IsObserved() const { return !!mObserved; }
|
||||||
|
|
||||||
public:
|
// It is necessary to allow adding a timeline marker wherever a docshell
|
||||||
static const mozilla::LinkedList<ObservedDocShell>& GetObservedDocShells()
|
// 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
|
||||||
return GetOrCreateObservedDocShells();
|
// 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:
|
||||||
// Tell the favicon service that aNewURI has the same favicon as aOldURI.
|
// Tell the favicon service that aNewURI has the same favicon as aOldURI.
|
||||||
static void CopyFavicon(nsIURI* aOldURI,
|
static void CopyFavicon(nsIURI* aOldURI,
|
||||||
nsIURI* aNewURI,
|
nsIURI* aNewURI,
|
||||||
@@ -1020,11 +993,6 @@ private:
|
|||||||
// has been called without a matching NotifyRunToCompletionStop.
|
// has been called without a matching NotifyRunToCompletionStop.
|
||||||
uint32_t mJSRunToCompletionDepth;
|
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.)
|
// Separate function to do the actual name (i.e. not _top, _self etc.)
|
||||||
// searching for FindItemWithName.
|
// searching for FindItemWithName.
|
||||||
nsresult DoFindItemWithName(const char16_t* aName,
|
nsresult DoFindItemWithName(const char16_t* aName,
|
||||||
|
|||||||
@@ -0,0 +1,37 @@
|
|||||||
|
/* -*- 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/AutoGlobalTimelineMarker.h"
|
||||||
|
|
||||||
|
#include "mozilla/TimelineConsumers.h"
|
||||||
|
#include "MainThreadUtils.h"
|
||||||
|
|
||||||
|
namespace mozilla {
|
||||||
|
|
||||||
|
AutoGlobalTimelineMarker::AutoGlobalTimelineMarker(const char* aName
|
||||||
|
MOZ_GUARD_OBJECT_NOTIFIER_PARAM_IN_IMPL)
|
||||||
|
: mName(aName)
|
||||||
|
{
|
||||||
|
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
|
||||||
|
MOZ_ASSERT(NS_IsMainThread());
|
||||||
|
|
||||||
|
if (TimelineConsumers::IsEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
TimelineConsumers::AddMarkerToAllObservedDocShells(mName, TRACING_INTERVAL_START);
|
||||||
|
}
|
||||||
|
|
||||||
|
AutoGlobalTimelineMarker::~AutoGlobalTimelineMarker()
|
||||||
|
{
|
||||||
|
if (TimelineConsumers::IsEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
TimelineConsumers::AddMarkerToAllObservedDocShells(mName, TRACING_INTERVAL_END);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace mozilla
|
||||||
+3
-46
@@ -4,50 +4,16 @@
|
|||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* 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/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
#ifndef AutoTimelineMarker_h__
|
#ifndef mozilla_AutoGlobalTimelineMarker_h_
|
||||||
#define AutoTimelineMarker_h__
|
#define mozilla_AutoGlobalTimelineMarker_h_
|
||||||
|
|
||||||
#include "mozilla/GuardObjects.h"
|
#include "mozilla/GuardObjects.h"
|
||||||
#include "mozilla/Vector.h"
|
|
||||||
|
|
||||||
#include "nsRefPtr.h"
|
#include "nsRefPtr.h"
|
||||||
|
|
||||||
class nsIDocShell;
|
|
||||||
class nsDocShell;
|
class nsDocShell;
|
||||||
|
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
|
|
||||||
// # AutoTimelineMarker
|
|
||||||
//
|
|
||||||
// An RAII class to trace some task in the platform by adding a start and end
|
|
||||||
// timeline marker pair. These markers are then rendered in the devtools'
|
|
||||||
// performance tool's waterfall graph.
|
|
||||||
//
|
|
||||||
// Example usage:
|
|
||||||
//
|
|
||||||
// {
|
|
||||||
// AutoTimelineMarker marker(mDocShell, "Parse CSS");
|
|
||||||
// nsresult rv = ParseTheCSSFile(mFile);
|
|
||||||
// ...
|
|
||||||
// }
|
|
||||||
class MOZ_STACK_CLASS AutoTimelineMarker
|
|
||||||
{
|
|
||||||
MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER;
|
|
||||||
|
|
||||||
nsRefPtr<nsDocShell> mDocShell;
|
|
||||||
const char* mName;
|
|
||||||
|
|
||||||
bool DocShellIsRecording(nsDocShell& aDocShell);
|
|
||||||
|
|
||||||
public:
|
|
||||||
explicit AutoTimelineMarker(nsIDocShell* aDocShell, const char* aName
|
|
||||||
MOZ_GUARD_OBJECT_NOTIFIER_PARAM);
|
|
||||||
~AutoTimelineMarker();
|
|
||||||
|
|
||||||
AutoTimelineMarker(const AutoTimelineMarker& aOther) = delete;
|
|
||||||
void operator=(const AutoTimelineMarker& aOther) = delete;
|
|
||||||
};
|
|
||||||
|
|
||||||
// # AutoGlobalTimelineMarker
|
// # AutoGlobalTimelineMarker
|
||||||
//
|
//
|
||||||
// Similar to `AutoTimelineMarker`, but adds its traced marker to all docshells,
|
// Similar to `AutoTimelineMarker`, but adds its traced marker to all docshells,
|
||||||
@@ -67,21 +33,12 @@ class MOZ_STACK_CLASS AutoGlobalTimelineMarker
|
|||||||
{
|
{
|
||||||
MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER;
|
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.
|
// The name of the marker we are adding.
|
||||||
const char* mName;
|
const char* mName;
|
||||||
|
|
||||||
void PopulateDocShells();
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit AutoGlobalTimelineMarker(const char* aName
|
explicit AutoGlobalTimelineMarker(const char* aName
|
||||||
MOZ_GUARD_OBJECT_NOTIFIER_PARAM);
|
MOZ_GUARD_OBJECT_NOTIFIER_PARAM);
|
||||||
|
|
||||||
~AutoGlobalTimelineMarker();
|
~AutoGlobalTimelineMarker();
|
||||||
|
|
||||||
AutoGlobalTimelineMarker(const AutoGlobalTimelineMarker& aOther) = delete;
|
AutoGlobalTimelineMarker(const AutoGlobalTimelineMarker& aOther) = delete;
|
||||||
@@ -90,4 +47,4 @@ public:
|
|||||||
|
|
||||||
} // namespace mozilla
|
} // namespace mozilla
|
||||||
|
|
||||||
#endif /* AutoTimelineMarker_h__ */
|
#endif /* mozilla_AutoGlobalTimelineMarker_h_ */
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
/* -*- 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/AutoTimelineMarker.h"
|
||||||
|
|
||||||
|
#include "mozilla/TimelineConsumers.h"
|
||||||
|
#include "MainThreadUtils.h"
|
||||||
|
#include "nsDocShell.h"
|
||||||
|
|
||||||
|
namespace mozilla {
|
||||||
|
|
||||||
|
AutoTimelineMarker::AutoTimelineMarker(nsIDocShell* aDocShell, const char* aName
|
||||||
|
MOZ_GUARD_OBJECT_NOTIFIER_PARAM_IN_IMPL)
|
||||||
|
: mName(aName)
|
||||||
|
, mDocShell(nullptr)
|
||||||
|
{
|
||||||
|
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
|
||||||
|
MOZ_ASSERT(NS_IsMainThread());
|
||||||
|
|
||||||
|
if (!aDocShell || TimelineConsumers::IsEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
mDocShell = static_cast<nsDocShell*>(aDocShell);
|
||||||
|
TimelineConsumers::AddMarkerForDocShell(mDocShell, mName, TRACING_INTERVAL_START);
|
||||||
|
}
|
||||||
|
|
||||||
|
AutoTimelineMarker::~AutoTimelineMarker()
|
||||||
|
{
|
||||||
|
if (!mDocShell || TimelineConsumers::IsEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
TimelineConsumers::AddMarkerForDocShell(mDocShell, mName, TRACING_INTERVAL_END);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace mozilla
|
||||||
@@ -0,0 +1,52 @@
|
|||||||
|
/* -*- 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_AutoTimelineMarker_h_
|
||||||
|
#define mozilla_AutoTimelineMarker_h_
|
||||||
|
|
||||||
|
#include "mozilla/GuardObjects.h"
|
||||||
|
#include "nsRefPtr.h"
|
||||||
|
|
||||||
|
class nsIDocShell;
|
||||||
|
class nsDocShell;
|
||||||
|
|
||||||
|
namespace mozilla {
|
||||||
|
|
||||||
|
// # AutoTimelineMarker
|
||||||
|
//
|
||||||
|
// An RAII class to trace some task in the platform by adding a start and end
|
||||||
|
// timeline marker pair. These markers are then rendered in the devtools'
|
||||||
|
// performance tool's waterfall graph.
|
||||||
|
//
|
||||||
|
// Example usage:
|
||||||
|
//
|
||||||
|
// {
|
||||||
|
// AutoTimelineMarker marker(mDocShell, "Parse CSS");
|
||||||
|
// nsresult rv = ParseTheCSSFile(mFile);
|
||||||
|
// ...
|
||||||
|
// }
|
||||||
|
class MOZ_STACK_CLASS AutoTimelineMarker
|
||||||
|
{
|
||||||
|
MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER;
|
||||||
|
|
||||||
|
// The name of the marker we are adding.
|
||||||
|
const char* mName;
|
||||||
|
|
||||||
|
// The docshell that is associated with this marker.
|
||||||
|
nsRefPtr<nsDocShell> mDocShell;
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit AutoTimelineMarker(nsIDocShell* aDocShell, const char* aName
|
||||||
|
MOZ_GUARD_OBJECT_NOTIFIER_PARAM);
|
||||||
|
~AutoTimelineMarker();
|
||||||
|
|
||||||
|
AutoTimelineMarker(const AutoTimelineMarker& aOther) = delete;
|
||||||
|
void operator=(const AutoTimelineMarker& aOther) = delete;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace mozilla
|
||||||
|
|
||||||
|
#endif /* mozilla_AutoTimelineMarker_h_ */
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
/* -*- 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"
|
||||||
|
|
||||||
|
namespace mozilla {
|
||||||
|
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace mozilla
|
||||||
@@ -0,0 +1,43 @@
|
|||||||
|
/* -*- 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 "mozilla/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;
|
||||||
|
|
||||||
|
public:
|
||||||
|
// FIXME: make this private once all marker-specific logic has been
|
||||||
|
// moved out of nsDocShell.
|
||||||
|
nsTArray<UniquePtr<TimelineMarker>> mTimelineMarkers;
|
||||||
|
|
||||||
|
explicit ObservedDocShell(nsDocShell* aDocShell);
|
||||||
|
nsDocShell* operator*() const { return mDocShell.get(); }
|
||||||
|
|
||||||
|
void AddMarker(const char* aName, TracingMetadata aMetaData);
|
||||||
|
void AddMarker(UniquePtr<TimelineMarker>&& aMarker);
|
||||||
|
void ClearMarkers();
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace mozilla
|
||||||
|
|
||||||
|
#endif /* ObservedDocShell_h_ */
|
||||||
@@ -0,0 +1,110 @@
|
|||||||
|
/* -*- 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
|
||||||
@@ -0,0 +1,47 @@
|
|||||||
|
/* -*- 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_ */
|
||||||
@@ -4,8 +4,8 @@
|
|||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* 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/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
#ifndef TimelineMarker_h__
|
#ifndef TimelineMarker_h_
|
||||||
#define TimelineMarker_h__
|
#define TimelineMarker_h_
|
||||||
|
|
||||||
#include "nsString.h"
|
#include "nsString.h"
|
||||||
#include "GeckoProfiler.h"
|
#include "GeckoProfiler.h"
|
||||||
@@ -96,4 +96,4 @@ private:
|
|||||||
JS::PersistentRooted<JSObject*> mStackTrace;
|
JS::PersistentRooted<JSObject*> mStackTrace;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* TimelineMarker_h__ */
|
#endif /* TimelineMarker_h_ */
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
|
||||||
|
# vim: set filetype=python:
|
||||||
|
# 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/.
|
||||||
|
|
||||||
|
EXPORTS.mozilla += [
|
||||||
|
'AutoGlobalTimelineMarker.h',
|
||||||
|
'AutoTimelineMarker.h',
|
||||||
|
'TimelineConsumers.h',
|
||||||
|
]
|
||||||
|
|
||||||
|
UNIFIED_SOURCES += [
|
||||||
|
'AutoGlobalTimelineMarker.cpp',
|
||||||
|
'AutoTimelineMarker.cpp',
|
||||||
|
'ObservedDocShell.cpp',
|
||||||
|
'TimelineConsumers.cpp',
|
||||||
|
'TimelineMarker.cpp',
|
||||||
|
]
|
||||||
|
|
||||||
|
FINAL_LIBRARY = 'xul'
|
||||||
|
|
||||||
|
LOCAL_INCLUDES += [
|
||||||
|
'/docshell/base'
|
||||||
|
]
|
||||||
@@ -1135,7 +1135,7 @@ Console::Method(JSContext* aCx, MethodName aMethodName,
|
|||||||
|
|
||||||
mozilla::UniquePtr<TimelineMarker> marker =
|
mozilla::UniquePtr<TimelineMarker> marker =
|
||||||
MakeUnique<TimestampTimelineMarker>(docShell, TRACING_TIMESTAMP, key);
|
MakeUnique<TimestampTimelineMarker>(docShell, TRACING_TIMESTAMP, key);
|
||||||
docShell->AddProfileTimelineMarker(Move(marker));
|
TimelineConsumers::AddMarkerForDocShell(docShell, Move(marker));
|
||||||
}
|
}
|
||||||
// For `console.time(foo)` and `console.timeEnd(foo)`
|
// For `console.time(foo)` and `console.timeEnd(foo)`
|
||||||
else if (isTimelineRecording && aData.Length() == 1) {
|
else if (isTimelineRecording && aData.Length() == 1) {
|
||||||
@@ -1148,7 +1148,7 @@ Console::Method(JSContext* aCx, MethodName aMethodName,
|
|||||||
MakeUnique<ConsoleTimelineMarker>(docShell,
|
MakeUnique<ConsoleTimelineMarker>(docShell,
|
||||||
aMethodName == MethodTime ? TRACING_INTERVAL_START : TRACING_INTERVAL_END,
|
aMethodName == MethodTime ? TRACING_INTERVAL_START : TRACING_INTERVAL_END,
|
||||||
key);
|
key);
|
||||||
docShell->AddProfileTimelineMarker(Move(marker));
|
TimelineConsumers::AddMarkerForDocShell(docShell, Move(marker));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,6 +23,7 @@
|
|||||||
#include "mozilla/dom/BindingUtils.h"
|
#include "mozilla/dom/BindingUtils.h"
|
||||||
#include "mozilla/dom/Element.h"
|
#include "mozilla/dom/Element.h"
|
||||||
#include "mozilla/dom/Event.h"
|
#include "mozilla/dom/Event.h"
|
||||||
|
#include "mozilla/TimelineConsumers.h"
|
||||||
|
|
||||||
#include "EventListenerService.h"
|
#include "EventListenerService.h"
|
||||||
#include "nsCOMArray.h"
|
#include "nsCOMArray.h"
|
||||||
@@ -1124,7 +1125,7 @@ EventListenerManager::HandleEventInternal(nsPresContext* aPresContext,
|
|||||||
nsCOMPtr<nsIDocShell> docShell;
|
nsCOMPtr<nsIDocShell> docShell;
|
||||||
bool isTimelineRecording = false;
|
bool isTimelineRecording = false;
|
||||||
if (mIsMainThreadELM &&
|
if (mIsMainThreadELM &&
|
||||||
nsDocShell::gProfileTimelineRecordingsCount > 0 &&
|
!TimelineConsumers::IsEmpty() &&
|
||||||
listener->mListenerType != Listener::eNativeListener) {
|
listener->mListenerType != Listener::eNativeListener) {
|
||||||
docShell = GetDocShellForTarget();
|
docShell = GetDocShellForTarget();
|
||||||
if (docShell) {
|
if (docShell) {
|
||||||
@@ -1139,7 +1140,7 @@ EventListenerManager::HandleEventInternal(nsPresContext* aPresContext,
|
|||||||
mozilla::UniquePtr<TimelineMarker> marker =
|
mozilla::UniquePtr<TimelineMarker> marker =
|
||||||
MakeUnique<EventTimelineMarker>(ds, TRACING_INTERVAL_START,
|
MakeUnique<EventTimelineMarker>(ds, TRACING_INTERVAL_START,
|
||||||
phase, typeStr);
|
phase, typeStr);
|
||||||
ds->AddProfileTimelineMarker(Move(marker));
|
TimelineConsumers::AddMarkerForDocShell(ds, Move(marker));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1150,7 +1151,7 @@ EventListenerManager::HandleEventInternal(nsPresContext* aPresContext,
|
|||||||
|
|
||||||
if (isTimelineRecording) {
|
if (isTimelineRecording) {
|
||||||
nsDocShell* ds = static_cast<nsDocShell*>(docShell.get());
|
nsDocShell* ds = static_cast<nsDocShell*>(docShell.get());
|
||||||
ds->AddProfileTimelineMarker("DOMEvent", TRACING_INTERVAL_END);
|
TimelineConsumers::AddMarkerForDocShell(ds, "DOMEvent", TRACING_INTERVAL_END);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,5 +3,6 @@
|
|||||||
"WeakMap.prototype.delete.length": true,
|
"WeakMap.prototype.delete.length": true,
|
||||||
"WeakMap.prototype.get.length": true,
|
"WeakMap.prototype.get.length": true,
|
||||||
"WeakMap.prototype.has.length": true,
|
"WeakMap.prototype.has.length": true,
|
||||||
"WeakMap.prototype.set.length": true
|
"WeakMap.prototype.set.length": true,
|
||||||
|
"WeakMap.prototype.@@toStringTag": true
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -817,7 +817,8 @@ HangMonitoredProcess::TerminatePlugin()
|
|||||||
}
|
}
|
||||||
|
|
||||||
uint32_t id = mHangData.get_PluginHangData().pluginId();
|
uint32_t id = mHangData.get_PluginHangData().pluginId();
|
||||||
plugins::TerminatePlugin(id, mBrowserDumpId);
|
plugins::TerminatePlugin(id, NS_LITERAL_CSTRING("HangMonitor"),
|
||||||
|
mBrowserDumpId);
|
||||||
|
|
||||||
if (mActor) {
|
if (mActor) {
|
||||||
mActor->CleanupPluginHang(id, false);
|
mActor->CleanupPluginHang(id, false);
|
||||||
|
|||||||
@@ -2258,7 +2258,6 @@ TabParent::RecvDispatchAfterKeyboardEvent(const WidgetKeyboardEvent& aEvent)
|
|||||||
if (mFrameElement &&
|
if (mFrameElement &&
|
||||||
PresShell::BeforeAfterKeyboardEventEnabled() &&
|
PresShell::BeforeAfterKeyboardEventEnabled() &&
|
||||||
localEvent.message != NS_KEY_PRESS) {
|
localEvent.message != NS_KEY_PRESS) {
|
||||||
nsCOMPtr<nsINode> node(do_QueryInterface(mFrameElement));
|
|
||||||
presShell->DispatchAfterKeyboardEvent(mFrameElement, localEvent,
|
presShell->DispatchAfterKeyboardEvent(mFrameElement, localEvent,
|
||||||
aEvent.mFlags.mDefaultPrevented);
|
aEvent.mFlags.mDefaultPrevented);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,7 +25,9 @@ FindPluginsForContent(uint32_t aPluginEpoch,
|
|||||||
uint32_t* aNewPluginEpoch);
|
uint32_t* aNewPluginEpoch);
|
||||||
|
|
||||||
void
|
void
|
||||||
TerminatePlugin(uint32_t aPluginId, const nsString& aBrowserDumpId);
|
TerminatePlugin(uint32_t aPluginId,
|
||||||
|
const nsCString& aMonitorDescription,
|
||||||
|
const nsAString& aBrowserDumpId);
|
||||||
|
|
||||||
} // namespace plugins
|
} // namespace plugins
|
||||||
} // namespace mozilla
|
} // namespace mozilla
|
||||||
|
|||||||
@@ -353,7 +353,9 @@ PluginHangUIParent::RecvUserResponse(const unsigned int& aResponse)
|
|||||||
int responseCode;
|
int responseCode;
|
||||||
if (aResponse & HANGUI_USER_RESPONSE_STOP) {
|
if (aResponse & HANGUI_USER_RESPONSE_STOP) {
|
||||||
// User clicked Stop
|
// User clicked Stop
|
||||||
mModule->TerminateChildProcess(mMainThreadMessageLoop, EmptyString());
|
mModule->TerminateChildProcess(mMainThreadMessageLoop,
|
||||||
|
NS_LITERAL_CSTRING("ModalHangUI"),
|
||||||
|
EmptyString());
|
||||||
responseCode = 1;
|
responseCode = 1;
|
||||||
} else if(aResponse & HANGUI_USER_RESPONSE_CONTINUE) {
|
} else if(aResponse & HANGUI_USER_RESPONSE_CONTINUE) {
|
||||||
mModule->OnHangUIContinue();
|
mModule->OnHangUIContinue();
|
||||||
|
|||||||
@@ -347,7 +347,9 @@ bool PluginModuleMapping::sIsLoadModuleOnStack = false;
|
|||||||
} // anonymous namespace
|
} // anonymous namespace
|
||||||
|
|
||||||
void
|
void
|
||||||
mozilla::plugins::TerminatePlugin(uint32_t aPluginId, const nsString& aBrowserDumpId)
|
mozilla::plugins::TerminatePlugin(uint32_t aPluginId,
|
||||||
|
const nsCString& aMonitorDescription,
|
||||||
|
const nsAString& aBrowserDumpId)
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(XRE_IsParentProcess());
|
MOZ_ASSERT(XRE_IsParentProcess());
|
||||||
|
|
||||||
@@ -357,8 +359,11 @@ mozilla::plugins::TerminatePlugin(uint32_t aPluginId, const nsString& aBrowserDu
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
nsRefPtr<nsNPAPIPlugin> plugin = pluginTag->mPlugin;
|
nsRefPtr<nsNPAPIPlugin> plugin = pluginTag->mPlugin;
|
||||||
PluginModuleChromeParent* chromeParent = static_cast<PluginModuleChromeParent*>(plugin->GetLibrary());
|
PluginModuleChromeParent* chromeParent =
|
||||||
chromeParent->TerminateChildProcess(MessageLoop::current(), aBrowserDumpId);
|
static_cast<PluginModuleChromeParent*>(plugin->GetLibrary());
|
||||||
|
chromeParent->TerminateChildProcess(MessageLoop::current(),
|
||||||
|
aMonitorDescription,
|
||||||
|
aBrowserDumpId);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* static */ PluginLibrary*
|
/* static */ PluginLibrary*
|
||||||
@@ -1057,7 +1062,9 @@ PluginModuleChromeParent::ShouldContinueFromReplyTimeout()
|
|||||||
// original plugin hang behaviour and kill the plugin container.
|
// original plugin hang behaviour and kill the plugin container.
|
||||||
FinishHangUI();
|
FinishHangUI();
|
||||||
#endif // XP_WIN
|
#endif // XP_WIN
|
||||||
TerminateChildProcess(MessageLoop::current(), EmptyString());
|
TerminateChildProcess(MessageLoop::current(),
|
||||||
|
NS_LITERAL_CSTRING("ModalHangUI"),
|
||||||
|
EmptyString());
|
||||||
GetIPCChannel()->CloseWithTimeout();
|
GetIPCChannel()->CloseWithTimeout();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -1081,6 +1088,7 @@ PluginModuleContentParent::OnExitedSyncSend()
|
|||||||
|
|
||||||
void
|
void
|
||||||
PluginModuleChromeParent::TerminateChildProcess(MessageLoop* aMsgLoop,
|
PluginModuleChromeParent::TerminateChildProcess(MessageLoop* aMsgLoop,
|
||||||
|
const nsCString& aMonitorDescription,
|
||||||
const nsAString& aBrowserDumpId)
|
const nsAString& aBrowserDumpId)
|
||||||
{
|
{
|
||||||
mozilla::ipc::ScopedProcessHandle geckoChildProcess;
|
mozilla::ipc::ScopedProcessHandle geckoChildProcess;
|
||||||
|
|||||||
@@ -361,12 +361,17 @@ class PluginModuleChromeParent
|
|||||||
*
|
*
|
||||||
* @param aMsgLoop the main message pump associated with the module
|
* @param aMsgLoop the main message pump associated with the module
|
||||||
* protocol.
|
* protocol.
|
||||||
|
* @param aMonitorDescription a string describing the hang monitor that
|
||||||
|
* is making this call. This string is added to the crash reporter
|
||||||
|
* annotations for the plugin process.
|
||||||
* @param aBrowserDumpId (optional) previously taken browser dump id. If
|
* @param aBrowserDumpId (optional) previously taken browser dump id. If
|
||||||
* provided TerminateChildProcess will use this browser dump file in
|
* provided TerminateChildProcess will use this browser dump file in
|
||||||
* generating a multi-process crash report. If not provided a browser
|
* generating a multi-process crash report. If not provided a browser
|
||||||
* dump will be taken at the time of this call.
|
* dump will be taken at the time of this call.
|
||||||
*/
|
*/
|
||||||
void TerminateChildProcess(MessageLoop* aMsgLoop, const nsAString& aBrowserDumpId);
|
void TerminateChildProcess(MessageLoop* aMsgLoop,
|
||||||
|
const nsCString& aMonitorDescription,
|
||||||
|
const nsAString& aBrowserDumpId);
|
||||||
|
|
||||||
#ifdef XP_WIN
|
#ifdef XP_WIN
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -45,11 +45,9 @@ JSObject*
|
|||||||
WeakSetObject::initClass(JSContext* cx, JSObject* obj)
|
WeakSetObject::initClass(JSContext* cx, JSObject* obj)
|
||||||
{
|
{
|
||||||
Rooted<GlobalObject*> global(cx, &obj->as<GlobalObject>());
|
Rooted<GlobalObject*> global(cx, &obj->as<GlobalObject>());
|
||||||
// Todo: WeakSet.prototype should not be a WeakSet!
|
RootedPlainObject proto(cx, NewBuiltinClassInstance<PlainObject>(cx));
|
||||||
Rooted<WeakSetObject*> proto(cx, global->createBlankPrototype<WeakSetObject>(cx));
|
|
||||||
if (!proto)
|
if (!proto)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
proto->setReservedSlot(WEAKSET_MAP_SLOT, UndefinedValue());
|
|
||||||
|
|
||||||
Rooted<JSFunction*> ctor(cx, global->createConstructor(cx, construct, ClassName(JSProto_WeakSet, cx), 0));
|
Rooted<JSFunction*> ctor(cx, global->createConstructor(cx, construct, ClassName(JSProto_WeakSet, cx), 0));
|
||||||
if (!ctor ||
|
if (!ctor ||
|
||||||
|
|||||||
@@ -1,10 +1,13 @@
|
|||||||
asm.js/testParallelCompile.js
|
asm.js/testParallelCompile.js
|
||||||
auto-regress/bug653395.js
|
auto-regress/bug653395.js
|
||||||
|
auto-regress/bug654392.js
|
||||||
auto-regress/bug675251.js
|
auto-regress/bug675251.js
|
||||||
baseline/bug847446.js
|
baseline/bug847446.js
|
||||||
baseline/bug852175.js
|
baseline/bug852175.js
|
||||||
basic/bug632964-regexp.js
|
basic/bug632964-regexp.js
|
||||||
|
basic/bug656261.js
|
||||||
basic/bug677957-2.js
|
basic/bug677957-2.js
|
||||||
|
basic/bug753283.js
|
||||||
basic/testBug614653.js
|
basic/testBug614653.js
|
||||||
basic/testBug686274.js
|
basic/testBug686274.js
|
||||||
basic/testTypedArrayInit.js
|
basic/testTypedArrayInit.js
|
||||||
|
|||||||
@@ -11,12 +11,12 @@ assertEq(WeakMap.length, 0);
|
|||||||
assertEq(WeakMap.name, "WeakMap");
|
assertEq(WeakMap.name, "WeakMap");
|
||||||
|
|
||||||
assertEq(Object.getPrototypeOf(WeakMap.prototype), Object.prototype);
|
assertEq(Object.getPrototypeOf(WeakMap.prototype), Object.prototype);
|
||||||
assertEq(Object.prototype.toString.call(WeakMap.prototype), "[object WeakMap]");
|
assertEq(Object.prototype.toString.call(WeakMap.prototype), "[object Object]");
|
||||||
assertEq(Object.prototype.toString.call(new WeakMap()), "[object WeakMap]");
|
assertEq(Object.prototype.toString.call(new WeakMap()), "[object WeakMap]");
|
||||||
assertEq(Object.keys(WeakMap.prototype).join(), "");
|
assertEq(Object.keys(WeakMap.prototype).join(), "");
|
||||||
assertEq(WeakMap.prototype.constructor, WeakMap);
|
assertEq(WeakMap.prototype.constructor, WeakMap);
|
||||||
|
|
||||||
function checkMethod(name, arity) {
|
function checkMethod(name, arity) {
|
||||||
var desc = Object.getOwnPropertyDescriptor(WeakMap.prototype, name);
|
var desc = Object.getOwnPropertyDescriptor(WeakMap.prototype, name);
|
||||||
assertEq(desc.enumerable, false);
|
assertEq(desc.enumerable, false);
|
||||||
assertEq(desc.configurable, true);
|
assertEq(desc.configurable, true);
|
||||||
@@ -26,8 +26,7 @@ function checkMethod(name, arity) {
|
|||||||
assertEq(desc.value.length, arity);
|
assertEq(desc.value.length, arity);
|
||||||
}
|
}
|
||||||
|
|
||||||
// XXX: WeakMap#get implementation has an undocumented 2nd argument
|
checkMethod("get", 1);
|
||||||
//checkMethod("get", 1);
|
|
||||||
checkMethod("has", 1);
|
checkMethod("has", 1);
|
||||||
checkMethod("set", 2);
|
checkMethod("set", 2);
|
||||||
checkMethod("delete", 1);
|
checkMethod("delete", 1);
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ assertEq(WeakSet.length, 0);
|
|||||||
assertEq(WeakSet.name, "WeakSet");
|
assertEq(WeakSet.name, "WeakSet");
|
||||||
|
|
||||||
assertEq(Object.getPrototypeOf(WeakSet.prototype), Object.prototype);
|
assertEq(Object.getPrototypeOf(WeakSet.prototype), Object.prototype);
|
||||||
assertEq(Object.prototype.toString.call(WeakSet.prototype), "[object WeakSet]");
|
assertEq(Object.prototype.toString.call(WeakSet.prototype), "[object Object]");
|
||||||
assertEq(Object.prototype.toString.call(new WeakSet), "[object WeakSet]");
|
assertEq(Object.prototype.toString.call(new WeakSet), "[object WeakSet]");
|
||||||
assertEq(Object.keys(WeakSet.prototype).length, 0);
|
assertEq(Object.keys(WeakSet.prototype).length, 0);
|
||||||
assertEq(WeakSet.prototype.constructor, WeakSet);
|
assertEq(WeakSet.prototype.constructor, WeakSet);
|
||||||
|
|||||||
@@ -2668,32 +2668,23 @@ GenerateCallSetter(JSContext* cx, IonScript* ion, MacroAssembler& masm,
|
|||||||
|
|
||||||
static bool
|
static bool
|
||||||
IsCacheableDOMProxyUnshadowedSetterCall(JSContext* cx, HandleObject obj, HandlePropertyName name,
|
IsCacheableDOMProxyUnshadowedSetterCall(JSContext* cx, HandleObject obj, HandlePropertyName name,
|
||||||
MutableHandleObject holder, MutableHandleShape shape,
|
MutableHandleObject holder, MutableHandleShape shape)
|
||||||
bool* isSetter)
|
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(IsCacheableDOMProxy(obj));
|
MOZ_ASSERT(IsCacheableDOMProxy(obj));
|
||||||
|
|
||||||
*isSetter = false;
|
|
||||||
|
|
||||||
RootedObject checkObj(cx, obj->getTaggedProto().toObjectOrNull());
|
RootedObject checkObj(cx, obj->getTaggedProto().toObjectOrNull());
|
||||||
if (!checkObj)
|
if (!checkObj)
|
||||||
return true;
|
return false;
|
||||||
|
|
||||||
if (!LookupProperty(cx, obj, name, holder, shape))
|
if (!LookupPropertyPure(cx, obj, NameToId(name), holder.address(), shape.address()))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (!holder)
|
if (!holder)
|
||||||
return true;
|
return false;
|
||||||
|
|
||||||
if (!IsCacheableSetPropCallNative(checkObj, holder, shape) &&
|
return IsCacheableSetPropCallNative(checkObj, holder, shape) ||
|
||||||
!IsCacheableSetPropCallPropertyOp(checkObj, holder, shape) &&
|
IsCacheableSetPropCallPropertyOp(checkObj, holder, shape) ||
|
||||||
!IsCacheableSetPropCallScripted(checkObj, holder, shape))
|
IsCacheableSetPropCallScripted(checkObj, holder, shape);
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
*isSetter = true;
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
@@ -2717,14 +2708,7 @@ SetPropertyIC::attachDOMProxyUnshadowed(JSContext* cx, HandleScript outerScript,
|
|||||||
RootedPropertyName propName(cx, name());
|
RootedPropertyName propName(cx, name());
|
||||||
RootedObject holder(cx);
|
RootedObject holder(cx);
|
||||||
RootedShape shape(cx);
|
RootedShape shape(cx);
|
||||||
bool isSetter;
|
if (IsCacheableDOMProxyUnshadowedSetterCall(cx, obj, propName, &holder, &shape)) {
|
||||||
if (!IsCacheableDOMProxyUnshadowedSetterCall(cx, obj, propName, &holder,
|
|
||||||
&shape, &isSetter))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isSetter) {
|
|
||||||
if (!GenerateCallSetter(cx, ion, masm, attacher, obj, holder, shape, strict(),
|
if (!GenerateCallSetter(cx, ion, masm, attacher, obj, holder, shape, strict(),
|
||||||
object(), value(), &failures, liveRegs_, returnAddr))
|
object(), value(), &failures, liveRegs_, returnAddr))
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -4464,6 +4464,7 @@ class MGuardObject
|
|||||||
setGuard();
|
setGuard();
|
||||||
setMovable();
|
setMovable();
|
||||||
setResultType(MIRType_Object);
|
setResultType(MIRType_Object);
|
||||||
|
setResultTypeSet(ins->resultTypeSet());
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@@ -4510,6 +4511,7 @@ class MPolyInlineGuard
|
|||||||
{
|
{
|
||||||
setGuard();
|
setGuard();
|
||||||
setResultType(MIRType_Object);
|
setResultType(MIRType_Object);
|
||||||
|
setResultTypeSet(ins->resultTypeSet());
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@@ -10628,6 +10630,7 @@ class MGuardShape
|
|||||||
setGuard();
|
setGuard();
|
||||||
setMovable();
|
setMovable();
|
||||||
setResultType(MIRType_Object);
|
setResultType(MIRType_Object);
|
||||||
|
setResultTypeSet(obj->resultTypeSet());
|
||||||
|
|
||||||
// Disallow guarding on unboxed object shapes. The group is better to
|
// Disallow guarding on unboxed object shapes. The group is better to
|
||||||
// guard on, and guarding on the shape can interact badly with
|
// guard on, and guarding on the shape can interact badly with
|
||||||
@@ -10681,6 +10684,7 @@ class MGuardReceiverPolymorphic
|
|||||||
setGuard();
|
setGuard();
|
||||||
setMovable();
|
setMovable();
|
||||||
setResultType(MIRType_Object);
|
setResultType(MIRType_Object);
|
||||||
|
setResultTypeSet(obj->resultTypeSet());
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|||||||
@@ -1022,7 +1022,32 @@ Range::rsh(TempAllocator& alloc, const Range* lhs, const Range* rhs)
|
|||||||
{
|
{
|
||||||
MOZ_ASSERT(lhs->isInt32());
|
MOZ_ASSERT(lhs->isInt32());
|
||||||
MOZ_ASSERT(rhs->isInt32());
|
MOZ_ASSERT(rhs->isInt32());
|
||||||
return Range::NewInt32Range(alloc, Min(lhs->lower(), 0), Max(lhs->upper(), 0));
|
|
||||||
|
// Canonicalize the shift range to 0 to 31.
|
||||||
|
int32_t shiftLower = rhs->lower();
|
||||||
|
int32_t shiftUpper = rhs->upper();
|
||||||
|
if ((int64_t(shiftUpper) - int64_t(shiftLower)) >= 31) {
|
||||||
|
shiftLower = 0;
|
||||||
|
shiftUpper = 31;
|
||||||
|
} else {
|
||||||
|
shiftLower &= 0x1f;
|
||||||
|
shiftUpper &= 0x1f;
|
||||||
|
if (shiftLower > shiftUpper) {
|
||||||
|
shiftLower = 0;
|
||||||
|
shiftUpper = 31;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
MOZ_ASSERT(shiftLower >= 0 && shiftUpper <= 31);
|
||||||
|
|
||||||
|
// The lhs bounds are signed, thus the minimum is either the lower bound
|
||||||
|
// shift by the smallest shift if negative or the lower bound shifted by the
|
||||||
|
// biggest shift otherwise. And the opposite for the maximum.
|
||||||
|
int32_t lhsLower = lhs->lower();
|
||||||
|
int32_t min = lhsLower < 0 ? lhsLower >> shiftLower : lhsLower >> shiftUpper;
|
||||||
|
int32_t lhsUpper = lhs->upper();
|
||||||
|
int32_t max = lhsUpper >= 0 ? lhsUpper >> shiftLower : lhsUpper >> shiftUpper;
|
||||||
|
|
||||||
|
return Range::NewInt32Range(alloc, min, max);
|
||||||
}
|
}
|
||||||
|
|
||||||
Range*
|
Range*
|
||||||
@@ -1883,6 +1908,16 @@ RangeAnalysis::analyzeLoop(MBasicBlock* header)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Unbox beta nodes in order to hoist instruction properly, and not be limited
|
||||||
|
// by the beta nodes which are added after each branch.
|
||||||
|
static inline MDefinition*
|
||||||
|
DefinitionOrBetaInputDefinition(MDefinition* ins)
|
||||||
|
{
|
||||||
|
while (ins->isBeta())
|
||||||
|
ins = ins->toBeta()->input();
|
||||||
|
return ins;
|
||||||
|
}
|
||||||
|
|
||||||
LoopIterationBound*
|
LoopIterationBound*
|
||||||
RangeAnalysis::analyzeLoopIterationCount(MBasicBlock* header,
|
RangeAnalysis::analyzeLoopIterationCount(MBasicBlock* header,
|
||||||
MTest* test, BranchDirection direction)
|
MTest* test, BranchDirection direction)
|
||||||
@@ -1928,9 +1963,8 @@ RangeAnalysis::analyzeLoopIterationCount(MBasicBlock* header,
|
|||||||
|
|
||||||
// The second operand of the phi should be a value written by an add/sub
|
// The second operand of the phi should be a value written by an add/sub
|
||||||
// in every loop iteration, i.e. in a block which dominates the backedge.
|
// in every loop iteration, i.e. in a block which dominates the backedge.
|
||||||
MDefinition* lhsWrite = lhs.term->toPhi()->getLoopBackedgeOperand();
|
MDefinition* lhsWrite =
|
||||||
if (lhsWrite->isBeta())
|
DefinitionOrBetaInputDefinition(lhs.term->toPhi()->getLoopBackedgeOperand());
|
||||||
lhsWrite = lhsWrite->getOperand(0);
|
|
||||||
if (!lhsWrite->isAdd() && !lhsWrite->isSub())
|
if (!lhsWrite->isAdd() && !lhsWrite->isSub())
|
||||||
return nullptr;
|
return nullptr;
|
||||||
if (!lhsWrite->block()->isMarked())
|
if (!lhsWrite->block()->isMarked())
|
||||||
@@ -2095,7 +2129,8 @@ bool
|
|||||||
RangeAnalysis::tryHoistBoundsCheck(MBasicBlock* header, MBoundsCheck* ins)
|
RangeAnalysis::tryHoistBoundsCheck(MBasicBlock* header, MBoundsCheck* ins)
|
||||||
{
|
{
|
||||||
// The bounds check's length must be loop invariant.
|
// The bounds check's length must be loop invariant.
|
||||||
if (ins->length()->block()->isMarked())
|
MDefinition *length = DefinitionOrBetaInputDefinition(ins->length());
|
||||||
|
if (length->block()->isMarked())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// The bounds check's index should not be loop invariant (else we would
|
// The bounds check's index should not be loop invariant (else we would
|
||||||
@@ -2148,20 +2183,22 @@ RangeAnalysis::tryHoistBoundsCheck(MBasicBlock* header, MBoundsCheck* ins)
|
|||||||
if (!SafeAdd(upper->sum.constant(), upperConstant, &upperConstant))
|
if (!SafeAdd(upper->sum.constant(), upperConstant, &upperConstant))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
// Hoist the loop invariant lower bounds checks.
|
||||||
MBoundsCheckLower* lowerCheck = MBoundsCheckLower::New(alloc(), lowerTerm);
|
MBoundsCheckLower* lowerCheck = MBoundsCheckLower::New(alloc(), lowerTerm);
|
||||||
lowerCheck->setMinimum(lowerConstant);
|
lowerCheck->setMinimum(lowerConstant);
|
||||||
lowerCheck->computeRange(alloc());
|
lowerCheck->computeRange(alloc());
|
||||||
lowerCheck->collectRangeInfoPreTrunc();
|
lowerCheck->collectRangeInfoPreTrunc();
|
||||||
|
|
||||||
MBoundsCheck* upperCheck = MBoundsCheck::New(alloc(), upperTerm, ins->length());
|
|
||||||
upperCheck->setMinimum(upperConstant);
|
|
||||||
upperCheck->setMaximum(upperConstant);
|
|
||||||
upperCheck->computeRange(alloc());
|
|
||||||
upperCheck->collectRangeInfoPreTrunc();
|
|
||||||
|
|
||||||
// Hoist the loop invariant upper and lower bounds checks.
|
|
||||||
preLoop->insertBefore(preLoop->lastIns(), lowerCheck);
|
preLoop->insertBefore(preLoop->lastIns(), lowerCheck);
|
||||||
preLoop->insertBefore(preLoop->lastIns(), upperCheck);
|
|
||||||
|
// Hoist the loop invariant upper bounds checks.
|
||||||
|
if (upperTerm != length || upperConstant >= 0) {
|
||||||
|
MBoundsCheck* upperCheck = MBoundsCheck::New(alloc(), upperTerm, length);
|
||||||
|
upperCheck->setMinimum(upperConstant);
|
||||||
|
upperCheck->setMaximum(upperConstant);
|
||||||
|
upperCheck->computeRange(alloc());
|
||||||
|
upperCheck->collectRangeInfoPreTrunc();
|
||||||
|
preLoop->insertBefore(preLoop->lastIns(), upperCheck);
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -277,3 +277,59 @@ BEGIN_TEST(testJitRangeAnalysis_StrictCompareBeta)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
END_TEST(testJitRangeAnalysis_StrictCompareBeta)
|
END_TEST(testJitRangeAnalysis_StrictCompareBeta)
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
deriveShiftRightRange(int32_t lhsLower, int32_t lhsUpper,
|
||||||
|
int32_t rhsLower, int32_t rhsUpper,
|
||||||
|
int32_t* min, int32_t* max)
|
||||||
|
{
|
||||||
|
// This is the reference algorithm and should be verifiable by inspection.
|
||||||
|
int64_t i, j;
|
||||||
|
*min = INT32_MAX; *max = INT32_MIN;
|
||||||
|
for (i = lhsLower; i <= lhsUpper; i++) {
|
||||||
|
for (j = rhsLower; j <= rhsUpper; j++) {
|
||||||
|
int32_t r = int32_t(i) >> (int32_t(j) & 0x1f);
|
||||||
|
if (r > *max) *max = r;
|
||||||
|
if (r < *min) *min = r;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
checkShiftRightRange(int32_t lhsLow, int32_t lhsHigh, int32_t lhsInc,
|
||||||
|
int32_t rhsLow, int32_t rhsHigh, int32_t rhsInc)
|
||||||
|
{
|
||||||
|
MinimalAlloc func;
|
||||||
|
int64_t lhsLower, lhsUpper, rhsLower, rhsUpper;
|
||||||
|
|
||||||
|
for (lhsLower = lhsLow; lhsLower <= lhsHigh; lhsLower += lhsInc) {
|
||||||
|
for (lhsUpper = lhsLower; lhsUpper <= lhsHigh; lhsUpper += lhsInc) {
|
||||||
|
Range* lhsRange = Range::NewInt32Range(func.alloc, lhsLower, lhsUpper);
|
||||||
|
for (rhsLower = rhsLow; rhsLower <= rhsHigh; rhsLower += rhsInc) {
|
||||||
|
for (rhsUpper = rhsLower; rhsUpper <= rhsHigh; rhsUpper += rhsInc) {
|
||||||
|
Range* rhsRange = Range::NewInt32Range(func.alloc, rhsLower, rhsUpper);
|
||||||
|
Range* result = Range::rsh(func.alloc, lhsRange, rhsRange);
|
||||||
|
int32_t min, max;
|
||||||
|
deriveShiftRightRange(lhsLower, lhsUpper,
|
||||||
|
rhsLower, rhsUpper,
|
||||||
|
&min, &max);
|
||||||
|
if (!result->isInt32() ||
|
||||||
|
result->lower() != min ||
|
||||||
|
result->upper() != max) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
BEGIN_TEST(testJitRangeAnalysis_shiftRight)
|
||||||
|
{
|
||||||
|
CHECK(checkShiftRightRange(-16, 15, 1, 0, 31, 1));
|
||||||
|
CHECK(checkShiftRightRange( -8, 7, 1, -64, 63, 1));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
END_TEST(testJitRangeAnalysis_shiftRight)
|
||||||
|
|||||||
@@ -631,7 +631,7 @@ const Class WeakMapObject::class_ = {
|
|||||||
|
|
||||||
static const JSFunctionSpec weak_map_methods[] = {
|
static const JSFunctionSpec weak_map_methods[] = {
|
||||||
JS_FN("has", WeakMap_has, 1, 0),
|
JS_FN("has", WeakMap_has, 1, 0),
|
||||||
JS_FN("get", WeakMap_get, 2, 0),
|
JS_FN("get", WeakMap_get, 1, 0),
|
||||||
JS_FN("delete", WeakMap_delete, 1, 0),
|
JS_FN("delete", WeakMap_delete, 1, 0),
|
||||||
JS_FN("set", WeakMap_set, 2, 0),
|
JS_FN("set", WeakMap_set, 2, 0),
|
||||||
JS_FN("clear", WeakMap_clear, 0, 0),
|
JS_FN("clear", WeakMap_clear, 0, 0),
|
||||||
@@ -645,8 +645,8 @@ InitWeakMapClass(JSContext* cx, HandleObject obj, bool defineMembers)
|
|||||||
|
|
||||||
Rooted<GlobalObject*> global(cx, &obj->as<GlobalObject>());
|
Rooted<GlobalObject*> global(cx, &obj->as<GlobalObject>());
|
||||||
|
|
||||||
RootedObject weakMapProto(cx, global->createBlankPrototype(cx, &WeakMapObject::class_));
|
RootedPlainObject proto(cx, NewBuiltinClassInstance<PlainObject>(cx));
|
||||||
if (!weakMapProto)
|
if (!proto)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
RootedFunction ctor(cx, global->createConstructor(cx, WeakMap_construct,
|
RootedFunction ctor(cx, global->createConstructor(cx, WeakMap_construct,
|
||||||
@@ -654,17 +654,17 @@ InitWeakMapClass(JSContext* cx, HandleObject obj, bool defineMembers)
|
|||||||
if (!ctor)
|
if (!ctor)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
if (!LinkConstructorAndPrototype(cx, ctor, weakMapProto))
|
if (!LinkConstructorAndPrototype(cx, ctor, proto))
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
if (defineMembers) {
|
if (defineMembers) {
|
||||||
if (!DefinePropertiesAndFunctions(cx, weakMapProto, nullptr, weak_map_methods))
|
if (!DefinePropertiesAndFunctions(cx, proto, nullptr, weak_map_methods))
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!GlobalObject::initBuiltinConstructor(cx, global, JSProto_WeakMap, ctor, weakMapProto))
|
if (!GlobalObject::initBuiltinConstructor(cx, global, JSProto_WeakMap, ctor, proto))
|
||||||
return nullptr;
|
return nullptr;
|
||||||
return weakMapProto;
|
return proto;
|
||||||
}
|
}
|
||||||
|
|
||||||
JSObject*
|
JSObject*
|
||||||
|
|||||||
+2
-1
@@ -91,6 +91,7 @@ using namespace js::cli;
|
|||||||
using namespace js::shell;
|
using namespace js::shell;
|
||||||
|
|
||||||
using mozilla::ArrayLength;
|
using mozilla::ArrayLength;
|
||||||
|
using mozilla::Atomic;
|
||||||
using mozilla::MakeUnique;
|
using mozilla::MakeUnique;
|
||||||
using mozilla::Maybe;
|
using mozilla::Maybe;
|
||||||
using mozilla::NumberEqualsInt32;
|
using mozilla::NumberEqualsInt32;
|
||||||
@@ -123,7 +124,7 @@ static size_t gMaxStackSize = 128 * sizeof(size_t) * 1024;
|
|||||||
*/
|
*/
|
||||||
static double MAX_TIMEOUT_INTERVAL = 1800.0;
|
static double MAX_TIMEOUT_INTERVAL = 1800.0;
|
||||||
static double gTimeoutInterval = -1.0;
|
static double gTimeoutInterval = -1.0;
|
||||||
static volatile bool gServiceInterrupt = false;
|
static Atomic<bool> gServiceInterrupt;
|
||||||
static JS::PersistentRootedValue gInterruptFunc;
|
static JS::PersistentRootedValue gInterruptFunc;
|
||||||
|
|
||||||
static bool gLastWarningEnabled = false;
|
static bool gLastWarningEnabled = false;
|
||||||
|
|||||||
@@ -3083,7 +3083,7 @@ void ContainerState::FinishPaintedLayerData(PaintedLayerData& aData, FindOpaqueB
|
|||||||
data->mLayer->SetEventRegions(EventRegions());
|
data->mLayer->SetEventRegions(EventRegions());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!layer) {
|
if (!layer) {
|
||||||
// We couldn't optimize to an image layer or a color layer above.
|
// We couldn't optimize to an image layer or a color layer above.
|
||||||
layer = data->mLayer;
|
layer = data->mLayer;
|
||||||
@@ -5659,7 +5659,7 @@ FrameLayerBuilder::DrawPaintedLayer(PaintedLayer* aLayer,
|
|||||||
if (isRecording) {
|
if (isRecording) {
|
||||||
mozilla::UniquePtr<TimelineMarker> marker =
|
mozilla::UniquePtr<TimelineMarker> marker =
|
||||||
MakeUnique<LayerTimelineMarker>(docShell, aRegionToDraw);
|
MakeUnique<LayerTimelineMarker>(docShell, aRegionToDraw);
|
||||||
docShell->AddProfileTimelineMarker(Move(marker));
|
TimelineConsumers::AddMarkerForDocShell(docShell, Move(marker));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -351,7 +351,7 @@ RestyleTracker::DoProcessRestyles()
|
|||||||
MakeUnique<RestyleTimelineMarker>(docShell,
|
MakeUnique<RestyleTimelineMarker>(docShell,
|
||||||
TRACING_INTERVAL_START,
|
TRACING_INTERVAL_START,
|
||||||
data->mRestyleHint);
|
data->mRestyleHint);
|
||||||
docShell->AddProfileTimelineMarker(Move(marker));
|
TimelineConsumers::AddMarkerForDocShell(docShell, Move(marker));
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(MOZ_ENABLE_PROFILER_SPS) && !defined(MOZILLA_XPCOMRT_API)
|
#if defined(MOZ_ENABLE_PROFILER_SPS) && !defined(MOZILLA_XPCOMRT_API)
|
||||||
@@ -369,7 +369,7 @@ RestyleTracker::DoProcessRestyles()
|
|||||||
MakeUnique<RestyleTimelineMarker>(docShell,
|
MakeUnique<RestyleTimelineMarker>(docShell,
|
||||||
TRACING_INTERVAL_END,
|
TRACING_INTERVAL_END,
|
||||||
data->mRestyleHint);
|
data->mRestyleHint);
|
||||||
docShell->AddProfileTimelineMarker(Move(marker));
|
TimelineConsumers::AddMarkerForDocShell(docShell, Move(marker));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -416,7 +416,7 @@ RestyleTracker::DoProcessRestyles()
|
|||||||
MakeUnique<RestyleTimelineMarker>(docShell,
|
MakeUnique<RestyleTimelineMarker>(docShell,
|
||||||
TRACING_INTERVAL_START,
|
TRACING_INTERVAL_START,
|
||||||
currentRestyle->mRestyleHint);
|
currentRestyle->mRestyleHint);
|
||||||
docShell->AddProfileTimelineMarker(Move(marker));
|
TimelineConsumers::AddMarkerForDocShell(docShell, Move(marker));
|
||||||
}
|
}
|
||||||
|
|
||||||
ProcessOneRestyle(currentRestyle->mElement,
|
ProcessOneRestyle(currentRestyle->mElement,
|
||||||
@@ -429,7 +429,7 @@ RestyleTracker::DoProcessRestyles()
|
|||||||
MakeUnique<RestyleTimelineMarker>(docShell,
|
MakeUnique<RestyleTimelineMarker>(docShell,
|
||||||
TRACING_INTERVAL_END,
|
TRACING_INTERVAL_END,
|
||||||
currentRestyle->mRestyleHint);
|
currentRestyle->mRestyleHint);
|
||||||
docShell->AddProfileTimelineMarker(Move(marker));
|
TimelineConsumers::AddMarkerForDocShell(docShell, Move(marker));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8909,7 +8909,7 @@ PresShell::DoReflow(nsIFrame* target, bool aInterruptible)
|
|||||||
|
|
||||||
nsDocShell* docShell = static_cast<nsDocShell*>(GetPresContext()->GetDocShell());
|
nsDocShell* docShell = static_cast<nsDocShell*>(GetPresContext()->GetDocShell());
|
||||||
if (docShell) {
|
if (docShell) {
|
||||||
docShell->AddProfileTimelineMarker("Reflow", TRACING_INTERVAL_START);
|
TimelineConsumers::AddMarkerForDocShell(docShell, "Reflow", TRACING_INTERVAL_START);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mReflowContinueTimer) {
|
if (mReflowContinueTimer) {
|
||||||
@@ -9086,7 +9086,7 @@ PresShell::DoReflow(nsIFrame* target, bool aInterruptible)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (docShell) {
|
if (docShell) {
|
||||||
docShell->AddProfileTimelineMarker("Reflow", TRACING_INTERVAL_END);
|
TimelineConsumers::AddMarkerForDocShell(docShell, "Reflow", TRACING_INTERVAL_END);
|
||||||
}
|
}
|
||||||
return !interrupted;
|
return !interrupted;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -62,6 +62,7 @@
|
|||||||
#include "mozilla/VsyncDispatcher.h"
|
#include "mozilla/VsyncDispatcher.h"
|
||||||
#include "nsThreadUtils.h"
|
#include "nsThreadUtils.h"
|
||||||
#include "mozilla/unused.h"
|
#include "mozilla/unused.h"
|
||||||
|
#include "mozilla/TimelineConsumers.h"
|
||||||
|
|
||||||
#ifdef MOZ_NUWA_PROCESS
|
#ifdef MOZ_NUWA_PROCESS
|
||||||
#include "ipc/Nuwa.h"
|
#include "ipc/Nuwa.h"
|
||||||
@@ -995,7 +996,7 @@ RefreshDriverTimer*
|
|||||||
nsRefreshDriver::ChooseTimer() const
|
nsRefreshDriver::ChooseTimer() const
|
||||||
{
|
{
|
||||||
if (mThrottled) {
|
if (mThrottled) {
|
||||||
if (!sThrottledRateTimer)
|
if (!sThrottledRateTimer)
|
||||||
sThrottledRateTimer = new InactiveRefreshDriverTimer(GetThrottledTimerInterval(),
|
sThrottledRateTimer = new InactiveRefreshDriverTimer(GetThrottledTimerInterval(),
|
||||||
DEFAULT_INACTIVE_TIMER_DISABLE_SECONDS * 1000.0);
|
DEFAULT_INACTIVE_TIMER_DISABLE_SECONDS * 1000.0);
|
||||||
return sThrottledRateTimer;
|
return sThrottledRateTimer;
|
||||||
@@ -1053,7 +1054,7 @@ nsRefreshDriver::~nsRefreshDriver()
|
|||||||
MOZ_ASSERT(ObserverCount() == 0,
|
MOZ_ASSERT(ObserverCount() == 0,
|
||||||
"observers should have unregistered");
|
"observers should have unregistered");
|
||||||
MOZ_ASSERT(!mActiveTimer, "timer should be gone");
|
MOZ_ASSERT(!mActiveTimer, "timer should be gone");
|
||||||
|
|
||||||
if (mRootRefresh) {
|
if (mRootRefresh) {
|
||||||
mRootRefresh->RemoveRefreshObserver(this, Flush_Style);
|
mRootRefresh->RemoveRefreshObserver(this, Flush_Style);
|
||||||
mRootRefresh = nullptr;
|
mRootRefresh = nullptr;
|
||||||
@@ -1437,7 +1438,7 @@ HasPendingAnimations(nsIPresShell* aShell)
|
|||||||
static void GetProfileTimelineSubDocShells(nsDocShell* aRootDocShell,
|
static void GetProfileTimelineSubDocShells(nsDocShell* aRootDocShell,
|
||||||
nsTArray<nsDocShell*>& aShells)
|
nsTArray<nsDocShell*>& aShells)
|
||||||
{
|
{
|
||||||
if (!aRootDocShell || nsDocShell::gProfileTimelineRecordingsCount == 0) {
|
if (!aRootDocShell || TimelineConsumers::IsEmpty()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1801,9 +1802,8 @@ nsRefreshDriver::Tick(int64_t aNowEpoch, TimeStamp aNowTime)
|
|||||||
for (nsDocShell* docShell : profilingDocShells) {
|
for (nsDocShell* docShell : profilingDocShells) {
|
||||||
// For the sake of the profile timeline's simplicity, this is flagged as
|
// For the sake of the profile timeline's simplicity, this is flagged as
|
||||||
// paint even if it includes creating display lists
|
// paint even if it includes creating display lists
|
||||||
docShell->AddProfileTimelineMarker("Paint", TRACING_INTERVAL_START);
|
TimelineConsumers::AddMarkerForDocShell(docShell, "Paint", TRACING_INTERVAL_START);
|
||||||
}
|
}
|
||||||
profiler_tracing("Paint", "DisplayList", TRACING_INTERVAL_START);
|
|
||||||
#ifdef MOZ_DUMP_PAINTING
|
#ifdef MOZ_DUMP_PAINTING
|
||||||
if (nsLayoutUtils::InvalidationDebuggingIsEnabled()) {
|
if (nsLayoutUtils::InvalidationDebuggingIsEnabled()) {
|
||||||
printf_stderr("Starting ProcessPendingUpdates\n");
|
printf_stderr("Starting ProcessPendingUpdates\n");
|
||||||
@@ -1819,9 +1819,8 @@ nsRefreshDriver::Tick(int64_t aNowEpoch, TimeStamp aNowTime)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
for (nsDocShell* docShell : profilingDocShells) {
|
for (nsDocShell* docShell : profilingDocShells) {
|
||||||
docShell->AddProfileTimelineMarker("Paint", TRACING_INTERVAL_END);
|
TimelineConsumers::AddMarkerForDocShell(docShell, "Paint", TRACING_INTERVAL_END);
|
||||||
}
|
}
|
||||||
profiler_tracing("Paint", "DisplayList", TRACING_INTERVAL_END);
|
|
||||||
|
|
||||||
if (nsContentUtils::XPConnect()) {
|
if (nsContentUtils::XPConnect()) {
|
||||||
nsContentUtils::XPConnect()->NotifyDidPaint();
|
nsContentUtils::XPConnect()->NotifyDidPaint();
|
||||||
|
|||||||
@@ -55,7 +55,7 @@ function advance_clock(milliseconds) {
|
|||||||
// This function checks that the list of eventsExpected matches
|
// This function checks that the list of eventsExpected matches
|
||||||
// the received events -- but it only checks the properties that
|
// the received events -- but it only checks the properties that
|
||||||
// are present on eventsExpected.
|
// are present on eventsExpected.
|
||||||
is(gEventsReceived.length, gEventsReceived.length,
|
is(gEventsReceived.length, eventsExpected.length,
|
||||||
"number of events received for " + desc);
|
"number of events received for " + desc);
|
||||||
for (var i = 0,
|
for (var i = 0,
|
||||||
i_end = Math.min(eventsExpected.length, gEventsReceived.length);
|
i_end = Math.min(eventsExpected.length, gEventsReceived.length);
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
[WeakMap.prototype-properties.html]
|
[WeakMap.prototype-properties.html]
|
||||||
type: testharness
|
type: testharness
|
||||||
[WeakMap.prototype.get.length]
|
[WeakMap.prototype.@@toStringTag]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
|
|||||||
@@ -386,6 +386,7 @@ nsViewManager::ProcessPendingUpdatesForView(nsView* aView,
|
|||||||
return; // presentation might have been torn down
|
return; // presentation might have been torn down
|
||||||
}
|
}
|
||||||
if (aFlushDirtyRegion) {
|
if (aFlushDirtyRegion) {
|
||||||
|
profiler_tracing("Paint", "DisplayList", TRACING_INTERVAL_START);
|
||||||
nsAutoScriptBlocker scriptBlocker;
|
nsAutoScriptBlocker scriptBlocker;
|
||||||
SetPainting(true);
|
SetPainting(true);
|
||||||
for (uint32_t i = 0; i < widgets.Length(); ++i) {
|
for (uint32_t i = 0; i < widgets.Length(); ++i) {
|
||||||
@@ -396,6 +397,7 @@ nsViewManager::ProcessPendingUpdatesForView(nsView* aView,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
SetPainting(false);
|
SetPainting(false);
|
||||||
|
profiler_tracing("Paint", "DisplayList", TRACING_INTERVAL_END);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -183,7 +183,7 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
#include "mozilla/AutoTimelineMarker.h"
|
#include "mozilla/AutoGlobalTimelineMarker.h"
|
||||||
#include "mozilla/Likely.h"
|
#include "mozilla/Likely.h"
|
||||||
#include "mozilla/PoisonIOInterposer.h"
|
#include "mozilla/PoisonIOInterposer.h"
|
||||||
#include "mozilla/ThreadLocal.h"
|
#include "mozilla/ThreadLocal.h"
|
||||||
|
|||||||
Reference in New Issue
Block a user