diff --git a/accessible/tests/mochitest/aom/test_general.html b/accessible/tests/mochitest/aom/test_general.html index 1a9c6911e21a..3b9fe4be359c 100644 --- a/accessible/tests/mochitest/aom/test_general.html +++ b/accessible/tests/mochitest/aom/test_general.html @@ -97,8 +97,8 @@ is(anode.attributes.length, attrs.length, 'correct number of attributes'); for (var i = 0; i < attrs.length; i++) { - is(anode.attributes[i], attrs[i], - `${attrs[i]} attribute is expected at ${i}th index`); + ok(attrs.indexOf(anode.attributes[i]) >= 0, + `${anode.attributes[i]} attribute is expected and found`); } finish(); diff --git a/browser/base/content/test/performance/browser.ini b/browser/base/content/test/performance/browser.ini index bda9c0786a65..a343bf340107 100644 --- a/browser/base/content/test/performance/browser.ini +++ b/browser/base/content/test/performance/browser.ini @@ -3,6 +3,8 @@ support-files = head.js [browser_appmenu_reflows.js] [browser_startup.js] +[browser_startup_content.js] +skip-if = !e10s [browser_startup_images.js] skip-if = !debug [browser_tabclose_grow_reflows.js] diff --git a/browser/base/content/test/performance/browser_startup_content.js b/browser/base/content/test/performance/browser_startup_content.js new file mode 100644 index 000000000000..4a6983463c88 --- /dev/null +++ b/browser/base/content/test/performance/browser_startup_content.js @@ -0,0 +1,81 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +/* This test records which services, JS components and JS modules are loaded + * when creating a new content process. + * + * If you made changes that cause this test to fail, it's likely because you + * are loading more JS code during content process startup. + * + * If your code isn't strictly required to show a page, consider loading it + * lazily. If you can't, consider delaying its load until after we have started + * handling user events. + */ + +"use strict"; + +const blacklist = { + components: new Set([ + "PushComponents.js", + "TelemetryStartup.js", + ]), + modules: new Set([ + "resource:///modules/ContentWebRTC.jsm", + "resource://gre/modules/InlineSpellChecker.jsm", + "resource://gre/modules/InlineSpellCheckerContent.jsm", + "resource://gre/modules/Promise.jsm", + "resource://gre/modules/Task.jsm", + "resource://gre/modules/debug.js", + "resource://gre/modules/osfile.jsm", + ]), + services: new Set([ + "@mozilla.org/base/telemetry-startup;1", + "@mozilla.org/push/Service;1", + ]) +}; + +add_task(async function() { + SimpleTest.requestCompleteLog(); + + let tab = await BrowserTestUtils.openNewForegroundTab({gBrowser, + forceNewProcess: true}); + + let mm = gBrowser.selectedBrowser.messageManager; + let promise = BrowserTestUtils.waitForMessage(mm, "Test:LoadedScripts"); + + // Load a custom frame script to avoid using ContentTask which loads Task.jsm + mm.loadFrameScript("data:text/javascript,(" + function() { + /* eslint-env mozilla/frame-script */ + const {classes: Cc, interfaces: Ci, manager: Cm} = Components; + Cm.QueryInterface(Ci.nsIServiceManager); + + let loader = Cc["@mozilla.org/moz/jsloader;1"].getService(Ci.xpcIJSModuleLoader); + sendAsyncMessage("Test:LoadedScripts", { + /* Keep only the file name for components, as the path is an absolute file + URL rather than a resource:// URL like for modules. */ + components: loader.loadedComponents().map(f => f.replace(/.*\//, "")), + modules: loader.loadedModules(), + services: Object.keys(Cc).filter(c => { + try { + Cm.isServiceInstantiatedByContractID(c, Ci.nsISupports); + return true; + } catch (e) { + return false; + } + }) + }); + } + ")()", false); + + let loadedList = await promise; + for (let scriptType in blacklist) { + info(scriptType); + for (let file of blacklist[scriptType]) { + ok(!loadedList[scriptType].includes(file), `${file} is not allowed`); + } + for (let file of loadedList[scriptType]) { + info(file); + } + } + + await BrowserTestUtils.removeTab(tab); +}); diff --git a/browser/components/extensions/ExtensionPopups.jsm b/browser/components/extensions/ExtensionPopups.jsm index 452e0b5cacc9..49d50f831cd7 100644 --- a/browser/components/extensions/ExtensionPopups.jsm +++ b/browser/components/extensions/ExtensionPopups.jsm @@ -421,6 +421,9 @@ class ViewPopup extends BasePopup { // be swapped with the browser in the real panel when it's ready. let panel = document.createElement("panel"); panel.setAttribute("type", "arrow"); + if (extension.remote) { + panel.setAttribute("remote", "true"); + } document.getElementById("mainPopupSet").appendChild(panel); super(extension, panel, popupURL, browserStyle, fixedWidth, blockParser); diff --git a/browser/components/extensions/ext-c-omnibox.js b/browser/components/extensions/ext-c-omnibox.js index 11e9d5bb0f3e..b9bb75929969 100644 --- a/browser/components/extensions/ext-c-omnibox.js +++ b/browser/components/extensions/ext-c-omnibox.js @@ -12,15 +12,15 @@ this.omnibox = class extends ExtensionAPI { onInputChanged: new EventManager(context, "omnibox.onInputChanged", fire => { let listener = (text, id) => { fire.asyncWithoutClone(text, suggestions => { - context.childManager.callParentFunctionNoReturn("omnibox_internal.addSuggestions", [ + context.childManager.callParentFunctionNoReturn("omnibox.addSuggestions", [ id, suggestions, ]); }); }; - context.childManager.getParentEvent("omnibox_internal.onInputChanged").addListener(listener); + context.childManager.getParentEvent("omnibox.onInputChanged").addListener(listener); return () => { - context.childManager.getParentEvent("omnibox_internal.onInputChanged").removeListener(listener); + context.childManager.getParentEvent("omnibox.onInputChanged").removeListener(listener); }; }).api(), }, diff --git a/browser/components/extensions/ext-omnibox.js b/browser/components/extensions/ext-omnibox.js index b85b112ad8f5..45e1d22a7ab3 100644 --- a/browser/components/extensions/ext-omnibox.js +++ b/browser/components/extensions/ext-omnibox.js @@ -69,9 +69,8 @@ this.omnibox = class extends ExtensionAPI { extension.off(ExtensionSearchHandler.MSG_INPUT_ENTERED, listener); }; }).api(), - }, - omnibox_internal: { + // Internal APIs. addSuggestions: (id, suggestions) => { try { ExtensionSearchHandler.addSuggestions(this.keyword, id, suggestions); @@ -81,7 +80,7 @@ this.omnibox = class extends ExtensionAPI { } }, - onInputChanged: new EventManager(context, "omnibox_internal.onInputChanged", fire => { + onInputChanged: new EventManager(context, "omnibox.onInputChanged", fire => { let listener = (eventName, text, id) => { fire.sync(text, id); }; diff --git a/browser/components/extensions/schemas/omnibox.json b/browser/components/extensions/schemas/omnibox.json index 34428fab77c4..0f6a549284df 100644 --- a/browser/components/extensions/schemas/omnibox.json +++ b/browser/components/extensions/schemas/omnibox.json @@ -197,52 +197,5 @@ "parameters": [] } ] - }, - { - "namespace": "omnibox_internal", - "description": "The internal namespace used by the omnibox API.", - "defaultContexts": ["addon_parent_only"], - "functions": [ - { - "name": "addSuggestions", - "type": "function", - "async": "callback", - "description": "Internal function used by omnibox.onInputChanged for adding search suggestions", - "parameters": [ - { - "name": "id", - "type": "integer", - "description": "The ID of the callback received by onInputChangedInternal" - }, - { - "name": "suggestResults", - "type": "array", - "description": "Array of suggest results", - "items": { - "$ref": "omnibox.SuggestResult" - } - }, - { - "type": "function", - "name": "callback", - "optional": true, - "parameters": [] - } - ] - } - ], - "events": [ - { - "name": "onInputChanged", - "type": "function", - "description": "Identical to omnibox.onInputChanged except no 'suggest' callback is provided.", - "parameters": [ - { - "type": "string", - "name": "text" - } - ] - } - ] } -] \ No newline at end of file +] diff --git a/config/system-headers b/config/system-headers index 9ffd83cd0efe..ba8e03efcce7 100644 --- a/config/system-headers +++ b/config/system-headers @@ -887,6 +887,7 @@ rpc/types.h sane/sane.h sane/sanei.h sane/saneopts.h +sanitizer/asan_interface.h sched.h Scrap.h Screen.h diff --git a/devtools/client/inspector/grids/components/GridDisplaySettings.js b/devtools/client/inspector/grids/components/GridDisplaySettings.js index fc05274b66a6..04745766dc23 100644 --- a/devtools/client/inspector/grids/components/GridDisplaySettings.js +++ b/devtools/client/inspector/grids/components/GridDisplaySettings.js @@ -96,7 +96,7 @@ module.exports = createClass({ onChange: this.onShowGridLineNumbersCheckboxClick, } ), - getStr("layout.displayNumbersOnLines") + getStr("layout.displayNumbersOnLines2") ) ), dom.li( diff --git a/devtools/client/inspector/shared/test/browser_styleinspector_tooltip-longhand-fontfamily.js b/devtools/client/inspector/shared/test/browser_styleinspector_tooltip-longhand-fontfamily.js index 713c9d06869d..f5e87dfc4f32 100644 --- a/devtools/client/inspector/shared/test/browser_styleinspector_tooltip-longhand-fontfamily.js +++ b/devtools/client/inspector/shared/test/browser_styleinspector_tooltip-longhand-fontfamily.js @@ -49,6 +49,7 @@ function* testRuleView(ruleView, nodeFront) { "font-family"); // And verify that the tooltip gets shown on this property + valueSpan.scrollIntoView(true); let previewTooltip = yield assertShowPreviewTooltip(ruleView, valueSpan); let images = panel.getElementsByTagName("img"); @@ -70,6 +71,7 @@ function* testComputedView(computedView, nodeFront) { let panel = tooltip.panel; let {valueSpan} = getComputedViewProperty(computedView, "font-family"); + valueSpan.scrollIntoView(true); let previewTooltip = yield assertShowPreviewTooltip(computedView, valueSpan); let images = panel.getElementsByTagName("img"); @@ -99,6 +101,7 @@ function* testExpandedComputedViewProperty(computedView, nodeFront) { let tooltip = computedView.tooltips.getTooltip("previewTooltip"); let panel = tooltip.panel; + valueSpan.scrollIntoView(true); let previewTooltip = yield assertShowPreviewTooltip(computedView, valueSpan); let images = panel.getElementsByTagName("img"); diff --git a/devtools/client/inspector/test/head.js b/devtools/client/inspector/test/head.js index a7fec69b8d64..be08c23dd522 100644 --- a/devtools/client/inspector/test/head.js +++ b/devtools/client/inspector/test/head.js @@ -710,7 +710,7 @@ function* assertShowPreviewTooltip(view, target) { let name = "previewTooltip"; ok(view.tooltips._instances.has(name), - `Tooltip '${name}' has been instanciated`); + `Tooltip '${name}' has been instantiated`); let tooltip = view.tooltips.getTooltip(name); if (!tooltip.isVisible()) { diff --git a/devtools/client/locales/en-US/layout.properties b/devtools/client/locales/en-US/layout.properties index 423db443b015..675127fd60fc 100644 --- a/devtools/client/locales/en-US/layout.properties +++ b/devtools/client/locales/en-US/layout.properties @@ -14,9 +14,9 @@ layout.cannotShowGridOutline.title=The selected grid’s outline cannot effectiv # option in the CSS Grid pane. layout.displayGridAreas=Display grid areas -# LOCALIZATION NOTE (layout.displayNumbersOnLines): Label of the display numbers on lines +# LOCALIZATION NOTE (layout.displayNumbersOnLines2): Label of the display numbers on lines # setting option in the CSS Grid pane. -layout.displayNumbersOnLines=Display numbers on lines +layout.displayNumbersOnLines2=Display line numbers # LOCALIZATION NOTE (layout.extendGridLinesInfinitely): Label of the extend grid lines # infinitely setting option in the CSS Grid pane. diff --git a/dom/base/CustomElementRegistry.cpp b/dom/base/CustomElementRegistry.cpp index 18bc269ce48f..4e7eef67a7e8 100644 --- a/dom/base/CustomElementRegistry.cpp +++ b/dom/base/CustomElementRegistry.cpp @@ -487,10 +487,8 @@ CustomElementRegistry::UpgradeCandidates(JSContext* aCx, } nsAutoPtr> candidates; - mCandidatesMap.RemoveAndForget(aKey, candidates); - if (candidates) { - - + if (mCandidatesMap.Remove(aKey, &candidates)) { + MOZ_ASSERT(candidates); CustomElementReactionsStack* reactionsStack = docGroup->CustomElementReactionsStack(); for (size_t i = 0; i < candidates->Length(); ++i) { diff --git a/dom/base/FlushType.h b/dom/base/FlushType.h index 0b0a06f5247a..f0c285b18df0 100644 --- a/dom/base/FlushType.h +++ b/dom/base/FlushType.h @@ -27,12 +27,13 @@ enum class FlushType : uint8_t { notifications. */ Style = 3, /* As above, plus flush style reresolution */ Frames = Style, - InterruptibleLayout = 4, /* As above, plus flush reflow, + EnsurePresShellInitAndFrames = 4, /* As above, plus ensure the pres shell is alive */ + InterruptibleLayout = 5, /* As above, plus flush reflow, but allow it to be interrupted (so an incomplete layout may result) */ - Layout = 5, /* As above, but layout must run to + Layout = 6, /* As above, but layout must run to completion */ - Display = 6, /* As above, plus flush painting */ + Display = 7, /* As above, plus flush painting */ Count }; diff --git a/dom/base/nsContentUtils.cpp b/dom/base/nsContentUtils.cpp index af45e84feaa1..e3c6a3ac86f5 100644 --- a/dom/base/nsContentUtils.cpp +++ b/dom/base/nsContentUtils.cpp @@ -302,6 +302,7 @@ bool nsContentUtils::sSkipCursorMoveForSameValueSet = false; bool nsContentUtils::sRequestIdleCallbackEnabled = false; bool nsContentUtils::sLowerNetworkPriority = false; bool nsContentUtils::sShowInputPlaceholderOnFocus = true; +bool nsContentUtils::sAutoFocusEnabled = true; #ifndef RELEASE_OR_BETA bool nsContentUtils::sBypassCSSOMOriginCheck = false; #endif @@ -764,6 +765,9 @@ nsContentUtils::Init() Preferences::AddBoolVarCache(&sShowInputPlaceholderOnFocus, "dom.placeholder.show_on_focus", true); + Preferences::AddBoolVarCache(&sAutoFocusEnabled, + "browser.autofocus", true); + Preferences::AddBoolVarCache(&sIsBytecodeCacheEnabled, "dom.script_loader.bytecode_cache.enabled", false); diff --git a/dom/base/nsContentUtils.h b/dom/base/nsContentUtils.h index b506b4c5d56c..81e082ae0570 100644 --- a/dom/base/nsContentUtils.h +++ b/dom/base/nsContentUtils.h @@ -3059,6 +3059,10 @@ public: // when they have focus. static bool ShowInputPlaceholderOnFocus() { return sShowInputPlaceholderOnFocus; } + // Check pref "browser.autofocus" to see if we want to enable autofocusing elements + // when the page requests it. + static bool AutoFocusEnabled() { return sAutoFocusEnabled; } + // Check pref "dom.script_loader.bytecode_cache.enabled" to see // if we want to cache JS bytecode on the cache entry. static bool IsBytecodeCacheEnabled() { return sIsBytecodeCacheEnabled; } @@ -3219,6 +3223,7 @@ private: static bool sRequestIdleCallbackEnabled; static bool sLowerNetworkPriority; static bool sShowInputPlaceholderOnFocus; + static bool sAutoFocusEnabled; #ifndef RELEASE_OR_BETA static bool sBypassCSSOMOriginCheck; #endif diff --git a/dom/base/nsFocusManager.cpp b/dom/base/nsFocusManager.cpp index 2d0839b9d1a3..596cb1178e7f 100644 --- a/dom/base/nsFocusManager.cpp +++ b/dom/base/nsFocusManager.cpp @@ -1567,9 +1567,10 @@ nsFocusManager::CheckIfFocusable(nsIContent* aContent, uint32_t aFlags) return nullptr; } - // Make sure that our frames are up to date + // Make sure that our frames are up to date while ensuring the presshell is + // also initialized in case we come from an autofocus event. mEventHandlingNeedsFlush = false; - doc->FlushPendingNotifications(FlushType::Frames); + doc->FlushPendingNotifications(FlushType::EnsurePresShellInitAndFrames); nsIPresShell *shell = doc->GetShell(); if (!shell) diff --git a/dom/base/nsIContent.h b/dom/base/nsIContent.h index 734f3f3ad0ae..f3faf67b4689 100644 --- a/dom/base/nsIContent.h +++ b/dom/base/nsIContent.h @@ -527,10 +527,12 @@ public: * Determines if an event attribute name (such as onclick) is valid for * a given element type. * @note calls nsContentUtils::IsEventAttributeName with right flag - * @note overridden by subclasses as needed + * @note *Internal is overridden by subclasses as needed * @param aName the event name to look up */ - virtual bool IsEventAttributeName(nsIAtom* aName) + bool IsEventAttributeName(nsIAtom* aName); + + virtual bool IsEventAttributeNameInternal(nsIAtom* aName) { return false; } diff --git a/dom/base/nsIContentInlines.h b/dom/base/nsIContentInlines.h index 439b281575a5..4f074f732c8d 100644 --- a/dom/base/nsIContentInlines.h +++ b/dom/base/nsIContentInlines.h @@ -10,6 +10,7 @@ #include "nsIContent.h" #include "nsIDocument.h" #include "nsContentUtils.h" +#include "nsIAtom.h" #include "mozilla/dom/Element.h" inline bool @@ -94,6 +95,17 @@ nsIContent::GetFlattenedTreeParent() const return (parent && parent->IsContent()) ? parent->AsContent() : nullptr; } +inline bool +nsIContent::IsEventAttributeName(nsIAtom* aName) +{ + const char16_t* name = aName->GetUTF16String(); + if (name[0] != 'o' || name[1] != 'n') { + return false; + } + + return IsEventAttributeNameInternal(aName); +} + inline nsINode* nsINode::GetFlattenedTreeParentNodeForStyle() const { diff --git a/dom/base/nsMappedAttributes.cpp b/dom/base/nsMappedAttributes.cpp index 0c5d6f0c615b..5fb4f4436cd8 100644 --- a/dom/base/nsMappedAttributes.cpp +++ b/dom/base/nsMappedAttributes.cpp @@ -230,10 +230,10 @@ nsMappedAttributes::Equals(const nsMappedAttributes* aOther) const return true; } -uint32_t +PLDHashNumber nsMappedAttributes::HashValue() const { - uint32_t hash = HashGeneric(mRuleMapper); + PLDHashNumber hash = HashGeneric(mRuleMapper); uint32_t i; for (i = 0; i < mAttrCount; ++i) { diff --git a/dom/base/nsMappedAttributes.h b/dom/base/nsMappedAttributes.h index 4cf5134c2492..cbd4f98a3eda 100644 --- a/dom/base/nsMappedAttributes.h +++ b/dom/base/nsMappedAttributes.h @@ -45,7 +45,7 @@ public: } bool Equals(const nsMappedAttributes* aAttributes) const; - uint32_t HashValue() const; + PLDHashNumber HashValue() const; void DropStyleSheetReference() { diff --git a/dom/base/nsXMLContentSerializer.cpp b/dom/base/nsXMLContentSerializer.cpp index d04f3535c715..839a8b50ceb0 100644 --- a/dom/base/nsXMLContentSerializer.cpp +++ b/dom/base/nsXMLContentSerializer.cpp @@ -17,6 +17,7 @@ #include "nsIDOMComment.h" #include "nsIDOMDocumentType.h" #include "nsIContent.h" +#include "nsIContentInlines.h" #include "nsIDocument.h" #include "nsIDocumentEncoder.h" #include "nsIParserService.h" diff --git a/dom/bindings/WebIDLGlobalNameHash.cpp b/dom/bindings/WebIDLGlobalNameHash.cpp index af5a6dce4f01..2478b83323e1 100644 --- a/dom/bindings/WebIDLGlobalNameHash.cpp +++ b/dom/bindings/WebIDLGlobalNameHash.cpp @@ -49,7 +49,7 @@ struct MOZ_STACK_CLASS WebIDLNameTableKey const char* mLatin1String; const char16_t* mTwoBytesString; size_t mLength; - uint32_t mHash; + PLDHashNumber mHash; }; struct WebIDLNameTableEntry : public PLDHashEntryHdr diff --git a/dom/console/Console.cpp b/dom/console/Console.cpp index a0217328413a..1f50c4b149c5 100644 --- a/dom/console/Console.cpp +++ b/dom/console/Console.cpp @@ -2085,10 +2085,7 @@ Console::StopTimer(JSContext* aCx, const JS::Value& aName, aTimerLabel = key; DOMHighResTimeStamp value = 0; - if (auto entry = mTimerRegistry.Lookup(key)) { - value = entry.Data(); - entry.Remove(); - } else { + if (!mTimerRegistry.Remove(key, &value)) { NS_WARNING("mTimerRegistry entry not found"); return eTimerDoesntExist; } diff --git a/dom/events/EventListenerManager.cpp b/dom/events/EventListenerManager.cpp index 887856620f91..0c1dc8dab111 100644 --- a/dom/events/EventListenerManager.cpp +++ b/dom/events/EventListenerManager.cpp @@ -33,9 +33,7 @@ #include "EventListenerService.h" #include "GeckoProfiler.h" -#ifdef MOZ_GECKO_PROFILER #include "ProfilerMarkerPayload.h" -#endif #include "nsCOMArray.h" #include "nsCOMPtr.h" #include "nsContentUtils.h" @@ -1288,7 +1286,6 @@ EventListenerManager::HandleEventInternal(nsPresContext* aPresContext, nsresult rv = NS_OK; if (profiler_is_active()) { -#ifdef MOZ_GECKO_PROFILER // Add a profiler label and a profiler marker for the actual // dispatch of the event. // This is a very hot code path, so we need to make sure not to @@ -1310,7 +1307,6 @@ EventListenerManager::HandleEventInternal(nsPresContext* aPresContext, "DOMEvent", MakeUnique(typeStr, phase, startTime, endTime)); -#endif } else { rv = HandleEventSubType(listener, *aDOMEvent, aCurrentTarget); } diff --git a/dom/html/HTMLBodyElement.cpp b/dom/html/HTMLBodyElement.cpp index 3a6653a903f0..4ff496285fa2 100644 --- a/dom/html/HTMLBodyElement.cpp +++ b/dom/html/HTMLBodyElement.cpp @@ -422,7 +422,7 @@ HTMLBodyElement::GetAssociatedEditor() } bool -HTMLBodyElement::IsEventAttributeName(nsIAtom *aName) +HTMLBodyElement::IsEventAttributeNameInternal(nsIAtom *aName) { return nsContentUtils::IsEventAttributeName(aName, EventNameType_HTML | diff --git a/dom/html/HTMLBodyElement.h b/dom/html/HTMLBodyElement.h index cf24bcf2d0f0..5373d9ca54a0 100644 --- a/dom/html/HTMLBodyElement.h +++ b/dom/html/HTMLBodyElement.h @@ -109,7 +109,7 @@ public: virtual nsresult Clone(mozilla::dom::NodeInfo *aNodeInfo, nsINode **aResult, bool aPreallocateChildren) const override; - virtual bool IsEventAttributeName(nsIAtom* aName) override; + virtual bool IsEventAttributeNameInternal(nsIAtom* aName) override; virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent, diff --git a/dom/html/HTMLFrameSetElement.cpp b/dom/html/HTMLFrameSetElement.cpp index 861dbfe9fc86..7f48d5fe1c55 100644 --- a/dom/html/HTMLFrameSetElement.cpp +++ b/dom/html/HTMLFrameSetElement.cpp @@ -337,7 +337,7 @@ HTMLFrameSetElement::ParseRowCol(const nsAString & aValue, } bool -HTMLFrameSetElement::IsEventAttributeName(nsIAtom *aName) +HTMLFrameSetElement::IsEventAttributeNameInternal(nsIAtom *aName) { return nsContentUtils::IsEventAttributeName(aName, EventNameType_HTML | diff --git a/dom/html/HTMLFrameSetElement.h b/dom/html/HTMLFrameSetElement.h index 93aaee2f7f01..6b16a337c7a9 100644 --- a/dom/html/HTMLFrameSetElement.h +++ b/dom/html/HTMLFrameSetElement.h @@ -82,7 +82,7 @@ public: SetHTMLAttr(nsGkAtoms::rows, aRows, aError); } - virtual bool IsEventAttributeName(nsIAtom *aName) override; + virtual bool IsEventAttributeNameInternal(nsIAtom *aName) override; // Event listener stuff; we need to declare only the ones we need to // forward to window that don't come from nsIDOMHTMLFrameSetElement. diff --git a/dom/html/HTMLMediaElement.cpp b/dom/html/HTMLMediaElement.cpp index e74d69ca816d..76b5793646fa 100644 --- a/dom/html/HTMLMediaElement.cpp +++ b/dom/html/HTMLMediaElement.cpp @@ -7005,10 +7005,10 @@ HTMLMediaElement::DispatchEncrypted(const nsTArray& aInitData, } bool -HTMLMediaElement::IsEventAttributeName(nsIAtom* aName) +HTMLMediaElement::IsEventAttributeNameInternal(nsIAtom* aName) { return aName == nsGkAtoms::onencrypted || - nsGenericHTMLElement::IsEventAttributeName(aName); + nsGenericHTMLElement::IsEventAttributeNameInternal(aName); } already_AddRefed diff --git a/dom/html/HTMLMediaElement.h b/dom/html/HTMLMediaElement.h index d4def6fff6e3..fd6865d32903 100644 --- a/dom/html/HTMLMediaElement.h +++ b/dom/html/HTMLMediaElement.h @@ -653,7 +653,7 @@ public: void DispatchEncrypted(const nsTArray& aInitData, const nsAString& aInitDataType) override; - bool IsEventAttributeName(nsIAtom* aName) override; + bool IsEventAttributeNameInternal(nsIAtom* aName) override; // Returns the principal of the "top level" document; the origin displayed // in the URL bar of the browser window. diff --git a/dom/html/nsGenericHTMLElement.cpp b/dom/html/nsGenericHTMLElement.cpp index c287cd1039fd..99dc20895bc7 100644 --- a/dom/html/nsGenericHTMLElement.cpp +++ b/dom/html/nsGenericHTMLElement.cpp @@ -1910,7 +1910,7 @@ nsGenericHTMLFormElement::BindToTree(nsIDocument* aDocument, // the document should not be already loaded and the "browser.autofocus" // preference should be 'true'. if (IsAutofocusable() && HasAttr(kNameSpaceID_None, nsGkAtoms::autofocus) && - Preferences::GetBool("browser.autofocus", true)) { + nsContentUtils::AutoFocusEnabled()) { nsCOMPtr event = new nsAutoFocusEvent(this); rv = NS_DispatchToCurrentThread(event); NS_ENSURE_SUCCESS(rv, rv); @@ -2925,7 +2925,7 @@ nsGenericHTMLElement::GetWidthHeightForImage(RefPtr& aImageRequ } bool -nsGenericHTMLElement::IsEventAttributeName(nsIAtom *aName) +nsGenericHTMLElement::IsEventAttributeNameInternal(nsIAtom *aName) { return nsContentUtils::IsEventAttributeName(aName, EventNameType_HTML); } diff --git a/dom/html/nsGenericHTMLElement.h b/dom/html/nsGenericHTMLElement.h index a8b67b3f68c7..cb47f8ed0c87 100644 --- a/dom/html/nsGenericHTMLElement.h +++ b/dom/html/nsGenericHTMLElement.h @@ -201,7 +201,7 @@ public: * @param aName the attribute * @return whether the name is an event handler name */ - virtual bool IsEventAttributeName(nsIAtom* aName) override; + virtual bool IsEventAttributeNameInternal(nsIAtom* aName) override; #define EVENT(name_, id_, type_, struct_) /* nothing; handled by nsINode */ // The using nsINode::Get/SetOn* are to avoid warnings about shadowing the XPCOM diff --git a/dom/html/nsHTMLContentSink.cpp b/dom/html/nsHTMLContentSink.cpp index 3908a7036638..f74568ebe70d 100644 --- a/dom/html/nsHTMLContentSink.cpp +++ b/dom/html/nsHTMLContentSink.cpp @@ -23,7 +23,6 @@ #include "nsIContentViewer.h" #include "mozilla/dom/NodeInfo.h" #include "mozilla/dom/ScriptLoader.h" -#include "nsToken.h" #include "nsIAppShell.h" #include "nsCRT.h" #include "prtime.h" @@ -1068,7 +1067,7 @@ HTMLContentSink::FlushPendingNotifications(FlushType aType) FlushTags(); } } - if (aType >= FlushType::InterruptibleLayout) { + if (aType >= FlushType::EnsurePresShellInitAndFrames) { // Make sure that layout has started so that the reflow flush // will actually happen. StartLayout(true); diff --git a/dom/indexedDB/test/browser.ini b/dom/indexedDB/test/browser.ini index 8d72d93cb271..85671568dca5 100644 --- a/dom/indexedDB/test/browser.ini +++ b/dom/indexedDB/test/browser.ini @@ -16,7 +16,6 @@ support-files = [browser_forgetThisSite.js] [browser_permissionsPromptAllow.js] [browser_permissionsPromptDeny.js] -skip-if = os == 'mac' # bug 1324163 [browser_permissionsPromptWorker.js] [browser_perwindow_privateBrowsing.js] [browser_bug839193.js] diff --git a/dom/indexedDB/test/browser_permissionsPromptDeny.js b/dom/indexedDB/test/browser_permissionsPromptDeny.js index 8b8cc46bde59..23d43b474e72 100644 --- a/dom/indexedDB/test/browser_permissionsPromptDeny.js +++ b/dom/indexedDB/test/browser_permissionsPromptDeny.js @@ -7,30 +7,39 @@ const testPageURL = "http://mochi.test:8888/browser/" + "dom/indexedDB/test/browser_permissionsPrompt.html"; const notificationID = "indexedDB-permissions-prompt"; -function promiseMessage(aMessage, browser) { - return ContentTask.spawn(browser.selectedBrowser, aMessage, async function(aMessage) { - await new Promise((resolve, reject) => { - content.addEventListener("message", function(event) { - is(event.data, aMessage, "received " + aMessage); - if (event.data == aMessage) - resolve(); - else - reject(); - }, {once: true}); +function waitForMessage(aMessage, browser) { + return new Promise((resolve, reject) => { + /* eslint-disable no-undef */ + function contentScript() { + addEventListener("message", function(event) { + sendAsyncMessage("testLocal:exception", + {exception: event.data}); + }, {once: true}, true); + } + /* eslint-enable no-undef */ + + let script = "data:,(" + contentScript.toString() + ")();"; + + let mm = browser.selectedBrowser.messageManager; + + mm.addMessageListener("testLocal:exception", function listener(msg) { + mm.removeMessageListener("testLocal:exception", listener); + mm.removeDelayedFrameScript(script); + is(msg.data.exception, aMessage, "received " + aMessage); + if (msg.data.exception == aMessage) { + resolve(); + } else { + reject(); + } }); + + mm.loadFrameScript(script, true); }); } add_task(async function test1() { removePermission(testPageURL, "indexedDB"); - info("creating tab"); - gBrowser.selectedTab = BrowserTestUtils.addTab(gBrowser); - - info("loading test page: " + testPageURL); - gBrowser.selectedBrowser.loadURI(testPageURL); - await BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser); - registerPopupEventHandler("popupshowing", function() { ok(true, "prompt showing"); }); @@ -42,7 +51,12 @@ add_task(async function test1() { ok(true, "prompt hidden"); }); - await promiseMessage("InvalidStateError", gBrowser); + info("creating tab"); + gBrowser.selectedTab = BrowserTestUtils.addTab(gBrowser); + + info("loading test page: " + testPageURL); + gBrowser.selectedBrowser.loadURI(testPageURL); + await waitForMessage("InvalidStateError", gBrowser); is(getPermission(testPageURL, "indexedDB"), Components.interfaces.nsIPermissionManager.DENY_ACTION, @@ -54,23 +68,22 @@ add_task(async function test2() { info("creating private window"); let win = await BrowserTestUtils.openNewBrowserWindow({ private: true }); + registerPopupEventHandler("popupshowing", function() { + ok(false, "prompt showing"); + }, win); + registerPopupEventHandler("popupshown", function() { + ok(false, "prompt shown"); + }, win); + registerPopupEventHandler("popuphidden", function() { + ok(false, "prompt hidden"); + }, win); + info("creating private tab"); win.gBrowser.selectedTab = win.gBrowser.addTab(); info("loading test page: " + testPageURL); win.gBrowser.selectedBrowser.loadURI(testPageURL); - await BrowserTestUtils.browserLoaded(win.gBrowser.selectedBrowser); - - registerPopupEventHandler("popupshowing", function() { - ok(false, "prompt showing"); - }); - registerPopupEventHandler("popupshown", function() { - ok(false, "prompt shown"); - }); - registerPopupEventHandler("popuphidden", function() { - ok(false, "prompt hidden"); - }); - await promiseMessage("InvalidStateError", win.gBrowser); + await waitForMessage("InvalidStateError", win.gBrowser); is(getPermission(testPageURL, "indexedDB"), Components.interfaces.nsIPermissionManager.DENY_ACTION, @@ -81,13 +94,6 @@ add_task(async function test2() { }); add_task(async function test3() { - info("creating tab"); - gBrowser.selectedTab = BrowserTestUtils.addTab(gBrowser); - - info("loading test page: " + testPageURL); - gBrowser.selectedBrowser.loadURI(testPageURL); - await BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser); - registerPopupEventHandler("popupshowing", function() { ok(false, "Shouldn't show a popup this time"); }); @@ -98,7 +104,12 @@ add_task(async function test3() { ok(false, "Shouldn't show a popup this time"); }); - await promiseMessage("InvalidStateError", gBrowser); + info("creating tab"); + gBrowser.selectedTab = BrowserTestUtils.addTab(gBrowser); + + info("loading test page: " + testPageURL); + gBrowser.selectedBrowser.loadURI(testPageURL); + await waitForMessage("InvalidStateError", gBrowser); is(getPermission(testPageURL, "indexedDB"), Components.interfaces.nsIPermissionManager.DENY_ACTION, diff --git a/dom/indexedDB/test/head.js b/dom/indexedDB/test/head.js index 8efe1bfa7a3e..7f63de948493 100644 --- a/dom/indexedDB/test/head.js +++ b/dom/indexedDB/test/head.js @@ -5,32 +5,45 @@ var gActiveListeners = {}; -function registerPopupEventHandler(eventName, callback) { +// These event (un)registration handlers only work for one window, DONOT use +// them with multiple windows. +function registerPopupEventHandler(eventName, callback, win) { + if (!win) { + win = window; + } gActiveListeners[eventName] = function(event) { - if (event.target != PopupNotifications.panel) + if (event.target != win.PopupNotifications.panel) return; - PopupNotifications.panel.removeEventListener(eventName, - gActiveListeners[eventName]); + win.PopupNotifications.panel.removeEventListener( + eventName, + gActiveListeners[eventName]); delete gActiveListeners[eventName]; - callback.call(PopupNotifications.panel); + callback.call(win.PopupNotifications.panel); } - PopupNotifications.panel.addEventListener(eventName, - gActiveListeners[eventName]); + win.PopupNotifications.panel.addEventListener(eventName, + gActiveListeners[eventName]); } -function unregisterPopupEventHandler(eventName) +function unregisterPopupEventHandler(eventName, win) { - PopupNotifications.panel.removeEventListener(eventName, - gActiveListeners[eventName]); + if (!win) { + win = window; + } + win.PopupNotifications.panel.removeEventListener(eventName, + gActiveListeners[eventName]); delete gActiveListeners[eventName]; } -function unregisterAllPopupEventHandlers() +function unregisterAllPopupEventHandlers(win) { + if (!win) { + win = window; + } for (let eventName in gActiveListeners) { - PopupNotifications.panel.removeEventListener(eventName, - gActiveListeners[eventName]); + win.PopupNotifications.panel.removeEventListener( + eventName, + gActiveListeners[eventName]); } gActiveListeners = {}; } diff --git a/dom/ipc/ContentChild.cpp b/dom/ipc/ContentChild.cpp index 118bb37ca49f..f6a26014147e 100644 --- a/dom/ipc/ContentChild.cpp +++ b/dom/ipc/ContentChild.cpp @@ -3462,7 +3462,7 @@ ContentChild::RecvProvideAnonymousTemporaryFile(const uint64_t& aID, const FileDescOrError& aFDOrError) { nsAutoPtr callback; - mPendingAnonymousTemporaryFiles.RemoveAndForget(aID, callback); + mPendingAnonymousTemporaryFiles.Remove(aID, &callback); MOZ_ASSERT(callback); PRFileDesc* prfile = nullptr; diff --git a/dom/ipc/ContentParent.cpp b/dom/ipc/ContentParent.cpp index 6b8d0203e551..b622ad632281 100644 --- a/dom/ipc/ContentParent.cpp +++ b/dom/ipc/ContentParent.cpp @@ -5102,8 +5102,7 @@ void ContentParent::SendGetFilesResponseAndForget(const nsID& aUUID, const GetFilesResponseResult& aResult) { - if (auto entry = mGetFilesPendingRequests.Lookup(aUUID)) { - entry.Remove(); + if (mGetFilesPendingRequests.Remove(aUUID)) { Unused << SendGetFilesResponse(aUUID, aResult); } } diff --git a/dom/media/gmp/GMPService.cpp b/dom/media/gmp/GMPService.cpp index cfc433952979..e608d68e49bc 100644 --- a/dom/media/gmp/GMPService.cpp +++ b/dom/media/gmp/GMPService.cpp @@ -178,7 +178,7 @@ GeckoMediaPluginService::RunPluginCrashCallbacks(uint32_t aPluginId, nsAutoPtr>> helpers; { MutexAutoLock lock(mMutex); - mPluginCrashHelpers.RemoveAndForget(aPluginId, helpers); + mPluginCrashHelpers.Remove(aPluginId, &helpers); } if (!helpers) { LOGD(("%s::%s(%i) No crash helpers, not handling crash.", __CLASS__, __FUNCTION__, aPluginId)); diff --git a/dom/media/platforms/agnostic/eme/EMEDecoderModule.cpp b/dom/media/platforms/agnostic/eme/EMEDecoderModule.cpp index 1f0412513de0..6b64a787a7c4 100644 --- a/dom/media/platforms/agnostic/eme/EMEDecoderModule.cpp +++ b/dom/media/platforms/agnostic/eme/EMEDecoderModule.cpp @@ -113,7 +113,7 @@ public: MOZ_ASSERT(aDecrypted.mSample); nsAutoPtr holder; - mDecrypts.RemoveAndForget(aDecrypted.mSample, holder); + mDecrypts.Remove(aDecrypted.mSample, &holder); if (holder) { holder->Complete(); } else { diff --git a/dom/performance/Performance.cpp b/dom/performance/Performance.cpp index 247bb253018c..0a67b812fdcb 100644 --- a/dom/performance/Performance.cpp +++ b/dom/performance/Performance.cpp @@ -8,9 +8,7 @@ #include "GeckoProfiler.h" #include "nsRFPService.h" -#ifdef MOZ_GECKO_PROFILER #include "ProfilerMarkerPayload.h" -#endif #include "PerformanceEntry.h" #include "PerformanceMainThread.h" #include "PerformanceMark.h" @@ -297,13 +295,11 @@ Performance::Mark(const nsAString& aName, ErrorResult& aRv) new PerformanceMark(GetAsISupports(), aName, Now()); InsertUserEntry(performanceMark); -#ifdef MOZ_GECKO_PROFILER if (profiler_is_active()) { profiler_add_marker( "UserTiming", MakeUnique(aName, TimeStamp::Now())); } -#endif } void @@ -391,7 +387,6 @@ Performance::Measure(const nsAString& aName, new PerformanceMeasure(GetAsISupports(), aName, startTime, endTime); InsertUserEntry(performanceMeasure); -#ifdef MOZ_GECKO_PROFILER if (profiler_is_active()) { TimeStamp startTimeStamp = CreationTimeStamp() + TimeDuration::FromMilliseconds(startTime); @@ -401,7 +396,6 @@ Performance::Measure(const nsAString& aName, "UserTiming", MakeUnique(aName, startTimeStamp, endTimeStamp)); } -#endif } void diff --git a/dom/plugins/ipc/PluginInstanceParent.cpp b/dom/plugins/ipc/PluginInstanceParent.cpp index c5d33dc2da48..461c6ef5e0f4 100644 --- a/dom/plugins/ipc/PluginInstanceParent.cpp +++ b/dom/plugins/ipc/PluginInstanceParent.cpp @@ -2201,7 +2201,7 @@ PluginInstanceParent::UnsubclassPluginWindow() // Remove 'this' from the plugin list safely nsAutoPtr tmp; MOZ_ASSERT(sPluginInstanceList); - sPluginInstanceList->RemoveAndForget((void*)mPluginHWND, tmp); + sPluginInstanceList->Remove((void*)mPluginHWND, &tmp); tmp.forget(); if (!sPluginInstanceList->Count()) { delete sPluginInstanceList; diff --git a/dom/svg/SVGAnimationElement.cpp b/dom/svg/SVGAnimationElement.cpp index 08dcb7d26588..346714e10068 100644 --- a/dom/svg/SVGAnimationElement.cpp +++ b/dom/svg/SVGAnimationElement.cpp @@ -445,7 +445,7 @@ SVGAnimationElement::EndElementAt(float offset, ErrorResult& rv) } bool -SVGAnimationElement::IsEventAttributeName(nsIAtom* aName) +SVGAnimationElement::IsEventAttributeNameInternal(nsIAtom* aName) { return nsContentUtils::IsEventAttributeName(aName, EventNameType_SMIL); } diff --git a/dom/svg/SVGAnimationElement.h b/dom/svg/SVGAnimationElement.h index 01dadd7780db..5b162d3508be 100644 --- a/dom/svg/SVGAnimationElement.h +++ b/dom/svg/SVGAnimationElement.h @@ -73,7 +73,7 @@ public: nsSMILTimeContainer* GetTimeContainer(); virtual nsSMILAnimationFunction& AnimationFunction() = 0; - virtual bool IsEventAttributeName(nsIAtom* aName) override; + virtual bool IsEventAttributeNameInternal(nsIAtom* aName) override; // Utility methods for within SVG void ActivateByHyperlink(); diff --git a/dom/svg/SVGPreserveAspectRatio.h b/dom/svg/SVGPreserveAspectRatio.h index 11b97a5470f3..fc8a33aa57c4 100644 --- a/dom/svg/SVGPreserveAspectRatio.h +++ b/dom/svg/SVGPreserveAspectRatio.h @@ -92,7 +92,7 @@ public: return static_cast(mMeetOrSlice); } - uint32_t Hash() const { + PLDHashNumber Hash() const { return HashGeneric(mAlign, mMeetOrSlice); } diff --git a/dom/svg/SVGSVGElement.cpp b/dom/svg/SVGSVGElement.cpp index 3ff4e7f99105..fd3cfd5afd6b 100644 --- a/dom/svg/SVGSVGElement.cpp +++ b/dom/svg/SVGSVGElement.cpp @@ -574,7 +574,7 @@ SVGSVGElement::GetEventTargetParent(EventChainPreVisitor& aVisitor) } bool -SVGSVGElement::IsEventAttributeName(nsIAtom* aName) +SVGSVGElement::IsEventAttributeNameInternal(nsIAtom* aName) { /* The events in EventNameType_SVGSVG are for events that are only applicable to outermost 'svg' elements. We don't check if we're an outer diff --git a/dom/svg/SVGSVGElement.h b/dom/svg/SVGSVGElement.h index 0e508ea91352..fc3d7f3b55c5 100644 --- a/dom/svg/SVGSVGElement.h +++ b/dom/svg/SVGSVGElement.h @@ -105,7 +105,7 @@ public: // nsIContent interface virtual nsresult GetEventTargetParent( EventChainPreVisitor& aVisitor) override; - virtual bool IsEventAttributeName(nsIAtom* aName) override; + virtual bool IsEventAttributeNameInternal(nsIAtom* aName) override; // nsINode methods: virtual nsresult Clone(mozilla::dom::NodeInfo *aNodeInfo, nsINode **aResult, diff --git a/dom/svg/SVGTransformableElement.cpp b/dom/svg/SVGTransformableElement.cpp index 0ce860f3b925..2feb96039759 100644 --- a/dom/svg/SVGTransformableElement.cpp +++ b/dom/svg/SVGTransformableElement.cpp @@ -92,7 +92,7 @@ SVGTransformableElement::GetAttributeChangeHint(const nsIAtom* aAttribute, } bool -SVGTransformableElement::IsEventAttributeName(nsIAtom* aName) +SVGTransformableElement::IsEventAttributeNameInternal(nsIAtom* aName) { return nsContentUtils::IsEventAttributeName(aName, EventNameType_SVGGraphic); } diff --git a/dom/svg/SVGTransformableElement.h b/dom/svg/SVGTransformableElement.h index b14a17299d25..bdcf812a3d7a 100644 --- a/dom/svg/SVGTransformableElement.h +++ b/dom/svg/SVGTransformableElement.h @@ -52,7 +52,7 @@ public: // nsSVGElement overrides - virtual bool IsEventAttributeName(nsIAtom* aName) override; + virtual bool IsEventAttributeNameInternal(nsIAtom* aName) override; virtual gfxMatrix PrependLocalTransformsTo( diff --git a/dom/svg/nsSVGElement.cpp b/dom/svg/nsSVGElement.cpp index 61cc0a06e59b..512bf35d8382 100644 --- a/dom/svg/nsSVGElement.cpp +++ b/dom/svg/nsSVGElement.cpp @@ -14,6 +14,7 @@ #include "mozilla/dom/SVGTests.h" #include "nsContentUtils.h" #include "nsICSSDeclaration.h" +#include "nsIContentInlines.h" #include "nsIDocument.h" #include "nsIDOMMutationEvent.h" #include "mozilla/InternalMutationEvent.h" diff --git a/dom/webbrowserpersist/nsWebBrowserPersist.cpp b/dom/webbrowserpersist/nsWebBrowserPersist.cpp index fdde2e56e24b..421f08ac2fb0 100644 --- a/dom/webbrowserpersist/nsWebBrowserPersist.cpp +++ b/dom/webbrowserpersist/nsWebBrowserPersist.cpp @@ -2416,7 +2416,7 @@ nsWebBrowserPersist::FixRedirectedChannelEntry(nsIChannel *aNewChannel) // If a match was found, remove the data entry with the old channel // key and re-add it with the new channel key. nsAutoPtr outputData; - mOutputMap.RemoveAndForget(matchingKey, outputData); + mOutputMap.Remove(matchingKey, &outputData); NS_ENSURE_TRUE(outputData, NS_ERROR_FAILURE); // Store data again with new channel unless told to ignore redirects. diff --git a/dom/workers/ServiceWorkerManager.cpp b/dom/workers/ServiceWorkerManager.cpp index c2c3069da563..6326b166d0b8 100644 --- a/dom/workers/ServiceWorkerManager.cpp +++ b/dom/workers/ServiceWorkerManager.cpp @@ -1794,8 +1794,7 @@ ServiceWorkerManager::ReportToAllClients(const nsCString& aScope, if (regList->IsEmpty()) { regList = nullptr; - nsAutoPtr doomed; - mRegisteringDocuments.RemoveAndForget(aScope, doomed); + mRegisteringDocuments.Remove(aScope); } } @@ -1950,8 +1949,7 @@ ServiceWorkerManager::FlushReportsToAllClients(const nsACString& aScope, if (regList->IsEmpty()) { regList = nullptr; - nsAutoPtr doomed; - mRegisteringDocuments.RemoveAndForget(aScope, doomed); + mRegisteringDocuments.Remove(aScope); } } @@ -3891,8 +3889,7 @@ ServiceWorkerManager::ShouldReportToWindow(mozIDOMWindowProxy* aWindow, if (list->IsEmpty()) { list = nullptr; - nsAutoPtr doomed; - mRegisteringDocuments.RemoveAndForget(aScope, doomed); + mRegisteringDocuments.Remove(aScope); } } @@ -4171,8 +4168,7 @@ ServiceWorkerManager::RemoveNavigationInterception(const nsACString& aScope, MOZ_ASSERT(!list->Contains(aChannel)); if (list->IsEmpty()) { list = nullptr; - nsAutoPtr doomed; - mNavigationInterceptions.RemoveAndForget(aScope, doomed); + mNavigationInterceptions.Remove(aScope); } } } diff --git a/dom/xbl/nsXBLDocumentInfo.cpp b/dom/xbl/nsXBLDocumentInfo.cpp index 48120b472934..127fd791d7f1 100644 --- a/dom/xbl/nsXBLDocumentInfo.cpp +++ b/dom/xbl/nsXBLDocumentInfo.cpp @@ -175,7 +175,7 @@ nsXBLDocumentInfo::RemovePrototypeBinding(const nsACString& aRef) { if (mBindingTable) { nsAutoPtr bindingToRemove; - mBindingTable->RemoveAndForget(aRef, bindingToRemove); + mBindingTable->Remove(aRef, &bindingToRemove); // We do not want to destroy the binding, so just forget it. bindingToRemove.forget(); diff --git a/dom/xml/nsXMLContentSink.cpp b/dom/xml/nsXMLContentSink.cpp index 96ca07060b87..65d4c0cf1cdc 100644 --- a/dom/xml/nsXMLContentSink.cpp +++ b/dom/xml/nsXMLContentSink.cpp @@ -1465,7 +1465,7 @@ nsXMLContentSink::FlushPendingNotifications(FlushType aType) FlushText(false); } } - if (aType >= FlushType::InterruptibleLayout) { + if (aType >= FlushType::EnsurePresShellInitAndFrames) { // Make sure that layout has started so that the reflow flush // will actually happen. MaybeStartLayout(true); diff --git a/dom/xslt/xpath/txMozillaXPathTreeWalker.cpp b/dom/xslt/xpath/txMozillaXPathTreeWalker.cpp index 0bb17451be77..adf7074dc193 100644 --- a/dom/xslt/xpath/txMozillaXPathTreeWalker.cpp +++ b/dom/xslt/xpath/txMozillaXPathTreeWalker.cpp @@ -27,17 +27,13 @@ using namespace mozilla::dom; -const uint32_t kUnknownIndex = uint32_t(-1); - txXPathTreeWalker::txXPathTreeWalker(const txXPathTreeWalker& aOther) - : mPosition(aOther.mPosition), - mCurrentIndex(aOther.mCurrentIndex) + : mPosition(aOther.mPosition) { } txXPathTreeWalker::txXPathTreeWalker(const txXPathNode& aNode) - : mPosition(aNode), - mCurrentIndex(kUnknownIndex) + : mPosition(aNode) { } @@ -62,9 +58,6 @@ txXPathTreeWalker::moveToRoot() mPosition.mIndex = txXPathNode::eContent; mPosition.mNode = rootNode; } - - mCurrentIndex = kUnknownIndex; - mDescendants.Clear(); } bool @@ -97,8 +90,6 @@ txXPathTreeWalker::moveToElementById(const nsAString& aID) mPosition.mIndex = txXPathNode::eContent; mPosition.mNode = content; - mCurrentIndex = kUnknownIndex; - mDescendants.Clear(); return true; } @@ -174,12 +165,6 @@ txXPathTreeWalker::moveToFirstChild() return false; } - NS_ASSERTION(!mPosition.isDocument() || - (mCurrentIndex == kUnknownIndex && mDescendants.IsEmpty()), - "we shouldn't have any position info at the document"); - NS_ASSERTION(mCurrentIndex != kUnknownIndex || mDescendants.IsEmpty(), - "Index should be known if parents index are"); - nsIContent* child = mPosition.mNode->GetFirstChild(); if (!child) { return false; @@ -187,12 +172,6 @@ txXPathTreeWalker::moveToFirstChild() mPosition.mIndex = txXPathNode::eContent; mPosition.mNode = child; - if (mCurrentIndex != kUnknownIndex && - !mDescendants.AppendValue(mCurrentIndex)) { - mDescendants.Clear(); - } - mCurrentIndex = 0; - return true; } @@ -203,23 +182,13 @@ txXPathTreeWalker::moveToLastChild() return false; } - NS_ASSERTION(!mPosition.isDocument() || - (mCurrentIndex == kUnknownIndex && mDescendants.IsEmpty()), - "we shouldn't have any position info at the document"); - NS_ASSERTION(mCurrentIndex != kUnknownIndex || mDescendants.IsEmpty(), - "Index should be known if parents index are"); - - uint32_t total = mPosition.mNode->GetChildCount(); - if (!total) { + nsIContent* child = mPosition.mNode->GetLastChild(); + if (!child) { return false; } - mPosition.mNode = mPosition.mNode->GetLastChild(); - if (mCurrentIndex != kUnknownIndex && - !mDescendants.AppendValue(mCurrentIndex)) { - mDescendants.Clear(); - } - mCurrentIndex = total - 1; + mPosition.mIndex = txXPathNode::eContent; + mPosition.mNode = child; return true; } @@ -231,7 +200,14 @@ txXPathTreeWalker::moveToNextSibling() return false; } - return moveToSibling(1); + nsINode* sibling = mPosition.mNode->GetNextSibling(); + if (!sibling) { + return false; + } + + mPosition.mNode = sibling; + + return true; } bool @@ -241,7 +217,14 @@ txXPathTreeWalker::moveToPreviousSibling() return false; } - return moveToSibling(-1); + nsINode* sibling = mPosition.mNode->GetPreviousSibling(); + if (!sibling) { + return false; + } + + mPosition.mNode = sibling; + + return true; } bool @@ -262,15 +245,6 @@ txXPathTreeWalker::moveToParent() return false; } - uint32_t count = mDescendants.Length(); - if (count) { - mCurrentIndex = mDescendants.ValueAt(--count); - mDescendants.RemoveValueAt(count); - } - else { - mCurrentIndex = kUnknownIndex; - } - mPosition.mIndex = mPosition.mNode->GetParent() ? txXPathNode::eContent : txXPathNode::eDocument; mPosition.mNode = parent; @@ -278,34 +252,6 @@ txXPathTreeWalker::moveToParent() return true; } -bool -txXPathTreeWalker::moveToSibling(int32_t aDir) -{ - NS_ASSERTION(mPosition.isContent(), - "moveToSibling should only be called for content"); - - nsINode* parent = mPosition.mNode->GetParentNode(); - if (!parent) { - return false; - } - if (mCurrentIndex == kUnknownIndex) { - mCurrentIndex = parent->IndexOf(mPosition.mNode); - } - - // if mCurrentIndex is 0 we rely on GetChildAt returning null for an - // index of uint32_t(-1). - uint32_t newIndex = mCurrentIndex + aDir; - nsIContent* newChild = parent->GetChildAt(newIndex); - if (!newChild) { - return false; - } - - mPosition.mNode = newChild; - mCurrentIndex = newIndex; - - return true; -} - txXPathNode::txXPathNode(const txXPathNode& aNode) : mNode(aNode.mNode), mRefCountRoot(aNode.mRefCountRoot), diff --git a/dom/xslt/xpath/txXPathTreeWalker.h b/dom/xslt/xpath/txXPathTreeWalker.h index 99a07ffe7170..fc6dff3249db 100644 --- a/dom/xslt/xpath/txXPathTreeWalker.h +++ b/dom/xslt/xpath/txXPathTreeWalker.h @@ -14,26 +14,6 @@ class nsIAtom; class nsIDOMDocument; -class txUint32Array : public nsTArray -{ -public: - bool AppendValue(uint32_t aValue) - { - return AppendElement(aValue) != nullptr; - } - bool RemoveValueAt(uint32_t aIndex) - { - if (aIndex < Length()) { - RemoveElementAt(aIndex); - } - return true; - } - uint32_t ValueAt(uint32_t aIndex) const - { - return (aIndex < Length()) ? ElementAt(aIndex) : 0; - } -}; - class txXPathTreeWalker { public: @@ -67,10 +47,6 @@ private: txXPathNode mPosition; bool moveToValidAttribute(uint32_t aStartIndex); - bool moveToSibling(int32_t aDir); - - uint32_t mCurrentIndex; - txUint32Array mDescendants; }; class txXPathNodeUtils @@ -195,9 +171,6 @@ txXPathTreeWalker::moveTo(const txXPathTreeWalker& aWalker) NS_IF_ADDREF(newRoot); NS_IF_RELEASE(root); } - - mCurrentIndex = aWalker.mCurrentIndex; - mDescendants.Clear(); } inline bool diff --git a/dom/xul/nsXULElement.cpp b/dom/xul/nsXULElement.cpp index ee57baf89f04..3a68dbf93949 100644 --- a/dom/xul/nsXULElement.cpp +++ b/dom/xul/nsXULElement.cpp @@ -2031,7 +2031,7 @@ nsXULElement::RecompileScriptEventListeners() } bool -nsXULElement::IsEventAttributeName(nsIAtom *aName) +nsXULElement::IsEventAttributeNameInternal(nsIAtom *aName) { return nsContentUtils::IsEventAttributeName(aName, EventNameType_XUL); } diff --git a/dom/xul/nsXULElement.h b/dom/xul/nsXULElement.h index 921bb16c2ed5..4f0e425408c6 100644 --- a/dom/xul/nsXULElement.h +++ b/dom/xul/nsXULElement.h @@ -434,7 +434,7 @@ public: virtual nsIDOMNode* AsDOMNode() override { return this; } - virtual bool IsEventAttributeName(nsIAtom* aName) override; + virtual bool IsEventAttributeNameInternal(nsIAtom* aName) override; typedef mozilla::dom::DOMString DOMString; void GetXULAttr(nsIAtom* aName, DOMString& aResult) const diff --git a/editor/libeditor/tests/test_bug1306532.html b/editor/libeditor/tests/test_bug1306532.html index 1d7b3e7afdb7..367bd5f04051 100644 --- a/editor/libeditor/tests/test_bug1306532.html +++ b/editor/libeditor/tests/test_bug1306532.html @@ -58,7 +58,7 @@ SimpleTest.waitForExplicitFinish(); - + diff --git a/editor/libeditor/tests/test_bug551704.html b/editor/libeditor/tests/test_bug551704.html index 52fc34568895..d42d541bfd30 100644 --- a/editor/libeditor/tests/test_bug551704.html +++ b/editor/libeditor/tests/test_bug551704.html @@ -94,7 +94,7 @@ SimpleTest.waitForFocus(function() { continueTest(); }); - iframe.src = "data:text/html,foo"; + iframe.srcdoc = "foo"; document.getElementById("content").appendChild(iframe); }); diff --git a/editor/libeditor/tests/test_bug674770-2.html b/editor/libeditor/tests/test_bug674770-2.html index 1bab9e8901a4..4c557a7b842e 100644 --- a/editor/libeditor/tests/test_bug674770-2.html +++ b/editor/libeditor/tests/test_bug674770-2.html @@ -14,7 +14,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=674770

+ srcdoc="

editor1:

editor2:

">
 
 
 
-
+
 
 
diff --git a/parser/htmlparser/tests/mochitest/test_bug667533.html b/parser/htmlparser/tests/mochitest/test_bug667533.html
index c5b24394eb4a..1475413b5b68 100644
--- a/parser/htmlparser/tests/mochitest/test_bug667533.html
+++ b/parser/htmlparser/tests/mochitest/test_bug667533.html
@@ -18,8 +18,8 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=667533
 SimpleTest.waitForExplicitFinish();
 
 function loaded(iframe) {
-  is(iframe.contentWindow.location.href, iframe.src, "should load correct URL");
-  is(iframe.contentDocument.body.textContent, '{"

Hello

": null}', "application/json should be treated as text"); + is(SpecialPowers.wrap(iframe).contentWindow.location.href, iframe.src, "should load correct URL"); + is(SpecialPowers.wrap(iframe).contentDocument.body.textContent, '{"

Hello

": null}', "application/json should be treated as text"); SimpleTest.finish(); } diff --git a/python/mozbuild/mozbuild/compilation/database.py b/python/mozbuild/mozbuild/compilation/database.py index 82e02903622e..5bcbc5d78c94 100644 --- a/python/mozbuild/mozbuild/compilation/database.py +++ b/python/mozbuild/mozbuild/compilation/database.py @@ -168,7 +168,7 @@ class CompileDBBackend(CommonBackend): db.append({ 'directory': directory, 'command': ' '.join(shell_quote(a) for a in c), - 'file': filename, + 'file': mozpath.join(directory, filename), }) import json diff --git a/security/manager/ssl/CertBlocklist.cpp b/security/manager/ssl/CertBlocklist.cpp index 83419295b66e..266ca42e2614 100644 --- a/security/manager/ssl/CertBlocklist.cpp +++ b/security/manager/ssl/CertBlocklist.cpp @@ -495,7 +495,7 @@ CertBlocklist::SaveEntries() for (auto iter = issuers.Iter(); !iter.Done(); iter.Next()) { nsCStringHashKey* hashKey = iter.Get(); nsAutoPtr issuerSet; - issuerTable.RemoveAndForget(hashKey->GetKey(), issuerSet); + issuerTable.Remove(hashKey->GetKey(), &issuerSet); nsresult rv = WriteLine(outputStream, hashKey->GetKey()); if (NS_FAILED(rv)) { diff --git a/security/sandbox/linux/SandboxBrokerClient.cpp b/security/sandbox/linux/SandboxBrokerClient.cpp index 68744ad02731..d9fcbfd1cba3 100644 --- a/security/sandbox/linux/SandboxBrokerClient.cpp +++ b/security/sandbox/linux/SandboxBrokerClient.cpp @@ -76,7 +76,7 @@ SandboxBrokerClient::DoCall(const Request* aReq, const char* aPath, ios[2].iov_base = const_cast(aPath2); ios[2].iov_len = strlen(aPath2) + 1; } else { - ios[2].iov_base = 0; + ios[2].iov_base = nullptr; ios[2].iov_len = 0; } if (ios[1].iov_len > kMaxPathLen) { diff --git a/security/sandbox/linux/SandboxFilter.cpp b/security/sandbox/linux/SandboxFilter.cpp index 6bfbab997343..e7d978e59c01 100644 --- a/security/sandbox/linux/SandboxFilter.cpp +++ b/security/sandbox/linux/SandboxFilter.cpp @@ -108,7 +108,7 @@ private: } public: - virtual ResultExpr InvalidSyscall() const override { + ResultExpr InvalidSyscall() const override { return Trap(BlockedSyscallTrap, nullptr); } @@ -155,7 +155,7 @@ public: .Default(InvalidSyscall()); } - virtual Maybe EvaluateSocketCall(int aCall) const override { + Maybe EvaluateSocketCall(int aCall) const override { switch (aCall) { case SYS_RECVMSG: case SYS_SENDMSG: @@ -165,7 +165,7 @@ public: } } - virtual ResultExpr EvaluateSyscall(int sysno) const override { + ResultExpr EvaluateSyscall(int sysno) const override { switch (sysno) { // Timekeeping case __NR_clock_gettime: { @@ -520,13 +520,13 @@ public: const std::vector& aSyscallWhitelist) : mBroker(aBroker), mSyscallWhitelist(aSyscallWhitelist) {} - virtual ~ContentSandboxPolicy() { } - virtual ResultExpr PrctlPolicy() const override { + ~ContentSandboxPolicy() override = default; + ResultExpr PrctlPolicy() const override { // Ideally this should be restricted to a whitelist, but content // uses enough things that it's not trivial to determine it. return Allow(); } - virtual Maybe EvaluateSocketCall(int aCall) const override { + Maybe EvaluateSocketCall(int aCall) const override { switch(aCall) { case SYS_RECVFROM: case SYS_SENDTO: @@ -570,7 +570,7 @@ public: } #ifdef DESKTOP - virtual Maybe EvaluateIpcCall(int aCall) const override { + Maybe EvaluateIpcCall(int aCall) const override { switch(aCall) { // These are a problem: SysV shared memory follows the Unix // "same uid policy" and can't be restricted/brokered like file @@ -591,7 +591,7 @@ public: } #endif - virtual ResultExpr EvaluateSyscall(int sysno) const override { + ResultExpr EvaluateSyscall(int sysno) const override { // Straight allow for anything that got overriden via prefs if (std::find(mSyscallWhitelist.begin(), mSyscallWhitelist.end(), sysno) != mSyscallWhitelist.end()) { @@ -957,9 +957,9 @@ public: MOZ_ASSERT(aPlugin->mPath[0] == '/', "plugin path should be absolute"); } - virtual ~GMPSandboxPolicy() { } + ~GMPSandboxPolicy() override = default; - virtual ResultExpr EvaluateSyscall(int sysno) const override { + ResultExpr EvaluateSyscall(int sysno) const override { switch (sysno) { // Simulate opening the plugin file. #ifdef __NR_open diff --git a/security/sandbox/linux/SandboxHooks.cpp b/security/sandbox/linux/SandboxHooks.cpp index eaaf56982dbc..7331104997f8 100644 --- a/security/sandbox/linux/SandboxHooks.cpp +++ b/security/sandbox/linux/SandboxHooks.cpp @@ -34,7 +34,7 @@ static int HandleSigset(int (*aRealFunc)(int, const sigset_t*, sigset_t*), } // Avoid unnecessary work - if (aSet == NULL || aHow == SIG_UNBLOCK) { + if (aSet == nullptr || aHow == SIG_UNBLOCK) { return aRealFunc(aHow, aSet, aOldSet); } diff --git a/security/sandbox/linux/broker/SandboxBroker.cpp b/security/sandbox/linux/broker/SandboxBroker.cpp index 668ac58bb612..2af874a6b28f 100644 --- a/security/sandbox/linux/broker/SandboxBroker.cpp +++ b/security/sandbox/linux/broker/SandboxBroker.cpp @@ -92,8 +92,8 @@ SandboxBroker::~SandboxBroker() { // destructor can now return. } -SandboxBroker::Policy::Policy() { } -SandboxBroker::Policy::~Policy() { } +SandboxBroker::Policy::Policy() = default; +SandboxBroker::Policy::~Policy() = default; SandboxBroker::Policy::Policy(const Policy& aOther) { for (auto iter = aOther.mMap.ConstIter(); !iter.Done(); iter.Next()) { @@ -425,9 +425,9 @@ DoLink(const char* aPath, const char* aPath2, size_t SandboxBroker::ConvertToRealPath(char* aPath, size_t aBufSize, size_t aPathLen) { - if (strstr(aPath, "..") != NULL) { - char* result = realpath(aPath, NULL); - if (result != NULL) { + if (strstr(aPath, "..") != nullptr) { + char* result = realpath(aPath, nullptr); + if (result != nullptr) { strncpy(aPath, result, aBufSize); aPath[aBufSize - 1] = '\0'; free(result); diff --git a/security/sandbox/linux/gtest/TestBroker.cpp b/security/sandbox/linux/gtest/TestBroker.cpp index 33543d113a3e..c52ac3ab1cb7 100644 --- a/security/sandbox/linux/gtest/TestBroker.cpp +++ b/security/sandbox/linux/gtest/TestBroker.cpp @@ -86,7 +86,7 @@ protected: return mClient->Readlink(aPath, aBuff, aSize); } - virtual void SetUp() { + void SetUp() override { ipc::FileDescriptor fd; mServer = SandboxBroker::Create(GetPolicy(), getpid(), fd); diff --git a/security/sandbox/linux/reporter/SandboxReporterWrappers.cpp b/security/sandbox/linux/reporter/SandboxReporterWrappers.cpp index 1bbe9abbefe4..ebe6cc1ec369 100644 --- a/security/sandbox/linux/reporter/SandboxReporterWrappers.cpp +++ b/security/sandbox/linux/reporter/SandboxReporterWrappers.cpp @@ -29,7 +29,7 @@ public: { } private: - ~SandboxReportWrapper() { } + ~SandboxReportWrapper() = default; SandboxReport mReport; }; @@ -132,7 +132,7 @@ public: { } private: - ~SandboxReportArray() { } + ~SandboxReportArray() = default; uint64_t mOffset; nsTArray mArray; }; @@ -173,10 +173,10 @@ public: NS_DECL_ISUPPORTS NS_DECL_MOZISANDBOXREPORTER - SandboxReporterWrapper() { } + SandboxReporterWrapper() = default; private: - ~SandboxReporterWrapper() { } + ~SandboxReporterWrapper() = default; }; NS_IMPL_ISUPPORTS(SandboxReporterWrapper, mozISandboxReporter) diff --git a/testing/config/tooltool-manifests/linux64/ccov.manifest b/testing/config/tooltool-manifests/linux64/ccov.manifest index f54371e635a6..64e2e67ffb38 100644 --- a/testing/config/tooltool-manifests/linux64/ccov.manifest +++ b/testing/config/tooltool-manifests/linux64/ccov.manifest @@ -1,7 +1,7 @@ [ { - "size": 752315, - "digest": "8e86d7ebbb11758a385bb2af65b3f6444a5c6a1468c35a77f60d253c82affa007c61dc9b73025f8a146678a3ce1b8d050064bccf5efa33357588db10dac44150", + "size": 770785, + "digest": "ee03f708a8c6e58d9c2dcc6140a720852c47737051df1781f1745f14f6fb11e472da831d138b06a86ab5507dbf3f8d5dcfc7cfe5f83dd09ea34d9bdd515e52c5", "algorithm": "sha512", "filename": "grcov-linux-standalone-x86_64.tar.bz2", "unpack": false diff --git a/testing/mochitest/BrowserTestUtils/BrowserTestUtils.jsm b/testing/mochitest/BrowserTestUtils/BrowserTestUtils.jsm index 8344e8a06504..4fb9cc96d84b 100644 --- a/testing/mochitest/BrowserTestUtils/BrowserTestUtils.jsm +++ b/testing/mochitest/BrowserTestUtils/BrowserTestUtils.jsm @@ -910,7 +910,7 @@ this.BrowserTestUtils = { messageManager.addMessageListener(message, function onMessage(msg) { if (!checkFn || checkFn(msg)) { messageManager.removeMessageListener(message, onMessage); - resolve(); + resolve(msg.data); } }); }); diff --git a/testing/mozharness/mozharness/mozilla/testing/codecoverage.py b/testing/mozharness/mozharness/mozilla/testing/codecoverage.py index 9c3139183cc3..7dc50c81edfb 100644 --- a/testing/mozharness/mozharness/mozilla/testing/codecoverage.py +++ b/testing/mozharness/mozharness/mozilla/testing/codecoverage.py @@ -130,8 +130,8 @@ class CodeCoverageMixin(object): self.download_file(self.url_to_gcno, file_name=None, parent_dir=self.grcov_dir) # Run grcov on the zipped .gcno and .gcda files. - grcov_command = [os.path.join(self.grcov_dir, 'grcov'), '-t', 'lcov' , '-p', \ - '/home/worker/workspace/build/src/', '-z', \ + grcov_command = [os.path.join(self.grcov_dir, 'grcov'), '-t', 'lcov', '-p', \ + '/home/worker/workspace/build/src/', \ os.path.join(self.grcov_dir, 'target.code-coverage-gcno.zip'), file_path_gcda] # 'grcov_output' will be a tuple, the first variable is the path to the lcov output, diff --git a/testing/web-platform/tests/old-tests/submission/Opera/script_scheduling/scripts/include-11.js b/testing/web-platform/tests/old-tests/submission/Opera/script_scheduling/scripts/include-11.js index a822dd8baf26..016913c4b80e 100644 --- a/testing/web-platform/tests/old-tests/submission/Opera/script_scheduling/scripts/include-11.js +++ b/testing/web-platform/tests/old-tests/submission/Opera/script_scheduling/scripts/include-11.js @@ -1,4 +1,4 @@ log("external script before adding iframe"); var iframe = document.createElement("iframe"); -iframe.src = "data:text/html," -document.body.appendChild(iframe); \ No newline at end of file +iframe.srcdoc = "" +document.body.appendChild(iframe); diff --git a/toolkit/components/telemetry/ThreadHangStats.cpp b/toolkit/components/telemetry/ThreadHangStats.cpp index 9534c39cf7ea..e567e5ce9eec 100644 --- a/toolkit/components/telemetry/ThreadHangStats.cpp +++ b/toolkit/components/telemetry/ThreadHangStats.cpp @@ -201,6 +201,12 @@ CreateJSThreadHangStats(JSContext* cx, const Telemetry::ThreadHangStats& thread) return nullptr; } + JS::RootedString runnableName(cx, JS_NewStringCopyZ(cx, thread.mHangs[i].GetRunnableName())); + if (!runnableName || + !JS_DefineProperty(cx, ret, "runnableName", runnableName, JSPROP_ENUMERATE)) { + return nullptr; + } + // Check if we have a cached native stack index, and if we do record it. uint32_t index = thread.mHangs[i].GetNativeStackIndex(); if (index != Telemetry::HangHistogram::NO_NATIVE_STACK_INDEX) { diff --git a/toolkit/components/telemetry/ThreadHangStats.h b/toolkit/components/telemetry/ThreadHangStats.h index 512e16d97500..6032a27844cf 100644 --- a/toolkit/components/telemetry/ThreadHangStats.h +++ b/toolkit/components/telemetry/ThreadHangStats.h @@ -182,12 +182,15 @@ private: const uint32_t mHash; // Annotations attributed to this stack HangMonitor::HangAnnotationsVector mAnnotations; + // The name of the runnable on the current thread. + nsCString mRunnableName; public: - explicit HangHistogram(HangStack&& aStack) + explicit HangHistogram(HangStack&& aStack, const nsACString& aRunnableName) : mStack(mozilla::Move(aStack)) , mNativeStackIndex(NO_NATIVE_STACK_INDEX) , mHash(GetHash(mStack)) + , mRunnableName(aRunnableName) { } @@ -197,6 +200,7 @@ public: , mNativeStackIndex(mozilla::Move(aOther.mNativeStackIndex)) , mHash(mozilla::Move(aOther.mHash)) , mAnnotations(mozilla::Move(aOther.mAnnotations)) + , mRunnableName(aOther.mRunnableName) { } bool operator==(const HangHistogram& aOther) const; @@ -214,6 +218,9 @@ public: MOZ_ASSERT(aIndex != NO_NATIVE_STACK_INDEX); mNativeStackIndex = aIndex; } + const char* GetRunnableName() const { + return mRunnableName.get(); + } const HangMonitor::HangAnnotationsVector& GetAnnotations() const { return mAnnotations; } diff --git a/toolkit/themes/shared/about.css b/toolkit/themes/shared/about.css index cfe6b5464858..b94e223e0b46 100644 --- a/toolkit/themes/shared/about.css +++ b/toolkit/themes/shared/about.css @@ -4,21 +4,17 @@ html { background: -moz-Dialog; + line-height: 1.6em; padding: 0 1em; font: message-box; } body { - color: -moz-FieldText; position: relative; min-width: 330px; max-width: 50em; margin: 4em auto; - border: 1px solid ThreeDShadow; - border-radius: 10px; - padding: 3em; padding-inline-start: 30px; - background: -moz-Field; } .aboutPageWideContainer { @@ -31,6 +27,11 @@ body { margin-bottom: 2em; } +h1 { + font-weight: lighter; + font-size: 2.4em; +} + img { border: 0; } @@ -46,7 +47,6 @@ ul { margin: 0; margin-inline-start: 1.5em; padding: 0; - list-style: square; } ul > li { diff --git a/tools/profiler/core/ProfilerMarkerPayload.cpp b/tools/profiler/core/ProfilerMarkerPayload.cpp index 57cb272b64fa..d7f7ef243368 100644 --- a/tools/profiler/core/ProfilerMarkerPayload.cpp +++ b/tools/profiler/core/ProfilerMarkerPayload.cpp @@ -12,22 +12,6 @@ using namespace mozilla; -ProfilerMarkerPayload::ProfilerMarkerPayload(UniqueProfilerBacktrace aStack) - : mStack(Move(aStack)) -{} - -ProfilerMarkerPayload::ProfilerMarkerPayload(const TimeStamp& aStartTime, - const TimeStamp& aEndTime, - UniqueProfilerBacktrace aStack) - : mStartTime(aStartTime) - , mEndTime(aEndTime) - , mStack(Move(aStack)) -{} - -ProfilerMarkerPayload::~ProfilerMarkerPayload() -{ -} - void ProfilerMarkerPayload::StreamCommonProps(const char* aMarkerType, SpliceableJSONWriter& aWriter, @@ -53,24 +37,6 @@ ProfilerMarkerPayload::StreamCommonProps(const char* aMarkerType, } } -TracingMarkerPayload::TracingMarkerPayload(const char* aCategory, - TracingKind aKind) - : mCategory(aCategory) - , mKind(aKind) -{ -} - -TracingMarkerPayload::TracingMarkerPayload(const char* aCategory, - TracingKind aKind, - UniqueProfilerBacktrace aCause) - : mCategory(aCategory) - , mKind(aKind) -{ - if (aCause) { - SetStack(Move(aCause)); - } -} - void TracingMarkerPayload::StreamPayload(SpliceableJSONWriter& aWriter, const TimeStamp& aProcessStartTime, @@ -89,19 +55,6 @@ TracingMarkerPayload::StreamPayload(SpliceableJSONWriter& aWriter, } } -GPUMarkerPayload::GPUMarkerPayload( - const TimeStamp& aCpuTimeStart, - const TimeStamp& aCpuTimeEnd, - uint64_t aGpuTimeStart, - uint64_t aGpuTimeEnd) - - : ProfilerMarkerPayload(aCpuTimeStart, aCpuTimeEnd) - , mCpuTimeStart(aCpuTimeStart) - , mCpuTimeEnd(aCpuTimeEnd) - , mGpuTimeStart(aGpuTimeStart) - , mGpuTimeEnd(aGpuTimeEnd) -{ } - void GPUMarkerPayload::StreamPayload(SpliceableJSONWriter& aWriter, const TimeStamp& aProcessStartTime, @@ -118,22 +71,6 @@ GPUMarkerPayload::StreamPayload(SpliceableJSONWriter& aWriter, aWriter.IntProperty("gpuend", (int)mGpuTimeEnd); } -IOMarkerPayload::IOMarkerPayload(const char* aSource, - const char* aFilename, - const TimeStamp& aStartTime, - const TimeStamp& aEndTime, - UniqueProfilerBacktrace aStack) - : ProfilerMarkerPayload(aStartTime, aEndTime, Move(aStack)), - mSource(aSource) -{ - mFilename = aFilename ? strdup(aFilename) : nullptr; - MOZ_ASSERT(aSource); -} - -IOMarkerPayload::~IOMarkerPayload(){ - free(mFilename); -} - void IOMarkerPayload::StreamPayload(SpliceableJSONWriter& aWriter, const TimeStamp& aProcessStartTime, @@ -141,32 +78,11 @@ IOMarkerPayload::StreamPayload(SpliceableJSONWriter& aWriter, { StreamCommonProps("io", aWriter, aProcessStartTime, aUniqueStacks); aWriter.StringProperty("source", mSource); - if (mFilename != nullptr) { - aWriter.StringProperty("filename", mFilename); + if (mFilename) { + aWriter.StringProperty("filename", mFilename.get()); } } -UserTimingMarkerPayload::UserTimingMarkerPayload(const nsAString& aName, - const TimeStamp& aStartTime) - : ProfilerMarkerPayload(aStartTime, aStartTime, nullptr) - , mEntryType("mark") - , mName(aName) -{ -} - -UserTimingMarkerPayload::UserTimingMarkerPayload(const nsAString& aName, - const TimeStamp& aStartTime, - const TimeStamp& aEndTime) - : ProfilerMarkerPayload(aStartTime, aEndTime, nullptr) - , mEntryType("measure") - , mName(aName) -{ -} - -UserTimingMarkerPayload::~UserTimingMarkerPayload() -{ -} - void UserTimingMarkerPayload::StreamPayload(SpliceableJSONWriter& aWriter, const TimeStamp& aProcessStartTime, @@ -177,19 +93,6 @@ UserTimingMarkerPayload::StreamPayload(SpliceableJSONWriter& aWriter, aWriter.StringProperty("entryType", mEntryType); } -DOMEventMarkerPayload::DOMEventMarkerPayload(const nsAString& aType, uint16_t aPhase, - const TimeStamp& aStartTime, - const TimeStamp& aEndTime) - : ProfilerMarkerPayload(aStartTime, aEndTime, nullptr) - , mType(aType) - , mPhase(aPhase) -{ -} - -DOMEventMarkerPayload::~DOMEventMarkerPayload() -{ -} - void DOMEventMarkerPayload::StreamPayload(SpliceableJSONWriter& aWriter, const TimeStamp& aProcessStartTime, @@ -200,14 +103,6 @@ DOMEventMarkerPayload::StreamPayload(SpliceableJSONWriter& aWriter, aWriter.IntProperty("phase", mPhase); } -LayerTranslationMarkerPayload::LayerTranslationMarkerPayload(layers::Layer* aLayer, - gfx::Point aPoint) - : ProfilerMarkerPayload(TimeStamp::Now(), TimeStamp::Now(), nullptr) - , mLayer(aLayer) - , mPoint(aPoint) -{ -} - void LayerTranslationMarkerPayload::StreamPayload(SpliceableJSONWriter& aWriter, const TimeStamp& aProcessStartTime, @@ -223,12 +118,6 @@ LayerTranslationMarkerPayload::StreamPayload(SpliceableJSONWriter& aWriter, aWriter.StringProperty("category", "LayerTranslation"); } -VsyncMarkerPayload::VsyncMarkerPayload(TimeStamp aVsyncTimestamp) - : ProfilerMarkerPayload(aVsyncTimestamp, aVsyncTimestamp, nullptr) - , mVsyncTimestamp(aVsyncTimestamp) -{ -} - void VsyncMarkerPayload::StreamPayload(SpliceableJSONWriter& aWriter, const TimeStamp& aProcessStartTime, diff --git a/tools/profiler/core/ThreadInfo.h b/tools/profiler/core/ThreadInfo.h index 871bc21010f3..c9592a821163 100644 --- a/tools/profiler/core/ThreadInfo.h +++ b/tools/profiler/core/ThreadInfo.h @@ -156,6 +156,13 @@ private: }; // This class contains the info for a single thread. +// +// Note: A thread's ThreadInfo can be held onto after the thread itself exits, +// because we may need to output profiling information about that thread. But +// some of the fields in this class are only relevant while the thread is +// alive. It's possible that this class could be refactored so there is a +// clearer split between those fields and the fields that are still relevant +// after the thread exists. class ThreadInfo final { public: diff --git a/tools/profiler/core/platform.cpp b/tools/profiler/core/platform.cpp index 1dc765ed89e4..36ed0314278a 100644 --- a/tools/profiler/core/platform.cpp +++ b/tools/profiler/core/platform.cpp @@ -2121,7 +2121,7 @@ profiler_init(void* aStackTop) ProfilerFeature::Threads | 0; - const char* filters[] = { "GeckoMain", "Compositor" }; + const char* filters[] = { "GeckoMain", "Compositor", "DOM Worker" }; if (getenv("MOZ_PROFILER_HELP")) { PrintUsageThenExit(0); // terminates execution @@ -3043,7 +3043,7 @@ profiler_current_thread_id() void profiler_suspend_and_sample_thread( int aThreadId, - const std::function& aCallback, + const std::function& aCallback, bool aSampleNative /* = true */) { // Allocate the space for the native stack @@ -3068,7 +3068,7 @@ profiler_suspend_and_sample_thread( DoNativeBacktrace(lock, *info, aRegs, nativeStack); } #endif - aCallback(nativeStack.mPCs, nativeStack.mCount); + aCallback(nativeStack.mPCs, nativeStack.mCount, info->IsMainThread()); }); // NOTE: Make sure to disable the sampler before it is destroyed, in case diff --git a/tools/profiler/moz.build b/tools/profiler/moz.build index 85e069295814..54c971791c96 100644 --- a/tools/profiler/moz.build +++ b/tools/profiler/moz.build @@ -12,7 +12,6 @@ if CONFIG['MOZ_GECKO_PROFILER']: EXPORTS += [ 'public/ChildProfilerController.h', 'public/ProfilerChild.h', - 'public/ProfilerMarkerPayload.h', 'public/ProfilerParent.h', 'public/shared-libraries.h', ] @@ -120,6 +119,7 @@ include('/ipc/chromium/chromium-config.mozbuild') EXPORTS += [ 'public/GeckoProfiler.h', 'public/GeckoProfilerReporter.h', + 'public/ProfilerMarkerPayload.h', ] if CONFIG['MOZ_TASK_TRACER']: diff --git a/tools/profiler/public/GeckoProfiler.h b/tools/profiler/public/GeckoProfiler.h index 47385cd27c2b..e42654a079d1 100644 --- a/tools/profiler/public/GeckoProfiler.h +++ b/tools/profiler/public/GeckoProfiler.h @@ -253,18 +253,23 @@ PROFILER_FUNC(double profiler_time(), 0) // Get the current thread's ID. PROFILER_FUNC(int profiler_current_thread_id(), 0) +// This is the function type of the callback passed to profiler_suspend_and_sample_thread. +// +// The callback is passed the following arguments: +// void** aPCs The program counters for the target thread's stack. +// size_t aCount The number of program counters in the aPCs array. +// bool aIsMainThread Whether the target thread was the main thread. +typedef void ProfilerStackCallback(void** aPCs, size_t aCount, bool aIsMainThread); + // This method suspends the thread identified by aThreadId, optionally samples -// it for its native stack, and then calls the callback. The callback is passed -// the native stack's program counters and length as two arguments if -// aSampleNative is true. +// it for its native stack, and then calls the callback. // // WARNING: The target thread is suspended during the callback. Do not try to // allocate or acquire any locks, or you could deadlock. The target thread will // have resumed by the time this function returns. PROFILER_FUNC_VOID( profiler_suspend_and_sample_thread(int aThreadId, - const std::function& - aCallback, + const std::function& aCallback, bool aSampleNative = true)) struct ProfilerBacktraceDestructor diff --git a/tools/profiler/public/ProfilerMarkerPayload.h b/tools/profiler/public/ProfilerMarkerPayload.h index 9648e365faf8..eb393a89adb4 100644 --- a/tools/profiler/public/ProfilerMarkerPayload.h +++ b/tools/profiler/public/ProfilerMarkerPayload.h @@ -7,9 +7,10 @@ #ifndef ProfilerMarkerPayload_h #define ProfilerMarkerPayload_h -#include "mozilla/TimeStamp.h" #include "mozilla/Attributes.h" #include "mozilla/RefPtr.h" +#include "mozilla/TimeStamp.h" +#include "mozilla/UniquePtrExtensions.h" #include "nsString.h" #include "GeckoProfiler.h" @@ -34,12 +35,19 @@ class UniqueStacks; class ProfilerMarkerPayload { public: - explicit ProfilerMarkerPayload(UniqueProfilerBacktrace aStack = nullptr); + explicit ProfilerMarkerPayload(UniqueProfilerBacktrace aStack = nullptr) + : mStack(Move(aStack)) + {} + ProfilerMarkerPayload(const mozilla::TimeStamp& aStartTime, const mozilla::TimeStamp& aEndTime, - UniqueProfilerBacktrace aStack = nullptr); + UniqueProfilerBacktrace aStack = nullptr) + : mStartTime(aStartTime) + , mEndTime(aEndTime) + , mStack(Move(aStack)) + {} - virtual ~ProfilerMarkerPayload(); + virtual ~ProfilerMarkerPayload() {} virtual void StreamPayload(SpliceableJSONWriter& aWriter, const mozilla::TimeStamp& aProcessStartTime, @@ -64,16 +72,32 @@ private: UniqueProfilerBacktrace mStack; }; +#define DECL_STREAM_PAYLOAD_BASE \ + virtual void StreamPayload(SpliceableJSONWriter& aWriter, \ + const mozilla::TimeStamp& aProcessStartTime, \ + UniqueStacks& aUniqueStacks) override + +// If the profiler is disabled then StreamPayload() will never be called. +#ifdef MOZ_GECKO_PROFILER +# define DECL_STREAM_PAYLOAD DECL_STREAM_PAYLOAD_BASE ; +#else +# define DECL_STREAM_PAYLOAD DECL_STREAM_PAYLOAD_BASE { MOZ_CRASH(); } +#endif + class TracingMarkerPayload : public ProfilerMarkerPayload { public: - TracingMarkerPayload(const char* aCategory, TracingKind aKind); TracingMarkerPayload(const char* aCategory, TracingKind aKind, - UniqueProfilerBacktrace aCause); + UniqueProfilerBacktrace aCause = nullptr) + : mCategory(aCategory) + , mKind(aKind) + { + if (aCause) { + SetStack(Move(aCause)); + } + } - virtual void StreamPayload(SpliceableJSONWriter& aWriter, - const mozilla::TimeStamp& aProcessStartTime, - UniqueStacks& aUniqueStacks) override; + DECL_STREAM_PAYLOAD private: const char *mCategory; @@ -86,16 +110,19 @@ public: IOMarkerPayload(const char* aSource, const char* aFilename, const mozilla::TimeStamp& aStartTime, const mozilla::TimeStamp& aEndTime, - UniqueProfilerBacktrace aStack); - ~IOMarkerPayload(); + UniqueProfilerBacktrace aStack) + : ProfilerMarkerPayload(aStartTime, aEndTime, Move(aStack)) + , mSource(aSource) + , mFilename(aFilename ? strdup(aFilename) : nullptr) + { + MOZ_ASSERT(aSource); + } - virtual void StreamPayload(SpliceableJSONWriter& aWriter, - const mozilla::TimeStamp& aProcessStartTime, - UniqueStacks& aUniqueStacks) override; + DECL_STREAM_PAYLOAD private: const char* mSource; - char* mFilename; + mozilla::UniqueFreePtr mFilename; }; class DOMEventMarkerPayload : public ProfilerMarkerPayload @@ -103,12 +130,13 @@ class DOMEventMarkerPayload : public ProfilerMarkerPayload public: DOMEventMarkerPayload(const nsAString& aType, uint16_t aPhase, const mozilla::TimeStamp& aStartTime, - const mozilla::TimeStamp& aEndTime); - ~DOMEventMarkerPayload(); + const mozilla::TimeStamp& aEndTime) + : ProfilerMarkerPayload(aStartTime, aEndTime) + , mType(aType) + , mPhase(aPhase) + {} - virtual void StreamPayload(SpliceableJSONWriter& aWriter, - const mozilla::TimeStamp& aProcessStartTime, - UniqueStacks& aUniqueStacks) override; + DECL_STREAM_PAYLOAD private: nsString mType; @@ -119,15 +147,21 @@ class UserTimingMarkerPayload : public ProfilerMarkerPayload { public: UserTimingMarkerPayload(const nsAString& aName, - const mozilla::TimeStamp& aStartTime); + const mozilla::TimeStamp& aStartTime) + : ProfilerMarkerPayload(aStartTime, aStartTime) + , mEntryType("mark") + , mName(aName) + {} + UserTimingMarkerPayload(const nsAString& aName, const mozilla::TimeStamp& aStartTime, - const mozilla::TimeStamp& aEndTime); - ~UserTimingMarkerPayload(); + const mozilla::TimeStamp& aEndTime) + : ProfilerMarkerPayload(aStartTime, aEndTime) + , mEntryType("measure") + , mName(aName) + {} - virtual void StreamPayload(SpliceableJSONWriter& aWriter, - const mozilla::TimeStamp& aProcessStartTime, - UniqueStacks& aUniqueStacks) override; + DECL_STREAM_PAYLOAD private: // Either "mark" or "measure". @@ -141,11 +175,14 @@ class LayerTranslationMarkerPayload : public ProfilerMarkerPayload { public: LayerTranslationMarkerPayload(mozilla::layers::Layer* aLayer, - mozilla::gfx::Point aPoint); + mozilla::gfx::Point aPoint, + mozilla::TimeStamp aStartTime) + : ProfilerMarkerPayload(aStartTime, aStartTime) + , mLayer(aLayer) + , mPoint(aPoint) + {} - virtual void StreamPayload(SpliceableJSONWriter& aWriter, - const mozilla::TimeStamp& aProcessStartTime, - UniqueStacks& aUniqueStacks) override; + DECL_STREAM_PAYLOAD private: mozilla::layers::Layer* mLayer; @@ -158,12 +195,12 @@ private: class VsyncMarkerPayload : public ProfilerMarkerPayload { public: - explicit VsyncMarkerPayload(mozilla::TimeStamp aVsyncTimestamp); - virtual ~VsyncMarkerPayload() {} + explicit VsyncMarkerPayload(mozilla::TimeStamp aVsyncTimestamp) + : ProfilerMarkerPayload(aVsyncTimestamp, aVsyncTimestamp) + , mVsyncTimestamp(aVsyncTimestamp) + {} - virtual void StreamPayload(SpliceableJSONWriter& aWriter, - const mozilla::TimeStamp& aProcessStartTime, - UniqueStacks& aUniqueStacks) override; + DECL_STREAM_PAYLOAD private: mozilla::TimeStamp mVsyncTimestamp; @@ -175,12 +212,15 @@ public: GPUMarkerPayload(const mozilla::TimeStamp& aCpuTimeStart, const mozilla::TimeStamp& aCpuTimeEnd, uint64_t aGpuTimeStart, - uint64_t aGpuTimeEnd); - ~GPUMarkerPayload() {} + uint64_t aGpuTimeEnd) + : ProfilerMarkerPayload(aCpuTimeStart, aCpuTimeEnd) + , mCpuTimeStart(aCpuTimeStart) + , mCpuTimeEnd(aCpuTimeEnd) + , mGpuTimeStart(aGpuTimeStart) + , mGpuTimeEnd(aGpuTimeEnd) + {} - virtual void StreamPayload(SpliceableJSONWriter& aWriter, - const mozilla::TimeStamp& aProcessStartTime, - UniqueStacks& aUniqueStacks) override; + DECL_STREAM_PAYLOAD private: mozilla::TimeStamp mCpuTimeStart; @@ -195,15 +235,11 @@ public: GCSliceMarkerPayload(const mozilla::TimeStamp& aStartTime, const mozilla::TimeStamp& aEndTime, JS::UniqueChars&& aTimingJSON) - : ProfilerMarkerPayload(aStartTime, aEndTime, nullptr), + : ProfilerMarkerPayload(aStartTime, aEndTime), mTimingJSON(mozilla::Move(aTimingJSON)) {} - virtual ~GCSliceMarkerPayload() {} - - void StreamPayload(SpliceableJSONWriter& aWriter, - const mozilla::TimeStamp& aProcessStartTime, - UniqueStacks& aUniqueStacks) override; + DECL_STREAM_PAYLOAD private: JS::UniqueChars mTimingJSON; @@ -215,15 +251,11 @@ public: GCMajorMarkerPayload(const mozilla::TimeStamp& aStartTime, const mozilla::TimeStamp& aEndTime, JS::UniqueChars&& aTimingJSON) - : ProfilerMarkerPayload(aStartTime, aEndTime, nullptr), + : ProfilerMarkerPayload(aStartTime, aEndTime), mTimingJSON(mozilla::Move(aTimingJSON)) {} - virtual ~GCMajorMarkerPayload() {} - - void StreamPayload(SpliceableJSONWriter& aWriter, - const mozilla::TimeStamp& aProcessStartTime, - UniqueStacks& aUniqueStacks) override; + DECL_STREAM_PAYLOAD private: JS::UniqueChars mTimingJSON; @@ -235,15 +267,11 @@ public: GCMinorMarkerPayload(const mozilla::TimeStamp& aStartTime, const mozilla::TimeStamp& aEndTime, JS::UniqueChars&& aTimingData) - : ProfilerMarkerPayload(aStartTime, aEndTime, nullptr), + : ProfilerMarkerPayload(aStartTime, aEndTime), mTimingData(mozilla::Move(aTimingData)) {} - virtual ~GCMinorMarkerPayload() {}; - - void StreamPayload(SpliceableJSONWriter& aWriter, - const mozilla::TimeStamp& aProcessStartTime, - UniqueStacks& aUniqueStacks) override; + DECL_STREAM_PAYLOAD private: JS::UniqueChars mTimingData; diff --git a/widget/VsyncDispatcher.cpp b/widget/VsyncDispatcher.cpp index cac138b7b08e..d853da54a46b 100644 --- a/widget/VsyncDispatcher.cpp +++ b/widget/VsyncDispatcher.cpp @@ -33,9 +33,7 @@ void CompositorVsyncDispatcher::NotifyVsync(TimeStamp aVsyncTimestamp) { // In vsync thread -#ifdef MOZ_GECKO_PROFILER layers::CompositorBridgeParent::PostInsertVsyncProfilerMarker(aVsyncTimestamp); -#endif MutexAutoLock lock(mCompositorObserverLock); if (mCompositorVsyncObserver) { diff --git a/widget/cocoa/nsChildView.h b/widget/cocoa/nsChildView.h index bb92b164205b..afc498df7f0c 100644 --- a/widget/cocoa/nsChildView.h +++ b/widget/cocoa/nsChildView.h @@ -297,7 +297,7 @@ public: // //------------------------------------------------------------------------- -class nsChildView : public nsBaseWidget +class nsChildView final : public nsBaseWidget { private: typedef nsBaseWidget Inherited; diff --git a/widget/cocoa/nsCocoaWindow.h b/widget/cocoa/nsCocoaWindow.h index 2cdaf56127a3..ed0afc6b4a9b 100644 --- a/widget/cocoa/nsCocoaWindow.h +++ b/widget/cocoa/nsCocoaWindow.h @@ -206,7 +206,7 @@ typedef struct _nsCocoaWindowList { - (void)restoreBackgroundColor; @end -class nsCocoaWindow : public nsBaseWidget, public nsPIWidgetCocoa +class nsCocoaWindow final : public nsBaseWidget, public nsPIWidgetCocoa { private: typedef nsBaseWidget Inherited; diff --git a/widget/windows/WinCompositorWidget.cpp b/widget/windows/WinCompositorWidget.cpp index cb642607598b..848537d25371 100644 --- a/widget/windows/WinCompositorWidget.cpp +++ b/widget/windows/WinCompositorWidget.cpp @@ -104,10 +104,16 @@ WinCompositorWidget::StartRemoteDrawing() return nullptr; } - MOZ_ASSERT(!mCompositeDC); - mCompositeDC = dc; + RefPtr dt = + mozilla::gfx::Factory::CreateDrawTargetForCairoSurface(surf->CairoSurface(), + size); + if (dt) { + mCompositeDC = dc; + } else { + FreeWindowSurface(dc); + } - return mozilla::gfx::Factory::CreateDrawTargetForCairoSurface(surf->CairoSurface(), size); + return dt.forget(); } void diff --git a/widget/windows/nsWindow.cpp b/widget/windows/nsWindow.cpp index d3f59bd2b9c1..a224952e1c0b 100644 --- a/widget/windows/nsWindow.cpp +++ b/widget/windows/nsWindow.cpp @@ -7176,19 +7176,6 @@ nsWindow::IsPopup() return mWindowType == eWindowType_popup; } -bool -nsWindow::ShouldUseOffMainThreadCompositing() -{ - // We don't currently support using an accelerated layer manager with - // transparent windows so don't even try. I'm also not sure if we even - // want to support this case. See bug 593471 - if (!(HasRemoteContent() && gIsPopupCompositingEnabled) && mTransparencyMode == eTransparencyTransparent) { - return false; - } - - return nsBaseWidget::ShouldUseOffMainThreadCompositing(); -} - void nsWindow::WindowUsesOMTC() { diff --git a/widget/windows/nsWindow.h b/widget/windows/nsWindow.h index a35470a8436b..f2c0e131270f 100644 --- a/widget/windows/nsWindow.h +++ b/widget/windows/nsWindow.h @@ -301,7 +301,6 @@ public: bool const DestroyCalled() { return mDestroyCalled; } bool IsPopup(); - virtual bool ShouldUseOffMainThreadCompositing() override; const IMEContext& DefaultIMC() const { return mDefaultIMC; } diff --git a/xpcom/base/CycleCollectedJSRuntime.cpp b/xpcom/base/CycleCollectedJSRuntime.cpp index 4916bf64806b..2f66b6c45449 100644 --- a/xpcom/base/CycleCollectedJSRuntime.cpp +++ b/xpcom/base/CycleCollectedJSRuntime.cpp @@ -85,9 +85,7 @@ #include "nsWrapperCache.h" #include "nsStringBuffer.h" #include "GeckoProfiler.h" -#ifdef MOZ_GECKO_PROFILER #include "ProfilerMarkerPayload.h" -#endif #ifdef MOZ_CRASHREPORTER #include "nsExceptionHandler.h" @@ -834,7 +832,6 @@ CycleCollectedJSRuntime::GCSliceCallback(JSContext* aContext, CycleCollectedJSRuntime* self = CycleCollectedJSRuntime::Get(); MOZ_ASSERT(CycleCollectedJSContext::Get()->Context() == aContext); -#ifdef MOZ_GECKO_PROFILER if (profiler_is_active()) { if (aProgress == JS::GC_CYCLE_END) { profiler_add_marker( @@ -850,7 +847,6 @@ CycleCollectedJSRuntime::GCSliceCallback(JSContext* aContext, aDesc.sliceToJSON(aContext))); } } -#endif if (aProgress == JS::GC_CYCLE_END) { JS::gcreason::Reason reason = aDesc.reason_; @@ -935,13 +931,11 @@ CycleCollectedJSRuntime::GCNurseryCollectionCallback(JSContext* aContext, } else if ((aProgress == JS::GCNurseryProgress::GC_NURSERY_COLLECTION_END) && profiler_is_active()) { -#ifdef MOZ_GECKO_PROFILER profiler_add_marker( "GCMinor", MakeUnique(self->mLatestNurseryCollectionStart, TimeStamp::Now(), JS::MinorGcToJSON(aContext))); -#endif } if (self->mPrevGCNurseryCollectionCallback) { diff --git a/xpcom/build/XPCOM.h b/xpcom/build/XPCOM.h index f52a87c69565..8ec9f47d26d1 100644 --- a/xpcom/build/XPCOM.h +++ b/xpcom/build/XPCOM.h @@ -14,6 +14,10 @@ #include +#ifndef MOZILLA_INTERNAL_API +#error "MOZILLA_INTERNAL_API must be defined" +#endif + // core headers required by pretty much everything else #include "nscore.h" @@ -35,13 +39,9 @@ #include "nsCOMPtr.h" #include "nsCOMArray.h" -#ifndef MOZILLA_INTERNAL_API -#include "nsStringAPI.h" -#else #include "nsString.h" #include "nsReadableUtils.h" #include "nsNativeCharsetUtils.h" -#endif #include "nsISupportsUtils.h" #include "nsISupportsImpl.h" diff --git a/xpcom/ds/PLDHashTable.cpp b/xpcom/ds/PLDHashTable.cpp index ffb074aeb8cf..06170ccd425d 100644 --- a/xpcom/ds/PLDHashTable.cpp +++ b/xpcom/ds/PLDHashTable.cpp @@ -72,10 +72,7 @@ PLDHashTable::HashStringKey(const void* aKey) /* static */ PLDHashNumber PLDHashTable::HashVoidPtrKeyStub(const void* aKey) { - // Be careful! We don't want to do the cast to PLDHashNumber which is a - // trimming cast on 64-bit platforms before the shift, otherwise we will lose - // valuable bits from our hash key! - return PLDHashNumber(uintptr_t(aKey) >> 2); + return uintptr_t(aKey) >> 2; } /* static */ bool @@ -258,10 +255,10 @@ PLDHashTable::Hash1(PLDHashNumber aHash0) void PLDHashTable::Hash2(PLDHashNumber aHash0, - uint32_t& aHash2Out, uint32_t& aSizeMaskOut) + size_t& aHash2Out, size_t& aSizeMaskOut) { - uint32_t sizeLog2 = kHashBits - mHashShift; - uint32_t sizeMask = (PLDHashNumber(1) << sizeLog2) - 1; + size_t sizeLog2 = kHashBits - mHashShift; + size_t sizeMask = (PLDHashNumber(1) << sizeLog2) - 1; aSizeMaskOut = sizeMask; // The incoming aHash0 always has the low bit unset (since we leave it @@ -295,7 +292,7 @@ PLDHashTable::MatchEntryKeyhash(PLDHashEntryHdr* aEntry, PLDHashNumber aKeyHash) // Compute the address of the indexed entry in table. PLDHashEntryHdr* -PLDHashTable::AddressEntry(uint32_t aIndex) +PLDHashTable::AddressEntry(size_t aIndex) { return reinterpret_cast( mEntryStore.Get() + aIndex * mEntrySize); @@ -373,7 +370,7 @@ PLDHashTable::SearchTable(const void* aKey, PLDHashNumber aKeyHash) // Collision: double hash. PLDHashNumber hash2; - uint32_t sizeMask; + size_t sizeMask; Hash2(aKeyHash, hash2, sizeMask); // Save the first removed entry pointer so Add() can recycle it. (Only used @@ -433,7 +430,7 @@ PLDHashTable::FindFreeEntry(PLDHashNumber aKeyHash) // Collision: double hash. PLDHashNumber hash2; - uint32_t sizeMask; + size_t sizeMask; Hash2(aKeyHash, hash2, sizeMask); for (;;) { diff --git a/xpcom/ds/PLDHashTable.h b/xpcom/ds/PLDHashTable.h index cd1323dbe7b5..3b74c65f9d70 100644 --- a/xpcom/ds/PLDHashTable.h +++ b/xpcom/ds/PLDHashTable.h @@ -15,7 +15,7 @@ #include "mozilla/Types.h" #include "nscore.h" -typedef uint32_t PLDHashNumber; +typedef size_t PLDHashNumber; class PLDHashTable; struct PLDHashTableOps; @@ -490,10 +490,15 @@ public: } private: - // Multiplicative hash uses an unsigned 32 bit integer and the golden ratio, - // expressed as a fixed-point 32-bit fraction. - static const uint32_t kHashBits = 32; + // Multiplicative hash uses an unsigned pointer sized integer and the golden ratio, + // expressed as a fixed-point pointer sized fraction. + static const uint32_t kHashBits = sizeof(size_t) * 8; +#ifdef HAVE_64BIT_BUILD + // Golden ratio borrowed from http://burtleburtle.net/bob/hash/evahash.html. + static const uint64_t kGoldenRatio = 0X9E3779B97F4A7C13ULL; +#else static const uint32_t kGoldenRatio = 0x9E3779B9U; +#endif static uint32_t HashShift(uint32_t aEntrySize, uint32_t aLength); @@ -522,10 +527,10 @@ private: } PLDHashNumber Hash1(PLDHashNumber aHash0); - void Hash2(PLDHashNumber aHash, uint32_t& aHash2Out, uint32_t& aSizeMaskOut); + void Hash2(PLDHashNumber aHash, size_t& aHash2Out, size_t& aSizeMaskOut); static bool MatchEntryKeyhash(PLDHashEntryHdr* aEntry, PLDHashNumber aHash); - PLDHashEntryHdr* AddressEntry(uint32_t aIndex); + PLDHashEntryHdr* AddressEntry(size_t aIndex); // We store mHashShift rather than sizeLog2 to optimize the collision-free // case in SearchTable. diff --git a/xpcom/ds/nsBaseHashtable.h b/xpcom/ds/nsBaseHashtable.h index e0412b615489..1560b210e3bc 100644 --- a/xpcom/ds/nsBaseHashtable.h +++ b/xpcom/ds/nsBaseHashtable.h @@ -154,10 +154,28 @@ public: } /** - * remove the data for the associated key + * Remove the entry associated with aKey (if any), optionally _moving_ its + * current value into *aData. Return true if found. * @param aKey the key to remove from the hashtable + * @param aData where to move the value (if non-null). If an entry is not + * found, *aData will be assigned a default-constructed value + * (i.e. reset to zero or nullptr for primitive types). + * @return true if an entry for aKey was found (and removed) */ - void Remove(KeyType aKey) { this->RemoveEntry(aKey); } + bool Remove(KeyType aKey, DataType* aData = nullptr) + { + if (auto* ent = this->GetEntry(aKey)) { + if (aData) { + *aData = mozilla::Move(ent->mData); + } + this->RemoveEntry(ent); + return true; + } + if (aData) { + *aData = mozilla::Move(DataType()); + } + return false; + } struct LookupResult { private: diff --git a/xpcom/ds/nsClassHashtable.h b/xpcom/ds/nsClassHashtable.h index ab264a21ca3f..94650b078d93 100644 --- a/xpcom/ds/nsClassHashtable.h +++ b/xpcom/ds/nsClassHashtable.h @@ -30,6 +30,7 @@ public: typedef nsBaseHashtable, T*> base_type; using base_type::IsEmpty; + using base_type::Remove; nsClassHashtable() {} explicit nsClassHashtable(uint32_t aInitLength) @@ -55,19 +56,6 @@ public: * @returns nullptr if the key is not present. */ UserDataType Get(KeyType aKey) const; - - /** - * Remove the entry for the given key from the hashtable and return it in - * aOut. If the key is not in the hashtable, aOut's pointer is set to - * nullptr. - * - * Normally, an entry is deleted when it's removed from an nsClassHashtable, - * but this function transfers ownership of the entry back to the caller - * through aOut -- the entry will be deleted when aOut goes out of scope. - * - * @param aKey the key to get and remove from the hashtable - */ - void RemoveAndForget(KeyType aKey, nsAutoPtr& aOut); }; // @@ -121,21 +109,4 @@ nsClassHashtable::Get(KeyType aKey) const return ent->mData; } -template -void -nsClassHashtable::RemoveAndForget(KeyType aKey, nsAutoPtr& aOut) -{ - aOut = nullptr; - - typename base_type::EntryType* ent = this->GetEntry(aKey); - if (!ent) { - return; - } - - // Transfer ownership from ent->mData into aOut. - aOut = mozilla::Move(ent->mData); - - this->RemoveEntry(ent); -} - #endif // nsClassHashtable_h__ diff --git a/xpcom/ds/nsHashPropertyBag.cpp b/xpcom/ds/nsHashPropertyBag.cpp index 3bc5371e9698..f3d47aa4bf9b 100644 --- a/xpcom/ds/nsHashPropertyBag.cpp +++ b/xpcom/ds/nsHashPropertyBag.cpp @@ -61,11 +61,7 @@ nsHashPropertyBagBase::SetProperty(const nsAString& aName, nsIVariant* aValue) NS_IMETHODIMP nsHashPropertyBagBase::DeleteProperty(const nsAString& aName) { - if (auto entry = mPropertyHash.Lookup(aName)) { - entry.Remove(); - return NS_OK; - } - return NS_ERROR_FAILURE; + return mPropertyHash.Remove(aName) ? NS_OK : NS_ERROR_FAILURE; } diff --git a/xpcom/ds/nsInterfaceHashtable.h b/xpcom/ds/nsInterfaceHashtable.h index 14368af63764..b9ee98c78b51 100644 --- a/xpcom/ds/nsInterfaceHashtable.h +++ b/xpcom/ds/nsInterfaceHashtable.h @@ -53,6 +53,17 @@ public: * @return The entry, or nullptr if not found. Do not release this pointer! */ Interface* GetWeak(KeyType aKey, bool* aFound = nullptr) const; + + /** + * Remove the entry associated with aKey (if any), optionally _moving_ its + * current value into *aData, thereby avoiding calls to AddRef and Release. + * Return true if found. + * @param aKey the key to remove from the hashtable + * @param aData where to move the value (if non-null). If an entry is not + * found it will be set to nullptr. + * @return true if an entry for aKey was found (and removed) + */ + inline bool Remove(KeyType aKey, Interface** aData = nullptr); }; template @@ -139,4 +150,25 @@ nsInterfaceHashtable::GetWeak(KeyType aKey, return nullptr; } +template +bool +nsInterfaceHashtable::Remove(KeyType aKey, + Interface** aData) +{ + typename base_type::EntryType* ent = this->GetEntry(aKey); + + if (ent) { + if (aData) { + ent->mData.forget(aData); + } + this->RemoveEntry(ent); + return true; + } + + if (aData) { + *aData = nullptr; + } + return false; +} + #endif // nsInterfaceHashtable_h__ diff --git a/xpcom/ds/nsPointerHashKeys.h b/xpcom/ds/nsPointerHashKeys.h index 796c652f9e3d..d8091a889ac7 100644 --- a/xpcom/ds/nsPointerHashKeys.h +++ b/xpcom/ds/nsPointerHashKeys.h @@ -35,10 +35,7 @@ public: static KeyTypePointer KeyToPointer(KeyType aKey) { return aKey; } static PLDHashNumber HashKey(KeyTypePointer aKey) { - // Be careful! We don't want to do the cast to PLDHashNumber which is a - // trimming cast on 64-bit platforms before the shift, otherwise we will - // lose valuable bits from our hash key! - return PLDHashNumber(uintptr_t(aKey) >> 2); + return uintptr_t(aKey) >> 2; } enum { ALLOW_MEMMOVE = true }; diff --git a/xpcom/ds/nsProperties.cpp b/xpcom/ds/nsProperties.cpp index 60d0960028a8..8b80166e9dde 100644 --- a/xpcom/ds/nsProperties.cpp +++ b/xpcom/ds/nsProperties.cpp @@ -44,11 +44,7 @@ nsProperties::Undefine(const char* prop) return NS_ERROR_INVALID_ARG; } - if (auto entry = nsProperties_HashBase::Lookup(prop)) { - entry.Remove(); - return NS_OK; - } - return NS_ERROR_FAILURE; + return nsProperties_HashBase::Remove(prop) ? NS_OK : NS_ERROR_FAILURE; } NS_IMETHODIMP diff --git a/xpcom/ds/nsRefPtrHashtable.h b/xpcom/ds/nsRefPtrHashtable.h index 27e8248a560f..bad5cbc08651 100644 --- a/xpcom/ds/nsRefPtrHashtable.h +++ b/xpcom/ds/nsRefPtrHashtable.h @@ -57,17 +57,16 @@ public: MOZ_MUST_USE bool Put(KeyType aKey, already_AddRefed aData, const mozilla::fallible_t&); - // Overload Remove, rather than overriding it. - using base_type::Remove; - /** - * Remove the data for the associated key, swapping the current value into - * pData, thereby avoiding calls to AddRef and Release. + * Remove the entry associated with aKey (if any), optionally _moving_ its + * current value into *aData, thereby avoiding calls to AddRef and Release. + * Return true if found. * @param aKey the key to remove from the hashtable - * @param aData This is an XPCOM getter, so aData is already_addrefed. - * If the key doesn't exist, aData will be set to nullptr. Must be non-null. + * @param aData where to move the value (if non-null). If an entry is not + * found it will be set to nullptr. + * @return true if an entry for aKey was found (and removed) */ - bool Remove(KeyType aKey, UserDataType* aData); + inline bool Remove(KeyType aKey, UserDataType* aData = nullptr); }; template @@ -173,18 +172,19 @@ bool nsRefPtrHashtable::Remove(KeyType aKey, UserDataType* aRefPtr) { - MOZ_ASSERT(aRefPtr); typename base_type::EntryType* ent = this->GetEntry(aKey); if (ent) { - ent->mData.forget(aRefPtr); + if (aRefPtr) { + ent->mData.forget(aRefPtr); + } this->RemoveEntry(ent); return true; } - // If the key doesn't exist, set *aRefPtr to null - // so that it is a valid XPCOM getter. - *aRefPtr = nullptr; + if (aRefPtr) { + *aRefPtr = nullptr; + } return false; } diff --git a/xpcom/io/nsDirectoryService.cpp b/xpcom/io/nsDirectoryService.cpp index a4590f8507cd..5643bf213af8 100644 --- a/xpcom/io/nsDirectoryService.cpp +++ b/xpcom/io/nsDirectoryService.cpp @@ -271,11 +271,7 @@ nsDirectoryService::Undefine(const char* aProp) } nsDependentCString key(aProp); - if (auto entry = mHashtable.Lookup(key)) { - entry.Remove(); - return NS_OK; - } - return NS_ERROR_FAILURE; + return mHashtable.Remove(key) ? NS_OK : NS_ERROR_FAILURE; } NS_IMETHODIMP diff --git a/xpcom/threads/BackgroundHangMonitor.cpp b/xpcom/threads/BackgroundHangMonitor.cpp index ef96a71d1884..02af6019f6eb 100644 --- a/xpcom/threads/BackgroundHangMonitor.cpp +++ b/xpcom/threads/BackgroundHangMonitor.cpp @@ -199,6 +199,8 @@ public: // List of runnables which can hold a reference to us which need to be // canceled before we can go away. LinkedList> mProcessHangRunnables; + // The name of the runnable which is hanging the current process + nsCString mRunnableName; BackgroundHangThread(const char* aName, uint32_t aTimeoutMs, @@ -354,12 +356,16 @@ BackgroundHangManager::RunMonitorThread() // for all hangs, not just permahangs. currentThread->mStats.mNativeStackCnt += 1; currentThread->mStackHelper.GetPseudoAndNativeStack( - currentThread->mHangStack, currentThread->mNativeHangStack); + currentThread->mHangStack, + currentThread->mNativeHangStack, + currentThread->mRunnableName); } else { - currentThread->mStackHelper.GetPseudoStack(currentThread->mHangStack); + currentThread->mStackHelper.GetPseudoStack(currentThread->mHangStack, + currentThread->mRunnableName); } #else - currentThread->mStackHelper.GetPseudoStack(currentThread->mHangStack); + currentThread->mStackHelper.GetPseudoStack(currentThread->mHangStack, + currentThread->mRunnableName); #endif currentThread->mHangStart = interval; currentThread->mHanging = true; @@ -574,7 +580,7 @@ BackgroundHangThread::ReportHang(PRIntervalTime aHangTime) mHangStack.erase(mHangStack.begin() + 1, mHangStack.begin() + elementsToRemove); } - Telemetry::HangHistogram newHistogram(Move(mHangStack)); + Telemetry::HangHistogram newHistogram(Move(mHangStack), mRunnableName); for (Telemetry::HangHistogram* oldHistogram = mStats.mHangs.begin(); oldHistogram != mStats.mHangs.end(); oldHistogram++) { if (newHistogram == *oldHistogram) { diff --git a/xpcom/threads/ThreadStackHelper.cpp b/xpcom/threads/ThreadStackHelper.cpp index a225bd10fc26..cf4e7843ef59 100644 --- a/xpcom/threads/ThreadStackHelper.cpp +++ b/xpcom/threads/ThreadStackHelper.cpp @@ -21,6 +21,7 @@ #include "mozilla/UniquePtr.h" #include "mozilla/MemoryChecking.h" #include "mozilla/Sprintf.h" +#include "nsThread.h" #ifdef __GNUC__ # pragma GCC diagnostic push @@ -91,26 +92,32 @@ public: } // namespace void -ThreadStackHelper::GetPseudoStack(Stack& aStack) +ThreadStackHelper::GetPseudoStack(Stack& aStack, nsACString& aRunnableName) { - GetStacksInternal(&aStack, nullptr); + GetStacksInternal(&aStack, nullptr, aRunnableName); } void -ThreadStackHelper::GetNativeStack(NativeStack& aNativeStack) +ThreadStackHelper::GetNativeStack(NativeStack& aNativeStack, nsACString& aRunnableName) { - GetStacksInternal(nullptr, &aNativeStack); + GetStacksInternal(nullptr, &aNativeStack, aRunnableName); } void -ThreadStackHelper::GetPseudoAndNativeStack(Stack& aStack, NativeStack& aNativeStack) +ThreadStackHelper::GetPseudoAndNativeStack(Stack& aStack, + NativeStack& aNativeStack, + nsACString& aRunnableName) { - GetStacksInternal(&aStack, &aNativeStack); + GetStacksInternal(&aStack, &aNativeStack, aRunnableName); } void -ThreadStackHelper::GetStacksInternal(Stack* aStack, NativeStack* aNativeStack) +ThreadStackHelper::GetStacksInternal(Stack* aStack, + NativeStack* aNativeStack, + nsACString& aRunnableName) { + aRunnableName.AssignLiteral("???"); + #if defined(MOZ_THREADSTACKHELPER_PSEUDO) || defined(MOZ_THREADSTACKHELPER_NATIVE) // Always run PrepareStackBuffer first to clear aStack if (aStack && !PrepareStackBuffer(*aStack)) { @@ -131,7 +138,22 @@ ThreadStackHelper::GetStacksInternal(Stack* aStack, NativeStack* aNativeStack) ScopedSetPtr nativeStackPtr(mNativeStackToFill, aNativeStack); #endif - auto callback = [&, this] (void** aPCs, size_t aCount) { + char nameBuffer[1000] = {0}; + auto callback = [&, this] (void** aPCs, size_t aCount, bool aIsMainThread) { + // NOTE: We cannot allocate any memory in this callback, as the target + // thread is suspended, so we first copy it into a stack-allocated buffer, + // and then once the target thread is resumed, we can copy it into a real + // nsCString. + // + // Currently we only store the names of runnables which are running on the + // main thread, so we only want to read sMainThreadRunnableName and copy its + // value in the case that we are currently suspending the main thread. + if (aIsMainThread && nsThread::sMainThreadRunnableName) { + strncpy(nameBuffer, nsThread::sMainThreadRunnableName, sizeof(nameBuffer)); + // Make sure the string is null-terminated. + nameBuffer[sizeof(nameBuffer) - 1] = '\0'; + } + #ifdef MOZ_THREADSTACKHELPER_PSEUDO if (mStackToFill) { FillStackBuffer(); @@ -153,6 +175,11 @@ ThreadStackHelper::GetStacksInternal(Stack* aStack, NativeStack* aNativeStack) callback, /* aSampleNative = */ !!aNativeStack); } + + // Copy the name buffer allocation into the output string. + if (nameBuffer[0] != 0) { + aRunnableName = nameBuffer; + } #endif } diff --git a/xpcom/threads/ThreadStackHelper.h b/xpcom/threads/ThreadStackHelper.h index 6730d99c2725..3e40924ac42e 100644 --- a/xpcom/threads/ThreadStackHelper.h +++ b/xpcom/threads/ThreadStackHelper.h @@ -90,33 +90,40 @@ public: * Retrieve the current pseudostack of the thread associated * with this ThreadStackHelper. * - * @param aStack Stack instance to be filled. + * @param aStack Stack instance to be filled. + * @param aRunnableName The name of the current runnable on the target thread. */ - void GetPseudoStack(Stack& aStack); + void GetPseudoStack(Stack& aStack, nsACString& aRunnableName); /** * Retrieve the current native stack of the thread associated * with this ThreadStackHelper. * - * @param aNativeStack NativeStack instance to be filled. + * @param aNativeStack NativeStack instance to be filled. + * @param aRunnableName The name of the current runnable on the target thread. */ - void GetNativeStack(NativeStack& aNativeStack); + void GetNativeStack(NativeStack& aNativeStack, nsACString& aRunnableName); /** * Retrieve the current pseudostack and native stack of the thread associated * with this ThreadStackHelper. This method only pauses the target thread once * to get both stacks. * - * @param aStack Stack instance to be filled with the pseudostack. - * @param aNativeStack NativeStack instance to be filled with the native stack. + * @param aStack Stack instance to be filled with the pseudostack. + * @param aNativeStack NativeStack instance to be filled with the native stack. + * @param aRunnableName The name of the current runnable on the target thread. */ - void GetPseudoAndNativeStack(Stack& aStack, NativeStack& aNativeStack); + void GetPseudoAndNativeStack(Stack& aStack, + NativeStack& aNativeStack, + nsACString& aRunnableName); private: // Fill in the passed aStack and aNativeStack datastructures with backtraces. // If only aStack needs to be collected, nullptr may be passed for // aNativeStack, and vice versa. - void GetStacksInternal(Stack* aStack, NativeStack* aNativeStack); + void GetStacksInternal(Stack* aStack, + NativeStack* aNativeStack, + nsACString& aRunnableName); // The profiler's unique thread identifier for the target thread. int mThreadId; diff --git a/xpcom/threads/nsThread.cpp b/xpcom/threads/nsThread.cpp index 5c78a0fadb5a..202025c5ca35 100644 --- a/xpcom/threads/nsThread.cpp +++ b/xpcom/threads/nsThread.cpp @@ -99,6 +99,8 @@ static LazyLogModule sThreadLog("nsThread"); NS_DECL_CI_INTERFACE_GETTER(nsThread) +const char* nsThread::sMainThreadRunnableName = nullptr; + //----------------------------------------------------------------------------- // Because we do not have our own nsIFactory, we have to implement nsIClassInfo // somewhat manually. @@ -1391,8 +1393,8 @@ nsThread::ProcessNextEvent(bool aMayWait, bool* aResult) Maybe> timer; Maybe> idleTimer; + nsAutoCString name; if ((MAIN_THREAD == mIsMainThread) || mNextIdleDeadline) { - nsCString name; bool labeled = GetLabeledRunnableName(event, name); if (MAIN_THREAD == mIsMainThread) { @@ -1417,6 +1419,19 @@ nsThread::ProcessNextEvent(bool aMayWait, bool* aResult) idleTimer.emplace(name, mNextIdleDeadline); } } + + // If we're on the main thread, we want to record our current runnable's + // name in a static so that BHR can record it. + const char* restoreRunnableName = nullptr; + auto clear = MakeScopeExit([&] { + if (MAIN_THREAD == mIsMainThread) { + sMainThreadRunnableName = restoreRunnableName; + } + }); + if (MAIN_THREAD == mIsMainThread) { + restoreRunnableName = sMainThreadRunnableName; + sMainThreadRunnableName = name.get(); + } #endif event->Run(); diff --git a/xpcom/threads/nsThread.h b/xpcom/threads/nsThread.h index 737b8c914d8e..5bbe8d8d78a7 100644 --- a/xpcom/threads/nsThread.h +++ b/xpcom/threads/nsThread.h @@ -93,6 +93,8 @@ public: static bool SaveMemoryReportNearOOM(ShouldSaveMemoryReport aShouldSave); #endif + static const char* sMainThreadRunnableName; + private: void DoMainThreadSpecificProcessing(bool aReallyWait); diff --git a/xpfe/components/windowds/nsWindowDataSource.cpp b/xpfe/components/windowds/nsWindowDataSource.cpp index 841b1163c289..e8c375a8862d 100644 --- a/xpfe/components/windowds/nsWindowDataSource.cpp +++ b/xpfe/components/windowds/nsWindowDataSource.cpp @@ -183,12 +183,10 @@ NS_IMETHODIMP nsWindowDataSource::OnCloseWindow(nsIXULWindow *window) { nsresult rv; - auto entry = mWindowResources.Lookup(window); - if (!entry) { + nsCOMPtr resource; + if (!mWindowResources.Remove(window, getter_AddRefs(resource))) { return NS_ERROR_UNEXPECTED; } - nsCOMPtr resource(entry.Data().forget()); - entry.Remove(); // make sure we're not shutting down if (!mContainer) return NS_OK;