From 496b2e34f362a0f1ea2ffae2e170992f07e6f120 Mon Sep 17 00:00:00 2001 From: roytam1 Date: Mon, 29 Nov 2021 09:26:06 +0800 Subject: [PATCH] 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) --- docshell/base/AutoTimelineMarker.cpp | 105 ----------------- docshell/base/moz.build | 7 +- docshell/base/nsDocShell.cpp | 68 ++++------- docshell/base/nsDocShell.h | 66 +++-------- .../timeline/AutoGlobalTimelineMarker.cpp | 37 ++++++ .../AutoGlobalTimelineMarker.h} | 49 +------- docshell/base/timeline/AutoTimelineMarker.cpp | 40 +++++++ docshell/base/timeline/AutoTimelineMarker.h | 52 +++++++++ docshell/base/timeline/ObservedDocShell.cpp | 37 ++++++ docshell/base/timeline/ObservedDocShell.h | 43 +++++++ docshell/base/timeline/TimelineConsumers.cpp | 110 ++++++++++++++++++ docshell/base/timeline/TimelineConsumers.h | 47 ++++++++ .../base/{ => timeline}/TimelineMarker.cpp | 0 docshell/base/{ => timeline}/TimelineMarker.h | 6 +- docshell/base/timeline/moz.build | 25 ++++ dom/base/Console.cpp | 4 +- dom/events/EventListenerManager.cpp | 7 +- ...est_WeakMap.prototype-properties.html.json | 3 +- dom/ipc/ProcessHangMonitor.cpp | 3 +- dom/ipc/TabParent.cpp | 1 - dom/plugins/ipc/PluginBridge.h | 4 +- dom/plugins/ipc/PluginHangUIParent.cpp | 4 +- dom/plugins/ipc/PluginModuleParent.cpp | 16 ++- dom/plugins/ipc/PluginModuleParent.h | 7 +- js/src/builtin/WeakSetObject.cpp | 4 +- .../automation/cgc-jittest-timeouts.txt | 3 + .../tests/collections/WeakMap-surfaces.js | 7 +- .../tests/collections/WeakSet-surface.js | 2 +- js/src/jit/IonCaches.cpp | 32 ++--- js/src/jit/MIR.h | 4 + js/src/jit/RangeAnalysis.cpp | 65 ++++++++--- js/src/jsapi-tests/testJitRangeAnalysis.cpp | 56 +++++++++ js/src/jsweakmap.cpp | 14 +-- js/src/shell/js.cpp | 3 +- layout/base/FrameLayerBuilder.cpp | 4 +- layout/base/RestyleTracker.cpp | 8 +- layout/base/nsPresShell.cpp | 4 +- layout/base/nsRefreshDriver.cpp | 13 +-- layout/style/test/animation_utils.js | 2 +- .../WeakMap.prototype-properties.html.ini | 2 +- view/nsViewManager.cpp | 2 + xpcom/base/nsCycleCollector.cpp | 2 +- 42 files changed, 628 insertions(+), 340 deletions(-) delete mode 100644 docshell/base/AutoTimelineMarker.cpp create mode 100644 docshell/base/timeline/AutoGlobalTimelineMarker.cpp rename docshell/base/{AutoTimelineMarker.h => timeline/AutoGlobalTimelineMarker.h} (53%) create mode 100644 docshell/base/timeline/AutoTimelineMarker.cpp create mode 100644 docshell/base/timeline/AutoTimelineMarker.h create mode 100644 docshell/base/timeline/ObservedDocShell.cpp create mode 100644 docshell/base/timeline/ObservedDocShell.h create mode 100644 docshell/base/timeline/TimelineConsumers.cpp create mode 100644 docshell/base/timeline/TimelineConsumers.h rename docshell/base/{ => timeline}/TimelineMarker.cpp (100%) rename docshell/base/{ => timeline}/TimelineMarker.h (97%) create mode 100644 docshell/base/timeline/moz.build diff --git a/docshell/base/AutoTimelineMarker.cpp b/docshell/base/AutoTimelineMarker.cpp deleted file mode 100644 index 5a2027d974..0000000000 --- a/docshell/base/AutoTimelineMarker.cpp +++ /dev/null @@ -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(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& 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>::Range range = mDocShells.all(); - !range.empty(); - range.popFront()) { - range.front()->AddProfileTimelineMarker(mName, TRACING_INTERVAL_START); - } -} - -AutoGlobalTimelineMarker::~AutoGlobalTimelineMarker() -{ - if (!mOk) { - return; - } - - for (Vector>::Range range = mDocShells.all(); - !range.empty(); - range.popFront()) { - range.front()->AddProfileTimelineMarker(mName, TRACING_INTERVAL_END); - } -} - - -} // namespace mozilla diff --git a/docshell/base/moz.build b/docshell/base/moz.build index c6a2f4edad..90ca61dcd8 100644 --- a/docshell/base/moz.build +++ b/docshell/base/moz.build @@ -4,6 +4,10 @@ # 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/. +DIRS += [ + 'timeline', +] + XPIDL_SOURCES += [ 'nsCDefaultURIFixup.idl', 'nsIClipboardCommands.idl', @@ -42,13 +46,11 @@ EXPORTS += [ ] EXPORTS.mozilla += [ - 'AutoTimelineMarker.h', 'IHistory.h', 'LoadContext.h', ] UNIFIED_SOURCES += [ - 'AutoTimelineMarker.cpp', 'LoadContext.cpp', 'nsAboutRedirector.cpp', 'nsDefaultURIFixup.cpp', @@ -61,7 +63,6 @@ UNIFIED_SOURCES += [ 'nsDSURIContentListener.cpp', 'nsWebNavigationInfo.cpp', 'SerializedLoadContext.cpp', - 'TimelineMarker.cpp', ] include('/ipc/chromium/chromium-config.mozbuild') diff --git a/docshell/base/nsDocShell.cpp b/docshell/base/nsDocShell.cpp index ded056fdb9..0ac2ed4723 100644 --- a/docshell/base/nsDocShell.cpp +++ b/docshell/base/nsDocShell.cpp @@ -2820,29 +2820,17 @@ nsDocShell::HistoryTransactionRemoved(int32_t aIndex) return NS_OK; } -unsigned long nsDocShell::gProfileTimelineRecordingsCount = 0; - -mozilla::LinkedList* nsDocShell::gObservedDocShells = nullptr; - NS_IMETHODIMP nsDocShell::SetRecordProfileTimelineMarkers(bool aValue) { bool currentValue = nsIDocShell::GetRecordProfileTimelineMarkers(); if (currentValue != aValue) { if (aValue) { - ++gProfileTimelineRecordingsCount; + TimelineConsumers::AddConsumer(this); UseEntryScriptProfiling(); - - MOZ_ASSERT(!mObserved); - mObserved.reset(new ObservedDocShell(this)); - GetOrCreateObservedDocShells().insertFront(mObserved.get()); } else { - --gProfileTimelineRecordingsCount; + TimelineConsumers::RemoveConsumer(this); UnuseEntryScriptProfiling(); - - mObserved.reset(nullptr); - - ClearProfileTimelineMarkers(); } } @@ -2873,13 +2861,23 @@ nsDocShell::PopProfileTimelineMarkers( SequenceRooter rooter( aCx, &profileTimelineMarkers); + if (!IsObserved()) { + if (!ToJSValue(aCx, profileTimelineMarkers, aProfileTimelineMarkers)) { + JS_ClearPendingException(aCx); + return NS_ERROR_UNEXPECTED; + } + return NS_OK; + } + + nsTArray>& markersStore = mObserved.get()->mTimelineMarkers; + // If we see an unpaired START, we keep it around for the next call // to PopProfileTimelineMarkers. We store the kept START objects in // this array. nsTArray> keptMarkers; - for (uint32_t i = 0; i < mProfileTimelineMarkers.Length(); ++i) { - UniquePtr& startPayload = mProfileTimelineMarkers[i]; + for (uint32_t i = 0; i < markersStore.Length(); ++i) { + UniquePtr& startPayload = markersStore[i]; const char* startMarkerName = startPayload->GetName(); bool hasSeenPaintedLayer = false; @@ -2915,8 +2913,8 @@ nsDocShell::PopProfileTimelineMarkers( // The assumption is that the devtools timeline flushes markers frequently // enough for the amount of markers to always be small enough that the // nested for loop isn't going to be a performance problem. - for (uint32_t j = i + 1; j < mProfileTimelineMarkers.Length(); ++j) { - UniquePtr& endPayload = mProfileTimelineMarkers[j]; + for (uint32_t j = i + 1; j < markersStore.Length(); ++j) { + UniquePtr& endPayload = markersStore[j]; const char* endMarkerName = endPayload->GetName(); // 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 (!hasSeenEnd) { - keptMarkers.AppendElement(Move(mProfileTimelineMarkers[i])); - mProfileTimelineMarkers.RemoveElementAt(i); + keptMarkers.AppendElement(Move(markersStore[i])); + markersStore.RemoveElementAt(i); --i; } } } - mProfileTimelineMarkers.SwapElements(keptMarkers); + markersStore.SwapElements(keptMarkers); if (!ToJSValue(aCx, profileTimelineMarkers, aProfileTimelineMarkers)) { JS_ClearPendingException(aCx); @@ -2988,24 +2986,6 @@ nsDocShell::Now(DOMHighResTimeStamp* aWhen) return NS_OK; } -void -nsDocShell::AddProfileTimelineMarker(const char* aName, - TracingMetadata aMetaData) -{ - if (IsObserved()) { - TimelineMarker* marker = new TimelineMarker(this, aName, aMetaData); - mProfileTimelineMarkers.AppendElement(marker); - } -} - -void -nsDocShell::AddProfileTimelineMarker(UniquePtr&& aMarker) -{ - if (IsObserved()) { - mProfileTimelineMarkers.AppendElement(Move(aMarker)); - } -} - NS_IMETHODIMP nsDocShell::SetWindowDraggingAllowed(bool aValue) { @@ -3035,12 +3015,6 @@ nsDocShell::GetWindowDraggingAllowed(bool* aValue) return NS_OK; } -void -nsDocShell::ClearProfileTimelineMarkers() -{ - mProfileTimelineMarkers.Clear(); -} - nsIDOMStorageManager* nsDocShell::TopSessionStorageManager() { @@ -14082,7 +14056,7 @@ nsDocShell::NotifyJSRunToCompletionStart(const char* aReason, MakeUnique(this, "Javascript", aReason, aFunctionName, aFilename, aLineNumber); - AddProfileTimelineMarker(Move(marker)); + TimelineConsumers::AddMarkerForDocShell(this, Move(marker)); } mJSRunToCompletionDepth++; } @@ -14095,7 +14069,7 @@ nsDocShell::NotifyJSRunToCompletionStop() // If last stop, mark interval end. mJSRunToCompletionDepth--; if (timelineOn && mJSRunToCompletionDepth == 0) { - AddProfileTimelineMarker("Javascript", TRACING_INTERVAL_END); + TimelineConsumers::AddMarkerForDocShell(this, "Javascript", TRACING_INTERVAL_END); } } diff --git a/docshell/base/nsDocShell.h b/docshell/base/nsDocShell.h index db8ed9908c..a9a73a1478 100644 --- a/docshell/base/nsDocShell.h +++ b/docshell/base/nsDocShell.h @@ -33,7 +33,9 @@ #include "nsAutoPtr.h" #include "nsThreadUtils.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 #define REFRESH_REDIRECT_TIMER 15000 @@ -260,53 +262,24 @@ public: // is no longer applied void NotifyAsyncPanZoomStopped(); - // Add new profile timeline markers to this docShell. This will only add - // markers if the docShell is currently recording profile timeline markers. - // See nsIDocShell::recordProfileTimelineMarkers - void AddProfileTimelineMarker(const char* aName, TracingMetadata aMetaData); - void AddProfileTimelineMarker(mozilla::UniquePtr&& aMarker); - - // Global counter for how many docShells are currently recording profile - // timeline markers - static unsigned long gProfileTimelineRecordingsCount; - - class ObservedDocShell : public mozilla::LinkedListElement - { - public: - explicit ObservedDocShell(nsDocShell* aDocShell) - : mDocShell(aDocShell) - { } - - nsDocShell* operator*() const { return mDocShell.get(); } - - private: - nsRefPtr mDocShell; - }; - private: - static mozilla::LinkedList* gObservedDocShells; - - static mozilla::LinkedList& GetOrCreateObservedDocShells() - { - if (!gObservedDocShells) { - gObservedDocShells = new mozilla::LinkedList(); - } - return *gObservedDocShells; - } - - // Never null if timeline markers are being observed. - mozilla::UniquePtr mObserved; - - // Return true if timeline markers are being observed for this docshell. False - // otherwise. + // An observed docshell wrapper is created when recording markers is enabled. + mozilla::UniquePtr mObserved; bool IsObserved() const { return !!mObserved; } -public: - static const mozilla::LinkedList& GetObservedDocShells() - { - return GetOrCreateObservedDocShells(); - } + // It is necessary to allow adding a timeline marker wherever a docshell + // instance is available. This operation happens frequently and needs to + // be very fast, so instead of using a Map or having to search for some + // docshell-specific markers storage, a pointer to an `ObservedDocShell` is + // is stored on docshells directly. + friend void mozilla::TimelineConsumers::AddConsumer(nsDocShell* aDocShell); + friend void mozilla::TimelineConsumers::RemoveConsumer(nsDocShell* aDocShell); + friend void mozilla::TimelineConsumers::AddMarkerForDocShell( + nsDocShell* aDocShell, UniquePtr&& 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. static void CopyFavicon(nsIURI* aOldURI, nsIURI* aNewURI, @@ -1020,11 +993,6 @@ private: // has been called without a matching NotifyRunToCompletionStop. uint32_t mJSRunToCompletionDepth; - nsTArray> mProfileTimelineMarkers; - - // Get rid of all the timeline markers accumulated so far - void ClearProfileTimelineMarkers(); - // Separate function to do the actual name (i.e. not _top, _self etc.) // searching for FindItemWithName. nsresult DoFindItemWithName(const char16_t* aName, diff --git a/docshell/base/timeline/AutoGlobalTimelineMarker.cpp b/docshell/base/timeline/AutoGlobalTimelineMarker.cpp new file mode 100644 index 0000000000..9baf8df95f --- /dev/null +++ b/docshell/base/timeline/AutoGlobalTimelineMarker.cpp @@ -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 diff --git a/docshell/base/AutoTimelineMarker.h b/docshell/base/timeline/AutoGlobalTimelineMarker.h similarity index 53% rename from docshell/base/AutoTimelineMarker.h rename to docshell/base/timeline/AutoGlobalTimelineMarker.h index 2f9db74158..7bb4e005b2 100644 --- a/docshell/base/AutoTimelineMarker.h +++ b/docshell/base/timeline/AutoGlobalTimelineMarker.h @@ -4,50 +4,16 @@ * 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 AutoTimelineMarker_h__ -#define AutoTimelineMarker_h__ +#ifndef mozilla_AutoGlobalTimelineMarker_h_ +#define mozilla_AutoGlobalTimelineMarker_h_ #include "mozilla/GuardObjects.h" -#include "mozilla/Vector.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; - - nsRefPtr 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 // // 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; - // 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> mDocShells; - // The name of the marker we are adding. const char* mName; - void PopulateDocShells(); - public: explicit AutoGlobalTimelineMarker(const char* aName MOZ_GUARD_OBJECT_NOTIFIER_PARAM); - ~AutoGlobalTimelineMarker(); AutoGlobalTimelineMarker(const AutoGlobalTimelineMarker& aOther) = delete; @@ -90,4 +47,4 @@ public: } // namespace mozilla -#endif /* AutoTimelineMarker_h__ */ +#endif /* mozilla_AutoGlobalTimelineMarker_h_ */ diff --git a/docshell/base/timeline/AutoTimelineMarker.cpp b/docshell/base/timeline/AutoTimelineMarker.cpp new file mode 100644 index 0000000000..8ac05e1e7a --- /dev/null +++ b/docshell/base/timeline/AutoTimelineMarker.cpp @@ -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(aDocShell); + TimelineConsumers::AddMarkerForDocShell(mDocShell, mName, TRACING_INTERVAL_START); +} + +AutoTimelineMarker::~AutoTimelineMarker() +{ + if (!mDocShell || TimelineConsumers::IsEmpty()) { + return; + } + + TimelineConsumers::AddMarkerForDocShell(mDocShell, mName, TRACING_INTERVAL_END); +} + +} // namespace mozilla diff --git a/docshell/base/timeline/AutoTimelineMarker.h b/docshell/base/timeline/AutoTimelineMarker.h new file mode 100644 index 0000000000..0d99e8e644 --- /dev/null +++ b/docshell/base/timeline/AutoTimelineMarker.h @@ -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 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_ */ diff --git a/docshell/base/timeline/ObservedDocShell.cpp b/docshell/base/timeline/ObservedDocShell.cpp new file mode 100644 index 0000000000..d2c352ed23 --- /dev/null +++ b/docshell/base/timeline/ObservedDocShell.cpp @@ -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&& aMarker) +{ + mTimelineMarkers.AppendElement(Move(aMarker)); +} + +void +ObservedDocShell::ClearMarkers() +{ + mTimelineMarkers.Clear(); +} + +} // namespace mozilla diff --git a/docshell/base/timeline/ObservedDocShell.h b/docshell/base/timeline/ObservedDocShell.h new file mode 100644 index 0000000000..47c35e5094 --- /dev/null +++ b/docshell/base/timeline/ObservedDocShell.h @@ -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 +{ +private: + nsRefPtr mDocShell; + +public: + // FIXME: make this private once all marker-specific logic has been + // moved out of nsDocShell. + nsTArray> mTimelineMarkers; + + explicit ObservedDocShell(nsDocShell* aDocShell); + nsDocShell* operator*() const { return mDocShell.get(); } + + void AddMarker(const char* aName, TracingMetadata aMetaData); + void AddMarker(UniquePtr&& aMarker); + void ClearMarkers(); +}; + +} // namespace mozilla + +#endif /* ObservedDocShell_h_ */ diff --git a/docshell/base/timeline/TimelineConsumers.cpp b/docshell/base/timeline/TimelineConsumers.cpp new file mode 100644 index 0000000000..a55e7c55d7 --- /dev/null +++ b/docshell/base/timeline/TimelineConsumers.cpp @@ -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* TimelineConsumers::sObservedDocShells = nullptr; + +LinkedList& +TimelineConsumers::GetOrCreateObservedDocShellsList() +{ + if (!sObservedDocShells) { + sObservedDocShells = new LinkedList(); + } + return *sObservedDocShells; +} + +void +TimelineConsumers::AddConsumer(nsDocShell* aDocShell) +{ + UniquePtr& observed = aDocShell->mObserved; + + MOZ_ASSERT(!observed); + sActiveConsumers++; + observed.reset(new ObservedDocShell(aDocShell)); + GetOrCreateObservedDocShellsList().insertFront(observed.get()); +} + +void +TimelineConsumers::RemoveConsumer(nsDocShell* aDocShell) +{ + UniquePtr& 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>& aStore) +{ + const LinkedList& 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&& 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>& aDocShells, + const char* aName, TracingMetadata aMetaData) +{ + for (Vector>::Range range = aDocShells.all(); + !range.empty(); + range.popFront()) { + AddMarkerForDocShell(range.front(), aName, aMetaData); + } +} + +void +TimelineConsumers::AddMarkerToAllObservedDocShells(const char* aName, TracingMetadata aMetaData) +{ + Vector> 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 diff --git a/docshell/base/timeline/TimelineConsumers.h b/docshell/base/timeline/TimelineConsumers.h new file mode 100644 index 0000000000..fdbed07161 --- /dev/null +++ b/docshell/base/timeline/TimelineConsumers.h @@ -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* sObservedDocShells; + static LinkedList& GetOrCreateObservedDocShellsList(); + +public: + static void AddConsumer(nsDocShell* aDocShell); + static void RemoveConsumer(nsDocShell* aDocShell); + static bool IsEmpty(); + static bool GetKnownDocShells(Vector>& 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&& aMarker); + static void AddMarkerForDocShell(nsDocShell* aDocShell, + const char* aName, TracingMetadata aMetaData); + static void AddMarkerToDocShellsList(Vector>& aDocShells, + const char* aName, TracingMetadata aMetaData); + static void AddMarkerToAllObservedDocShells(const char* aName, TracingMetadata aMetaData); +}; + +} // namespace mozilla + +#endif /* mozilla_TimelineConsumers_h_ */ diff --git a/docshell/base/TimelineMarker.cpp b/docshell/base/timeline/TimelineMarker.cpp similarity index 100% rename from docshell/base/TimelineMarker.cpp rename to docshell/base/timeline/TimelineMarker.cpp diff --git a/docshell/base/TimelineMarker.h b/docshell/base/timeline/TimelineMarker.h similarity index 97% rename from docshell/base/TimelineMarker.h rename to docshell/base/timeline/TimelineMarker.h index a13baef397..25e6e2e8e5 100644 --- a/docshell/base/TimelineMarker.h +++ b/docshell/base/timeline/TimelineMarker.h @@ -4,8 +4,8 @@ * 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 TimelineMarker_h__ -#define TimelineMarker_h__ +#ifndef TimelineMarker_h_ +#define TimelineMarker_h_ #include "nsString.h" #include "GeckoProfiler.h" @@ -96,4 +96,4 @@ private: JS::PersistentRooted mStackTrace; }; -#endif /* TimelineMarker_h__ */ +#endif /* TimelineMarker_h_ */ diff --git a/docshell/base/timeline/moz.build b/docshell/base/timeline/moz.build new file mode 100644 index 0000000000..5aa3008395 --- /dev/null +++ b/docshell/base/timeline/moz.build @@ -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' +] diff --git a/dom/base/Console.cpp b/dom/base/Console.cpp index 0e1c8e7022..ce67d9f1fc 100644 --- a/dom/base/Console.cpp +++ b/dom/base/Console.cpp @@ -1135,7 +1135,7 @@ Console::Method(JSContext* aCx, MethodName aMethodName, mozilla::UniquePtr marker = MakeUnique(docShell, TRACING_TIMESTAMP, key); - docShell->AddProfileTimelineMarker(Move(marker)); + TimelineConsumers::AddMarkerForDocShell(docShell, Move(marker)); } // For `console.time(foo)` and `console.timeEnd(foo)` else if (isTimelineRecording && aData.Length() == 1) { @@ -1148,7 +1148,7 @@ Console::Method(JSContext* aCx, MethodName aMethodName, MakeUnique(docShell, aMethodName == MethodTime ? TRACING_INTERVAL_START : TRACING_INTERVAL_END, key); - docShell->AddProfileTimelineMarker(Move(marker)); + TimelineConsumers::AddMarkerForDocShell(docShell, Move(marker)); } } } diff --git a/dom/events/EventListenerManager.cpp b/dom/events/EventListenerManager.cpp index b7a77343e3..9e9cc31f23 100644 --- a/dom/events/EventListenerManager.cpp +++ b/dom/events/EventListenerManager.cpp @@ -23,6 +23,7 @@ #include "mozilla/dom/BindingUtils.h" #include "mozilla/dom/Element.h" #include "mozilla/dom/Event.h" +#include "mozilla/TimelineConsumers.h" #include "EventListenerService.h" #include "nsCOMArray.h" @@ -1124,7 +1125,7 @@ EventListenerManager::HandleEventInternal(nsPresContext* aPresContext, nsCOMPtr docShell; bool isTimelineRecording = false; if (mIsMainThreadELM && - nsDocShell::gProfileTimelineRecordingsCount > 0 && + !TimelineConsumers::IsEmpty() && listener->mListenerType != Listener::eNativeListener) { docShell = GetDocShellForTarget(); if (docShell) { @@ -1139,7 +1140,7 @@ EventListenerManager::HandleEventInternal(nsPresContext* aPresContext, mozilla::UniquePtr marker = MakeUnique(ds, TRACING_INTERVAL_START, phase, typeStr); - ds->AddProfileTimelineMarker(Move(marker)); + TimelineConsumers::AddMarkerForDocShell(ds, Move(marker)); } } @@ -1150,7 +1151,7 @@ EventListenerManager::HandleEventInternal(nsPresContext* aPresContext, if (isTimelineRecording) { nsDocShell* ds = static_cast(docShell.get()); - ds->AddProfileTimelineMarker("DOMEvent", TRACING_INTERVAL_END); + TimelineConsumers::AddMarkerForDocShell(ds, "DOMEvent", TRACING_INTERVAL_END); } } } diff --git a/dom/imptests/failures/html/js/builtins/test_WeakMap.prototype-properties.html.json b/dom/imptests/failures/html/js/builtins/test_WeakMap.prototype-properties.html.json index 64b9a01c71..ccaf35e45b 100644 --- a/dom/imptests/failures/html/js/builtins/test_WeakMap.prototype-properties.html.json +++ b/dom/imptests/failures/html/js/builtins/test_WeakMap.prototype-properties.html.json @@ -3,5 +3,6 @@ "WeakMap.prototype.delete.length": true, "WeakMap.prototype.get.length": true, "WeakMap.prototype.has.length": true, - "WeakMap.prototype.set.length": true + "WeakMap.prototype.set.length": true, + "WeakMap.prototype.@@toStringTag": true } diff --git a/dom/ipc/ProcessHangMonitor.cpp b/dom/ipc/ProcessHangMonitor.cpp index 06d30ded66..a49337c703 100644 --- a/dom/ipc/ProcessHangMonitor.cpp +++ b/dom/ipc/ProcessHangMonitor.cpp @@ -817,7 +817,8 @@ HangMonitoredProcess::TerminatePlugin() } uint32_t id = mHangData.get_PluginHangData().pluginId(); - plugins::TerminatePlugin(id, mBrowserDumpId); + plugins::TerminatePlugin(id, NS_LITERAL_CSTRING("HangMonitor"), + mBrowserDumpId); if (mActor) { mActor->CleanupPluginHang(id, false); diff --git a/dom/ipc/TabParent.cpp b/dom/ipc/TabParent.cpp index fc132cf722..98749ba0ce 100644 --- a/dom/ipc/TabParent.cpp +++ b/dom/ipc/TabParent.cpp @@ -2258,7 +2258,6 @@ TabParent::RecvDispatchAfterKeyboardEvent(const WidgetKeyboardEvent& aEvent) if (mFrameElement && PresShell::BeforeAfterKeyboardEventEnabled() && localEvent.message != NS_KEY_PRESS) { - nsCOMPtr node(do_QueryInterface(mFrameElement)); presShell->DispatchAfterKeyboardEvent(mFrameElement, localEvent, aEvent.mFlags.mDefaultPrevented); } diff --git a/dom/plugins/ipc/PluginBridge.h b/dom/plugins/ipc/PluginBridge.h index df1248c596..4066994ff4 100644 --- a/dom/plugins/ipc/PluginBridge.h +++ b/dom/plugins/ipc/PluginBridge.h @@ -25,7 +25,9 @@ FindPluginsForContent(uint32_t aPluginEpoch, uint32_t* aNewPluginEpoch); void -TerminatePlugin(uint32_t aPluginId, const nsString& aBrowserDumpId); +TerminatePlugin(uint32_t aPluginId, + const nsCString& aMonitorDescription, + const nsAString& aBrowserDumpId); } // namespace plugins } // namespace mozilla diff --git a/dom/plugins/ipc/PluginHangUIParent.cpp b/dom/plugins/ipc/PluginHangUIParent.cpp index 4ab5f96d5a..092308a7a3 100644 --- a/dom/plugins/ipc/PluginHangUIParent.cpp +++ b/dom/plugins/ipc/PluginHangUIParent.cpp @@ -353,7 +353,9 @@ PluginHangUIParent::RecvUserResponse(const unsigned int& aResponse) int responseCode; if (aResponse & HANGUI_USER_RESPONSE_STOP) { // User clicked Stop - mModule->TerminateChildProcess(mMainThreadMessageLoop, EmptyString()); + mModule->TerminateChildProcess(mMainThreadMessageLoop, + NS_LITERAL_CSTRING("ModalHangUI"), + EmptyString()); responseCode = 1; } else if(aResponse & HANGUI_USER_RESPONSE_CONTINUE) { mModule->OnHangUIContinue(); diff --git a/dom/plugins/ipc/PluginModuleParent.cpp b/dom/plugins/ipc/PluginModuleParent.cpp index a1671227c0..57c1fd6618 100755 --- a/dom/plugins/ipc/PluginModuleParent.cpp +++ b/dom/plugins/ipc/PluginModuleParent.cpp @@ -347,7 +347,9 @@ bool PluginModuleMapping::sIsLoadModuleOnStack = false; } // anonymous namespace 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()); @@ -357,8 +359,11 @@ mozilla::plugins::TerminatePlugin(uint32_t aPluginId, const nsString& aBrowserDu return; } nsRefPtr plugin = pluginTag->mPlugin; - PluginModuleChromeParent* chromeParent = static_cast(plugin->GetLibrary()); - chromeParent->TerminateChildProcess(MessageLoop::current(), aBrowserDumpId); + PluginModuleChromeParent* chromeParent = + static_cast(plugin->GetLibrary()); + chromeParent->TerminateChildProcess(MessageLoop::current(), + aMonitorDescription, + aBrowserDumpId); } /* static */ PluginLibrary* @@ -1057,7 +1062,9 @@ PluginModuleChromeParent::ShouldContinueFromReplyTimeout() // original plugin hang behaviour and kill the plugin container. FinishHangUI(); #endif // XP_WIN - TerminateChildProcess(MessageLoop::current(), EmptyString()); + TerminateChildProcess(MessageLoop::current(), + NS_LITERAL_CSTRING("ModalHangUI"), + EmptyString()); GetIPCChannel()->CloseWithTimeout(); return false; } @@ -1081,6 +1088,7 @@ PluginModuleContentParent::OnExitedSyncSend() void PluginModuleChromeParent::TerminateChildProcess(MessageLoop* aMsgLoop, + const nsCString& aMonitorDescription, const nsAString& aBrowserDumpId) { mozilla::ipc::ScopedProcessHandle geckoChildProcess; diff --git a/dom/plugins/ipc/PluginModuleParent.h b/dom/plugins/ipc/PluginModuleParent.h index f02aade025..e4380bbe24 100644 --- a/dom/plugins/ipc/PluginModuleParent.h +++ b/dom/plugins/ipc/PluginModuleParent.h @@ -361,12 +361,17 @@ class PluginModuleChromeParent * * @param aMsgLoop the main message pump associated with the module * 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 * provided TerminateChildProcess will use this browser dump file in * generating a multi-process crash report. If not provided a browser * 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 /** diff --git a/js/src/builtin/WeakSetObject.cpp b/js/src/builtin/WeakSetObject.cpp index 7197656be3..655adc4925 100644 --- a/js/src/builtin/WeakSetObject.cpp +++ b/js/src/builtin/WeakSetObject.cpp @@ -45,11 +45,9 @@ JSObject* WeakSetObject::initClass(JSContext* cx, JSObject* obj) { Rooted global(cx, &obj->as()); - // Todo: WeakSet.prototype should not be a WeakSet! - Rooted proto(cx, global->createBlankPrototype(cx)); + RootedPlainObject proto(cx, NewBuiltinClassInstance(cx)); if (!proto) return nullptr; - proto->setReservedSlot(WEAKSET_MAP_SLOT, UndefinedValue()); Rooted ctor(cx, global->createConstructor(cx, construct, ClassName(JSProto_WeakSet, cx), 0)); if (!ctor || diff --git a/js/src/devtools/automation/cgc-jittest-timeouts.txt b/js/src/devtools/automation/cgc-jittest-timeouts.txt index 3b52d46e2d..7b96ea4955 100644 --- a/js/src/devtools/automation/cgc-jittest-timeouts.txt +++ b/js/src/devtools/automation/cgc-jittest-timeouts.txt @@ -1,10 +1,13 @@ asm.js/testParallelCompile.js auto-regress/bug653395.js +auto-regress/bug654392.js auto-regress/bug675251.js baseline/bug847446.js baseline/bug852175.js basic/bug632964-regexp.js +basic/bug656261.js basic/bug677957-2.js +basic/bug753283.js basic/testBug614653.js basic/testBug686274.js basic/testTypedArrayInit.js diff --git a/js/src/jit-test/tests/collections/WeakMap-surfaces.js b/js/src/jit-test/tests/collections/WeakMap-surfaces.js index 678c9a59fa..5feae5f7da 100644 --- a/js/src/jit-test/tests/collections/WeakMap-surfaces.js +++ b/js/src/jit-test/tests/collections/WeakMap-surfaces.js @@ -11,12 +11,12 @@ assertEq(WeakMap.length, 0); assertEq(WeakMap.name, "WeakMap"); 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.keys(WeakMap.prototype).join(), ""); assertEq(WeakMap.prototype.constructor, WeakMap); -function checkMethod(name, arity) { +function checkMethod(name, arity) { var desc = Object.getOwnPropertyDescriptor(WeakMap.prototype, name); assertEq(desc.enumerable, false); assertEq(desc.configurable, true); @@ -26,8 +26,7 @@ function checkMethod(name, 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("set", 2); checkMethod("delete", 1); diff --git a/js/src/jit-test/tests/collections/WeakSet-surface.js b/js/src/jit-test/tests/collections/WeakSet-surface.js index 253ff4646e..1e3f155c58 100644 --- a/js/src/jit-test/tests/collections/WeakSet-surface.js +++ b/js/src/jit-test/tests/collections/WeakSet-surface.js @@ -11,7 +11,7 @@ assertEq(WeakSet.length, 0); assertEq(WeakSet.name, "WeakSet"); 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.keys(WeakSet.prototype).length, 0); assertEq(WeakSet.prototype.constructor, WeakSet); diff --git a/js/src/jit/IonCaches.cpp b/js/src/jit/IonCaches.cpp index 8221378439..3ca30e38f5 100644 --- a/js/src/jit/IonCaches.cpp +++ b/js/src/jit/IonCaches.cpp @@ -2668,32 +2668,23 @@ GenerateCallSetter(JSContext* cx, IonScript* ion, MacroAssembler& masm, static bool IsCacheableDOMProxyUnshadowedSetterCall(JSContext* cx, HandleObject obj, HandlePropertyName name, - MutableHandleObject holder, MutableHandleShape shape, - bool* isSetter) + MutableHandleObject holder, MutableHandleShape shape) { MOZ_ASSERT(IsCacheableDOMProxy(obj)); - *isSetter = false; - RootedObject checkObj(cx, obj->getTaggedProto().toObjectOrNull()); 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; if (!holder) - return true; + return false; - if (!IsCacheableSetPropCallNative(checkObj, holder, shape) && - !IsCacheableSetPropCallPropertyOp(checkObj, holder, shape) && - !IsCacheableSetPropCallScripted(checkObj, holder, shape)) - { - return true; - } - - *isSetter = true; - return true; + return IsCacheableSetPropCallNative(checkObj, holder, shape) || + IsCacheableSetPropCallPropertyOp(checkObj, holder, shape) || + IsCacheableSetPropCallScripted(checkObj, holder, shape); } bool @@ -2717,14 +2708,7 @@ SetPropertyIC::attachDOMProxyUnshadowed(JSContext* cx, HandleScript outerScript, RootedPropertyName propName(cx, name()); RootedObject holder(cx); RootedShape shape(cx); - bool isSetter; - if (!IsCacheableDOMProxyUnshadowedSetterCall(cx, obj, propName, &holder, - &shape, &isSetter)) - { - return false; - } - - if (isSetter) { + if (IsCacheableDOMProxyUnshadowedSetterCall(cx, obj, propName, &holder, &shape)) { if (!GenerateCallSetter(cx, ion, masm, attacher, obj, holder, shape, strict(), object(), value(), &failures, liveRegs_, returnAddr)) { diff --git a/js/src/jit/MIR.h b/js/src/jit/MIR.h index aa4289a75b..a330648867 100644 --- a/js/src/jit/MIR.h +++ b/js/src/jit/MIR.h @@ -4464,6 +4464,7 @@ class MGuardObject setGuard(); setMovable(); setResultType(MIRType_Object); + setResultTypeSet(ins->resultTypeSet()); } public: @@ -4510,6 +4511,7 @@ class MPolyInlineGuard { setGuard(); setResultType(MIRType_Object); + setResultTypeSet(ins->resultTypeSet()); } public: @@ -10628,6 +10630,7 @@ class MGuardShape setGuard(); setMovable(); setResultType(MIRType_Object); + setResultTypeSet(obj->resultTypeSet()); // Disallow guarding on unboxed object shapes. The group is better to // guard on, and guarding on the shape can interact badly with @@ -10681,6 +10684,7 @@ class MGuardReceiverPolymorphic setGuard(); setMovable(); setResultType(MIRType_Object); + setResultTypeSet(obj->resultTypeSet()); } public: diff --git a/js/src/jit/RangeAnalysis.cpp b/js/src/jit/RangeAnalysis.cpp index 59e0eed822..0118241818 100644 --- a/js/src/jit/RangeAnalysis.cpp +++ b/js/src/jit/RangeAnalysis.cpp @@ -1022,7 +1022,32 @@ Range::rsh(TempAllocator& alloc, const Range* lhs, const Range* rhs) { MOZ_ASSERT(lhs->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* @@ -1883,6 +1908,16 @@ RangeAnalysis::analyzeLoop(MBasicBlock* header) 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* RangeAnalysis::analyzeLoopIterationCount(MBasicBlock* header, 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 // in every loop iteration, i.e. in a block which dominates the backedge. - MDefinition* lhsWrite = lhs.term->toPhi()->getLoopBackedgeOperand(); - if (lhsWrite->isBeta()) - lhsWrite = lhsWrite->getOperand(0); + MDefinition* lhsWrite = + DefinitionOrBetaInputDefinition(lhs.term->toPhi()->getLoopBackedgeOperand()); if (!lhsWrite->isAdd() && !lhsWrite->isSub()) return nullptr; if (!lhsWrite->block()->isMarked()) @@ -2095,7 +2129,8 @@ bool RangeAnalysis::tryHoistBoundsCheck(MBasicBlock* header, MBoundsCheck* ins) { // 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; // 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)) return false; + // Hoist the loop invariant lower bounds checks. MBoundsCheckLower* lowerCheck = MBoundsCheckLower::New(alloc(), lowerTerm); lowerCheck->setMinimum(lowerConstant); lowerCheck->computeRange(alloc()); 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(), 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; } diff --git a/js/src/jsapi-tests/testJitRangeAnalysis.cpp b/js/src/jsapi-tests/testJitRangeAnalysis.cpp index 8672f0b908..96ef5e0976 100644 --- a/js/src/jsapi-tests/testJitRangeAnalysis.cpp +++ b/js/src/jsapi-tests/testJitRangeAnalysis.cpp @@ -277,3 +277,59 @@ BEGIN_TEST(testJitRangeAnalysis_StrictCompareBeta) return true; } 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) diff --git a/js/src/jsweakmap.cpp b/js/src/jsweakmap.cpp index 89d77a2901..2eadd45194 100644 --- a/js/src/jsweakmap.cpp +++ b/js/src/jsweakmap.cpp @@ -631,7 +631,7 @@ const Class WeakMapObject::class_ = { static const JSFunctionSpec weak_map_methods[] = { 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("set", WeakMap_set, 2, 0), JS_FN("clear", WeakMap_clear, 0, 0), @@ -645,8 +645,8 @@ InitWeakMapClass(JSContext* cx, HandleObject obj, bool defineMembers) Rooted global(cx, &obj->as()); - RootedObject weakMapProto(cx, global->createBlankPrototype(cx, &WeakMapObject::class_)); - if (!weakMapProto) + RootedPlainObject proto(cx, NewBuiltinClassInstance(cx)); + if (!proto) return nullptr; RootedFunction ctor(cx, global->createConstructor(cx, WeakMap_construct, @@ -654,17 +654,17 @@ InitWeakMapClass(JSContext* cx, HandleObject obj, bool defineMembers) if (!ctor) return nullptr; - if (!LinkConstructorAndPrototype(cx, ctor, weakMapProto)) + if (!LinkConstructorAndPrototype(cx, ctor, proto)) return nullptr; if (defineMembers) { - if (!DefinePropertiesAndFunctions(cx, weakMapProto, nullptr, weak_map_methods)) + if (!DefinePropertiesAndFunctions(cx, proto, nullptr, weak_map_methods)) return nullptr; } - if (!GlobalObject::initBuiltinConstructor(cx, global, JSProto_WeakMap, ctor, weakMapProto)) + if (!GlobalObject::initBuiltinConstructor(cx, global, JSProto_WeakMap, ctor, proto)) return nullptr; - return weakMapProto; + return proto; } JSObject* diff --git a/js/src/shell/js.cpp b/js/src/shell/js.cpp index 5d0f4efc94..920e262ed2 100644 --- a/js/src/shell/js.cpp +++ b/js/src/shell/js.cpp @@ -91,6 +91,7 @@ using namespace js::cli; using namespace js::shell; using mozilla::ArrayLength; +using mozilla::Atomic; using mozilla::MakeUnique; using mozilla::Maybe; 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 gTimeoutInterval = -1.0; -static volatile bool gServiceInterrupt = false; +static Atomic gServiceInterrupt; static JS::PersistentRootedValue gInterruptFunc; static bool gLastWarningEnabled = false; diff --git a/layout/base/FrameLayerBuilder.cpp b/layout/base/FrameLayerBuilder.cpp index f6ee3a4aec..215f0ba401 100644 --- a/layout/base/FrameLayerBuilder.cpp +++ b/layout/base/FrameLayerBuilder.cpp @@ -3083,7 +3083,7 @@ void ContainerState::FinishPaintedLayerData(PaintedLayerData& aData, FindOpaqueB data->mLayer->SetEventRegions(EventRegions()); } } - + if (!layer) { // We couldn't optimize to an image layer or a color layer above. layer = data->mLayer; @@ -5659,7 +5659,7 @@ FrameLayerBuilder::DrawPaintedLayer(PaintedLayer* aLayer, if (isRecording) { mozilla::UniquePtr marker = MakeUnique(docShell, aRegionToDraw); - docShell->AddProfileTimelineMarker(Move(marker)); + TimelineConsumers::AddMarkerForDocShell(docShell, Move(marker)); } } diff --git a/layout/base/RestyleTracker.cpp b/layout/base/RestyleTracker.cpp index 0d69d56bdf..0d32bd9dbf 100644 --- a/layout/base/RestyleTracker.cpp +++ b/layout/base/RestyleTracker.cpp @@ -351,7 +351,7 @@ RestyleTracker::DoProcessRestyles() MakeUnique(docShell, TRACING_INTERVAL_START, data->mRestyleHint); - docShell->AddProfileTimelineMarker(Move(marker)); + TimelineConsumers::AddMarkerForDocShell(docShell, Move(marker)); } #if defined(MOZ_ENABLE_PROFILER_SPS) && !defined(MOZILLA_XPCOMRT_API) @@ -369,7 +369,7 @@ RestyleTracker::DoProcessRestyles() MakeUnique(docShell, TRACING_INTERVAL_END, data->mRestyleHint); - docShell->AddProfileTimelineMarker(Move(marker)); + TimelineConsumers::AddMarkerForDocShell(docShell, Move(marker)); } } @@ -416,7 +416,7 @@ RestyleTracker::DoProcessRestyles() MakeUnique(docShell, TRACING_INTERVAL_START, currentRestyle->mRestyleHint); - docShell->AddProfileTimelineMarker(Move(marker)); + TimelineConsumers::AddMarkerForDocShell(docShell, Move(marker)); } ProcessOneRestyle(currentRestyle->mElement, @@ -429,7 +429,7 @@ RestyleTracker::DoProcessRestyles() MakeUnique(docShell, TRACING_INTERVAL_END, currentRestyle->mRestyleHint); - docShell->AddProfileTimelineMarker(Move(marker)); + TimelineConsumers::AddMarkerForDocShell(docShell, Move(marker)); } } } diff --git a/layout/base/nsPresShell.cpp b/layout/base/nsPresShell.cpp index 9e080df095..0738e19691 100644 --- a/layout/base/nsPresShell.cpp +++ b/layout/base/nsPresShell.cpp @@ -8909,7 +8909,7 @@ PresShell::DoReflow(nsIFrame* target, bool aInterruptible) nsDocShell* docShell = static_cast(GetPresContext()->GetDocShell()); if (docShell) { - docShell->AddProfileTimelineMarker("Reflow", TRACING_INTERVAL_START); + TimelineConsumers::AddMarkerForDocShell(docShell, "Reflow", TRACING_INTERVAL_START); } if (mReflowContinueTimer) { @@ -9086,7 +9086,7 @@ PresShell::DoReflow(nsIFrame* target, bool aInterruptible) } if (docShell) { - docShell->AddProfileTimelineMarker("Reflow", TRACING_INTERVAL_END); + TimelineConsumers::AddMarkerForDocShell(docShell, "Reflow", TRACING_INTERVAL_END); } return !interrupted; } diff --git a/layout/base/nsRefreshDriver.cpp b/layout/base/nsRefreshDriver.cpp index 4e45cb33c8..e961357c82 100644 --- a/layout/base/nsRefreshDriver.cpp +++ b/layout/base/nsRefreshDriver.cpp @@ -62,6 +62,7 @@ #include "mozilla/VsyncDispatcher.h" #include "nsThreadUtils.h" #include "mozilla/unused.h" +#include "mozilla/TimelineConsumers.h" #ifdef MOZ_NUWA_PROCESS #include "ipc/Nuwa.h" @@ -995,7 +996,7 @@ RefreshDriverTimer* nsRefreshDriver::ChooseTimer() const { if (mThrottled) { - if (!sThrottledRateTimer) + if (!sThrottledRateTimer) sThrottledRateTimer = new InactiveRefreshDriverTimer(GetThrottledTimerInterval(), DEFAULT_INACTIVE_TIMER_DISABLE_SECONDS * 1000.0); return sThrottledRateTimer; @@ -1053,7 +1054,7 @@ nsRefreshDriver::~nsRefreshDriver() MOZ_ASSERT(ObserverCount() == 0, "observers should have unregistered"); MOZ_ASSERT(!mActiveTimer, "timer should be gone"); - + if (mRootRefresh) { mRootRefresh->RemoveRefreshObserver(this, Flush_Style); mRootRefresh = nullptr; @@ -1437,7 +1438,7 @@ HasPendingAnimations(nsIPresShell* aShell) static void GetProfileTimelineSubDocShells(nsDocShell* aRootDocShell, nsTArray& aShells) { - if (!aRootDocShell || nsDocShell::gProfileTimelineRecordingsCount == 0) { + if (!aRootDocShell || TimelineConsumers::IsEmpty()) { return; } @@ -1801,9 +1802,8 @@ nsRefreshDriver::Tick(int64_t aNowEpoch, TimeStamp aNowTime) for (nsDocShell* docShell : profilingDocShells) { // For the sake of the profile timeline's simplicity, this is flagged as // paint even if it includes creating display lists - docShell->AddProfileTimelineMarker("Paint", TRACING_INTERVAL_START); + TimelineConsumers::AddMarkerForDocShell(docShell, "Paint", TRACING_INTERVAL_START); } - profiler_tracing("Paint", "DisplayList", TRACING_INTERVAL_START); #ifdef MOZ_DUMP_PAINTING if (nsLayoutUtils::InvalidationDebuggingIsEnabled()) { printf_stderr("Starting ProcessPendingUpdates\n"); @@ -1819,9 +1819,8 @@ nsRefreshDriver::Tick(int64_t aNowEpoch, TimeStamp aNowTime) } #endif 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()) { nsContentUtils::XPConnect()->NotifyDidPaint(); diff --git a/layout/style/test/animation_utils.js b/layout/style/test/animation_utils.js index 9456dcae67..fead18dd5a 100644 --- a/layout/style/test/animation_utils.js +++ b/layout/style/test/animation_utils.js @@ -55,7 +55,7 @@ function advance_clock(milliseconds) { // This function checks that the list of eventsExpected matches // the received events -- but it only checks the properties that // are present on eventsExpected. - is(gEventsReceived.length, gEventsReceived.length, + is(gEventsReceived.length, eventsExpected.length, "number of events received for " + desc); for (var i = 0, i_end = Math.min(eventsExpected.length, gEventsReceived.length); diff --git a/testing/web-platform/meta/js/builtins/WeakMap.prototype-properties.html.ini b/testing/web-platform/meta/js/builtins/WeakMap.prototype-properties.html.ini index 04efb3bcdc..849c761e19 100644 --- a/testing/web-platform/meta/js/builtins/WeakMap.prototype-properties.html.ini +++ b/testing/web-platform/meta/js/builtins/WeakMap.prototype-properties.html.ini @@ -1,5 +1,5 @@ [WeakMap.prototype-properties.html] type: testharness - [WeakMap.prototype.get.length] + [WeakMap.prototype.@@toStringTag] expected: FAIL diff --git a/view/nsViewManager.cpp b/view/nsViewManager.cpp index f6525cb4a1..b670fe8113 100644 --- a/view/nsViewManager.cpp +++ b/view/nsViewManager.cpp @@ -386,6 +386,7 @@ nsViewManager::ProcessPendingUpdatesForView(nsView* aView, return; // presentation might have been torn down } if (aFlushDirtyRegion) { + profiler_tracing("Paint", "DisplayList", TRACING_INTERVAL_START); nsAutoScriptBlocker scriptBlocker; SetPainting(true); for (uint32_t i = 0; i < widgets.Length(); ++i) { @@ -396,6 +397,7 @@ nsViewManager::ProcessPendingUpdatesForView(nsView* aView, } } SetPainting(false); + profiler_tracing("Paint", "DisplayList", TRACING_INTERVAL_END); } } diff --git a/xpcom/base/nsCycleCollector.cpp b/xpcom/base/nsCycleCollector.cpp index b658a53cf8..eb7dad5f79 100644 --- a/xpcom/base/nsCycleCollector.cpp +++ b/xpcom/base/nsCycleCollector.cpp @@ -183,7 +183,7 @@ #include #include -#include "mozilla/AutoTimelineMarker.h" +#include "mozilla/AutoGlobalTimelineMarker.h" #include "mozilla/Likely.h" #include "mozilla/PoisonIOInterposer.h" #include "mozilla/ThreadLocal.h"