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:
2021-11-29 09:26:06 +08:00
parent 8cdfd32011
commit 496b2e34f3
42 changed files with 628 additions and 340 deletions
-105
View File
@@ -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 -3
View File
@@ -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')
+21 -47
View File
@@ -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
View File
@@ -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
@@ -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
+43
View File
@@ -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_ */
+25
View File
@@ -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'
]
+2 -2
View File
@@ -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));
} }
} }
} }
+4 -3
View File
@@ -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
} }
+2 -1
View File
@@ -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);
-1
View File
@@ -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);
} }
+3 -1
View File
@@ -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
+3 -1
View File
@@ -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();
+12 -4
View File
@@ -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;
+6 -1
View File
@@ -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
/** /**
+1 -3
View File
@@ -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);
+8 -24
View File
@@ -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))
{ {
+4
View File
@@ -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:
+51 -14
View File
@@ -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)
+7 -7
View File
@@ -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
View File
@@ -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;
+2 -2
View File
@@ -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));
} }
} }
+4 -4
View File
@@ -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));
} }
} }
} }
+2 -2
View File
@@ -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;
} }
+6 -7
View File
@@ -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();
+1 -1
View File
@@ -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
+2
View File
@@ -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);
} }
} }
+1 -1
View File
@@ -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"