Merge mozilla-central to autoland

This commit is contained in:
Carsten "Tomcat" Book 2017-07-05 13:05:51 +02:00
commit 49921c11be
186 changed files with 1591 additions and 1092 deletions

View File

@ -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();

View File

@ -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]

View File

@ -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);
});

View File

@ -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);

View File

@ -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(),
},

View File

@ -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);
};

View File

@ -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"
}
]
}
]
}
]
]

View File

@ -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

View File

@ -96,7 +96,7 @@ module.exports = createClass({
onChange: this.onShowGridLineNumbersCheckboxClick,
}
),
getStr("layout.displayNumbersOnLines")
getStr("layout.displayNumbersOnLines2")
)
),
dom.li(

View File

@ -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");

View File

@ -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()) {

View File

@ -14,9 +14,9 @@ layout.cannotShowGridOutline.title=The selected grids 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.

View File

@ -487,10 +487,8 @@ CustomElementRegistry::UpgradeCandidates(JSContext* aCx,
}
nsAutoPtr<nsTArray<nsWeakPtr>> 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) {

View File

@ -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
};

View File

@ -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);

View File

@ -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

View File

@ -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)

View File

@ -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;
}

View File

@ -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
{

View File

@ -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) {

View File

@ -45,7 +45,7 @@ public:
}
bool Equals(const nsMappedAttributes* aAttributes) const;
uint32_t HashValue() const;
PLDHashNumber HashValue() const;
void DropStyleSheetReference()
{

View File

@ -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"

View File

@ -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

View File

@ -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;
}

View File

@ -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<DOMEventMarkerPayload>(typeStr, phase,
startTime, endTime));
#endif
} else {
rv = HandleEventSubType(listener, *aDOMEvent, aCurrentTarget);
}

View File

@ -422,7 +422,7 @@ HTMLBodyElement::GetAssociatedEditor()
}
bool
HTMLBodyElement::IsEventAttributeName(nsIAtom *aName)
HTMLBodyElement::IsEventAttributeNameInternal(nsIAtom *aName)
{
return nsContentUtils::IsEventAttributeName(aName,
EventNameType_HTML |

View File

@ -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,

View File

@ -337,7 +337,7 @@ HTMLFrameSetElement::ParseRowCol(const nsAString & aValue,
}
bool
HTMLFrameSetElement::IsEventAttributeName(nsIAtom *aName)
HTMLFrameSetElement::IsEventAttributeNameInternal(nsIAtom *aName)
{
return nsContentUtils::IsEventAttributeName(aName,
EventNameType_HTML |

View File

@ -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.

View File

@ -7005,10 +7005,10 @@ HTMLMediaElement::DispatchEncrypted(const nsTArray<uint8_t>& aInitData,
}
bool
HTMLMediaElement::IsEventAttributeName(nsIAtom* aName)
HTMLMediaElement::IsEventAttributeNameInternal(nsIAtom* aName)
{
return aName == nsGkAtoms::onencrypted ||
nsGenericHTMLElement::IsEventAttributeName(aName);
nsGenericHTMLElement::IsEventAttributeNameInternal(aName);
}
already_AddRefed<nsIPrincipal>

View File

@ -653,7 +653,7 @@ public:
void DispatchEncrypted(const nsTArray<uint8_t>& 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.

View File

@ -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<nsIRunnable> event = new nsAutoFocusEvent(this);
rv = NS_DispatchToCurrentThread(event);
NS_ENSURE_SUCCESS(rv, rv);
@ -2925,7 +2925,7 @@ nsGenericHTMLElement::GetWidthHeightForImage(RefPtr<imgRequestProxy>& aImageRequ
}
bool
nsGenericHTMLElement::IsEventAttributeName(nsIAtom *aName)
nsGenericHTMLElement::IsEventAttributeNameInternal(nsIAtom *aName)
{
return nsContentUtils::IsEventAttributeName(aName, EventNameType_HTML);
}

View File

@ -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

View File

@ -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);

View File

@ -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]

View File

@ -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,

View File

@ -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 = {};
}

View File

@ -3462,7 +3462,7 @@ ContentChild::RecvProvideAnonymousTemporaryFile(const uint64_t& aID,
const FileDescOrError& aFDOrError)
{
nsAutoPtr<AnonymousTemporaryFileCallback> callback;
mPendingAnonymousTemporaryFiles.RemoveAndForget(aID, callback);
mPendingAnonymousTemporaryFiles.Remove(aID, &callback);
MOZ_ASSERT(callback);
PRFileDesc* prfile = nullptr;

View File

@ -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);
}
}

View File

@ -178,7 +178,7 @@ GeckoMediaPluginService::RunPluginCrashCallbacks(uint32_t aPluginId,
nsAutoPtr<nsTArray<RefPtr<GMPCrashHelper>>> 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));

View File

@ -113,7 +113,7 @@ public:
MOZ_ASSERT(aDecrypted.mSample);
nsAutoPtr<DecryptPromiseRequestHolder> holder;
mDecrypts.RemoveAndForget(aDecrypted.mSample, holder);
mDecrypts.Remove(aDecrypted.mSample, &holder);
if (holder) {
holder->Complete();
} else {

View File

@ -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<UserTimingMarkerPayload>(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<UserTimingMarkerPayload>(aName, startTimeStamp, endTimeStamp));
}
#endif
}
void

View File

@ -2201,7 +2201,7 @@ PluginInstanceParent::UnsubclassPluginWindow()
// Remove 'this' from the plugin list safely
nsAutoPtr<PluginInstanceParent> tmp;
MOZ_ASSERT(sPluginInstanceList);
sPluginInstanceList->RemoveAndForget((void*)mPluginHWND, tmp);
sPluginInstanceList->Remove((void*)mPluginHWND, &tmp);
tmp.forget();
if (!sPluginInstanceList->Count()) {
delete sPluginInstanceList;

View File

@ -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);
}

View File

@ -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();

View File

@ -92,7 +92,7 @@ public:
return static_cast<SVGMeetOrSlice>(mMeetOrSlice);
}
uint32_t Hash() const {
PLDHashNumber Hash() const {
return HashGeneric(mAlign, mMeetOrSlice);
}

View File

@ -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

View File

@ -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,

View File

@ -92,7 +92,7 @@ SVGTransformableElement::GetAttributeChangeHint(const nsIAtom* aAttribute,
}
bool
SVGTransformableElement::IsEventAttributeName(nsIAtom* aName)
SVGTransformableElement::IsEventAttributeNameInternal(nsIAtom* aName)
{
return nsContentUtils::IsEventAttributeName(aName, EventNameType_SVGGraphic);
}

View File

@ -52,7 +52,7 @@ public:
// nsSVGElement overrides
virtual bool IsEventAttributeName(nsIAtom* aName) override;
virtual bool IsEventAttributeNameInternal(nsIAtom* aName) override;
virtual gfxMatrix PrependLocalTransformsTo(

View File

@ -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"

View File

@ -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> 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.

View File

@ -1794,8 +1794,7 @@ ServiceWorkerManager::ReportToAllClients(const nsCString& aScope,
if (regList->IsEmpty()) {
regList = nullptr;
nsAutoPtr<WeakDocumentList> doomed;
mRegisteringDocuments.RemoveAndForget(aScope, doomed);
mRegisteringDocuments.Remove(aScope);
}
}
@ -1950,8 +1949,7 @@ ServiceWorkerManager::FlushReportsToAllClients(const nsACString& aScope,
if (regList->IsEmpty()) {
regList = nullptr;
nsAutoPtr<WeakDocumentList> doomed;
mRegisteringDocuments.RemoveAndForget(aScope, doomed);
mRegisteringDocuments.Remove(aScope);
}
}
@ -3891,8 +3889,7 @@ ServiceWorkerManager::ShouldReportToWindow(mozIDOMWindowProxy* aWindow,
if (list->IsEmpty()) {
list = nullptr;
nsAutoPtr<WeakDocumentList> 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<InterceptionList> doomed;
mNavigationInterceptions.RemoveAndForget(aScope, doomed);
mNavigationInterceptions.Remove(aScope);
}
}
}

View File

@ -175,7 +175,7 @@ nsXBLDocumentInfo::RemovePrototypeBinding(const nsACString& aRef)
{
if (mBindingTable) {
nsAutoPtr<nsXBLPrototypeBinding> bindingToRemove;
mBindingTable->RemoveAndForget(aRef, bindingToRemove);
mBindingTable->Remove(aRef, &bindingToRemove);
// We do not want to destroy the binding, so just forget it.
bindingToRemove.forget();

View File

@ -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);

View File

@ -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),

View File

@ -14,26 +14,6 @@
class nsIAtom;
class nsIDOMDocument;
class txUint32Array : public nsTArray<uint32_t>
{
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

View File

@ -2031,7 +2031,7 @@ nsXULElement::RecompileScriptEventListeners()
}
bool
nsXULElement::IsEventAttributeName(nsIAtom *aName)
nsXULElement::IsEventAttributeNameInternal(nsIAtom *aName)
{
return nsContentUtils::IsEventAttributeName(aName, EventNameType_XUL);
}

View File

@ -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

View File

@ -58,7 +58,7 @@ SimpleTest.waitForExplicitFinish();
</table>
</div>
<iframe onload="runTest();" id="pasteframe" src="data:text/html,<html><body contenteditable='true'>"></iframe>
<iframe onload="runTest();" id="pasteframe" srcdoc="<html><body contenteditable='true'>"></iframe>
</body>
</html>

View File

@ -94,7 +94,7 @@ SimpleTest.waitForFocus(function() {
continueTest();
});
iframe.src = "data:text/html,foo";
iframe.srcdoc = "foo";
document.getElementById("content").appendChild(iframe);
});

View File

@ -14,7 +14,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=674770
<p id="display"></p>
<div id="content">
<iframe id="iframe" style="display: block; height: 14em;"
src="data:text/html,<input id='text' value='pasted'><input id='input' style='display: block;'><p id='editor1' contenteditable>editor1:</p><p id='editor2' contenteditable>editor2:</p>"></iframe>
srcdoc="<input id='text' value='pasted'><input id='input' style='display: block;'><p id='editor1' contenteditable>editor1:</p><p id='editor2' contenteditable>editor2:</p>"></iframe>
</div>
<pre id="test">
<script type="application/javascript">
@ -337,8 +337,7 @@ function initForBodyEditableDocumentTests()
iframe.onload =
function (aEvent) { SimpleTest.executeSoon(runBodyEditableDocumentTests1); };
iframe.src =
"data:text/html,<body contenteditable>body:</body>";
iframe.srcdoc = "<body contenteditable>body:</body>";
}
function runBodyEditableDocumentTests1()

View File

@ -82,7 +82,7 @@ needs-focus == spellcheck-non-latin-japanese.html spellcheck-non-latin-japanese-
needs-focus == spellcheck-non-latin-korean.html spellcheck-non-latin-korean-ref.html
== unneeded_scroll.html unneeded_scroll-ref.html
== caret_on_presshell_reinit.html caret_on_presshell_reinit-ref.html
fuzzy-if(browserIsRemote,255,3) asserts-if(browserIsRemote,0-2) asserts-if(webrender&&!browserIsRemote,0-1) == caret_on_presshell_reinit-2.html caret_on_presshell_reinit-ref.html
fuzzy-if(browserIsRemote,255,3) asserts-if(browserIsRemote,0-3) asserts-if(webrender&&!browserIsRemote,0-1) == caret_on_presshell_reinit-2.html caret_on_presshell_reinit-ref.html # bug 959132 for assertions
fuzzy-if(asyncPan&&!layersGPUAccelerated,102,2824) == 642800.html 642800-ref.html
== selection_visibility_after_reframe.html selection_visibility_after_reframe-ref.html
!= selection_visibility_after_reframe-2.html selection_visibility_after_reframe-ref.html

View File

@ -1050,7 +1050,7 @@ struct ScrollableLayerGuid {
return false;
}
uint32_t Hash() const
PLDHashNumber Hash() const
{
return HashGeneric(mLayersId, mPresShellId, mScrollId);
}

View File

@ -8,6 +8,7 @@
#include <map>
#include "gfxPrefs.h"
#include "FrameMetrics.h"
#include "nsDebug.h" // for NS_WARNING
#include "mozilla/Assertions.h" // for MOZ_ASSERT
@ -85,6 +86,7 @@ private:
ViewID aScrollId,
const std::string& aKey,
const std::string& aValue) {
MOZ_ASSERT(gfxPrefs::APZTestLoggingEnabled(), "don't call me");
auto bucketIterator = aDataStore.find(aSequenceNumber);
if (bucketIterator == aDataStore.end()) {
MOZ_ASSERT(false, "LogTestDataImpl called with nonexistent sequence number");

View File

@ -9,6 +9,7 @@
#include <stdint.h> // for int32_t
#include "Layers.h"
#include "gfxContext.h" // for gfxContext
#include "gfxPrefs.h"
#include "mozilla/Attributes.h" // for override
#include "mozilla/LinkedList.h" // For LinkedList
#include "mozilla/WidgetUtils.h" // for ScreenRotation
@ -207,6 +208,7 @@ public:
const std::string& aKey,
const std::string& aValue)
{
MOZ_ASSERT(gfxPrefs::APZTestLoggingEnabled(), "don't call me");
mApzTestData.LogTestDataForPaint(mPaintSequenceNumber, aScrollId, aKey, aValue);
}
@ -223,6 +225,7 @@ public:
const std::string& aKey,
const std::string& aValue)
{
MOZ_ASSERT(gfxPrefs::APZTestLoggingEnabled(), "don't call me");
mApzTestData.LogTestDataForRepaintRequest(aSequenceNumber, aScrollId, aKey, aValue);
}

View File

@ -35,9 +35,7 @@
#include "TextRenderer.h" // for TextRenderer
#include <vector>
#include "GeckoProfiler.h" // for GeckoProfiler
#ifdef MOZ_GECKO_PROFILER
#include "ProfilerMarkerPayload.h" // for LayerTranslationMarkerPayload
#endif
#define CULLING_LOG(...)
// #define CULLING_LOG(...) printf_stderr("CULLING: " __VA_ARGS__)
@ -83,7 +81,6 @@ DrawLayerInfo(const RenderTargetIntRect& aClipRect,
static void
PrintUniformityInfo(Layer* aLayer)
{
#ifdef MOZ_GECKO_PROFILER
if (!profiler_is_active()) {
return;
}
@ -102,8 +99,8 @@ PrintUniformityInfo(Layer* aLayer)
Point translation = transform.As2D().GetTranslation();
profiler_add_marker(
"LayerTranslation",
MakeUnique<LayerTranslationMarkerPayload>(aLayer, translation));
#endif
MakeUnique<LayerTranslationMarkerPayload>(aLayer, translation,
TimeStamp::Now()));
}
static Maybe<gfx::Polygon>

View File

@ -83,9 +83,7 @@
#include "mozilla/HalTypes.h"
#include "mozilla/StaticPtr.h"
#include "mozilla/Telemetry.h"
#ifdef MOZ_GECKO_PROFILER
#include "ProfilerMarkerPayload.h"
#endif
#include "mozilla/VsyncDispatcher.h"
#if defined(XP_WIN) || defined(MOZ_WIDGET_GTK)
#include "VsyncSource.h"
@ -1844,12 +1842,10 @@ CompositorBridgeParent::GetAPZCTreeManager(uint64_t aLayersId)
static void
InsertVsyncProfilerMarker(TimeStamp aVsyncTimestamp)
{
#ifdef MOZ_GECKO_PROFILER
MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread());
profiler_add_marker(
"VsyncTimestamp",
MakeUnique<VsyncMarkerPayload>(aVsyncTimestamp));
#endif
}
/*static */ void

View File

@ -6,6 +6,7 @@
#ifndef GFX_WEBRENDERLAYERMANAGER_H
#define GFX_WEBRENDERLAYERMANAGER_H
#include "gfxPrefs.h"
#include "Layers.h"
#include "mozilla/MozPromise.h"
#include "mozilla/layers/APZTestData.h"
@ -161,6 +162,7 @@ public:
void LogTestDataForCurrentPaint(FrameMetrics::ViewID aScrollId,
const std::string& aKey,
const std::string& aValue) {
MOZ_ASSERT(gfxPrefs::APZTestLoggingEnabled(), "don't call me");
mApzTestData.LogTestDataForPaint(mPaintSequenceNumber, aScrollId, aKey, aValue);
}
// See equivalent function in ClientLayerManager

View File

@ -6,9 +6,7 @@
#include "ContextStateTracker.h"
#include "GLContext.h"
#include "GeckoProfiler.h"
#ifdef MOZ_GECKO_PROFILER
#include "ProfilerMarkerPayload.h"
#endif
namespace mozilla {
@ -111,13 +109,13 @@ ContextStateTrackerOGL::Flush(GLContext* aGL)
aGL->fDeleteQueries(1, &handle);
#ifdef MOZ_GECKO_PROFILER
profiler_add_marker(
"gpu_timer_query",
MakeUnique<GPUMarkerPayload>(mCompletedSections[0].mCpuTimeStart,
mCompletedSections[0].mCpuTimeEnd,
0, gpuTime));
#endif
if (profiler_is_active()) {
profiler_add_marker(
"gpu_timer_query",
MakeUnique<GPUMarkerPayload>(mCompletedSections[0].mCpuTimeStart,
mCompletedSections[0].mCpuTimeEnd,
0, gpuTime));
}
mCompletedSections.RemoveElementAt(0);
}

View File

@ -698,9 +698,9 @@ gfxFontEntry::GrReleaseTable(const void *aAppFaceHandle,
{
gfxFontEntry *fontEntry =
static_cast<gfxFontEntry*>(const_cast<void*>(aAppFaceHandle));
if (auto entry = fontEntry->mGrTableMap->Lookup(aTableBuffer)) {
hb_blob_destroy(static_cast<hb_blob_t*>(entry.Data()));
entry.Remove();
void* value;
if (fontEntry->mGrTableMap->Remove(aTableBuffer, &value)) {
hb_blob_destroy(static_cast<hb_blob_t*>(value));
}
}

View File

@ -239,7 +239,11 @@ RenderThread::UpdateAndRender(wr::WindowId aWindowId)
TimeStamp start = TimeStamp::Now();
renderer->Render();
bool ret = renderer->Render();
if (!ret) {
// Render did not happen, do not call NotifyDidRender.
return;
}
TimeStamp end = TimeStamp::Now();

View File

@ -105,6 +105,8 @@ RendererOGL::Render()
{
if (!mGL->MakeCurrent()) {
gfxCriticalNote << "Failed to make render context current, can't draw.";
// XXX This could cause oom in webrender since pending_texture_updates is not handled.
// It needs to be addressed.
return false;
}
@ -118,6 +120,8 @@ RendererOGL::Render()
#endif
if (!mWidget->PreRender(&widgetContext)) {
// XXX This could cause oom in webrender since pending_texture_updates is not handled.
// It needs to be addressed.
return false;
}
// XXX set clear color if MOZ_WIDGET_ANDROID is defined.

View File

@ -128,7 +128,7 @@ ImageCacheKey::Spec() const
return mURI->Spec();
}
/* static */ uint32_t
/* static */ PLDHashNumber
ImageCacheKey::ComputeHash(ImageURL* aURI,
const Maybe<uint64_t>& aBlobSerial,
const OriginAttributes& aAttrs,

View File

@ -42,7 +42,7 @@ public:
ImageCacheKey(ImageCacheKey&& aOther);
bool operator==(const ImageCacheKey& aOther) const;
uint32_t Hash() const { return mHash; }
PLDHashNumber Hash() const { return mHash; }
/// A weak pointer to the URI spec for this cache entry. For logging only.
const char* Spec() const;
@ -55,17 +55,17 @@ public:
void* ControlledDocument() const { return mControlledDocument; }
private:
static uint32_t ComputeHash(ImageURL* aURI,
const Maybe<uint64_t>& aBlobSerial,
const OriginAttributes& aAttrs,
void* aControlledDocument);
static PLDHashNumber ComputeHash(ImageURL* aURI,
const Maybe<uint64_t>& aBlobSerial,
const OriginAttributes& aAttrs,
void* aControlledDocument);
static void* GetControlledDocumentToken(nsIDocument* aDocument);
RefPtr<ImageURL> mURI;
Maybe<uint64_t> mBlobSerial;
OriginAttributes mOriginAttributes;
void* mControlledDocument;
uint32_t mHash;
PLDHashNumber mHash;
bool mIsChrome;
};

View File

@ -118,7 +118,7 @@ public:
private:
friend class ImageCacheKey;
uint32_t ComputeHash(const Maybe<uint64_t>& aBlobSerial) const
PLDHashNumber ComputeHash(const Maybe<uint64_t>& aBlobSerial) const
{
if (aBlobSerial) {
// For blob URIs, we hash the serial number of the underlying blob, so that

View File

@ -471,11 +471,7 @@ ProgressTracker::RemoveObserver(IProgressObserver* aObserver)
// Remove the observer from the list.
bool removed = mObservers.Write([=](ObserverTable* aTable) {
if (auto entry = aTable->Lookup(observer)) {
entry.Remove();
return true;
}
return false;
return aTable->Remove(observer);
});
// Observers can get confused if they don't get all the proper teardown

View File

@ -60,9 +60,9 @@ public:
aOther.mFlags == mFlags;
}
uint32_t Hash() const
PLDHashNumber Hash() const
{
uint32_t hash = HashGeneric(mSize.width, mSize.height);
PLDHashNumber hash = HashGeneric(mSize.width, mSize.height);
hash = AddToHash(hash, mSVGContext.map(HashSIC).valueOr(0));
hash = AddToHash(hash, uint8_t(mPlayback), uint32_t(mFlags));
return hash;
@ -84,7 +84,7 @@ private:
, mFlags(aFlags)
{ }
static uint32_t HashSIC(const SVGImageContext& aSIC) {
static PLDHashNumber HashSIC(const SVGImageContext& aSIC) {
return aSIC.Hash();
}

View File

@ -176,7 +176,7 @@ sub genTest {
<meta http-equiv="Content-type" content="text/html; charset=utf-8">
<style type="text/css">
\@font-face { font-family: foo; src: url($testFont); }
p { font-family: foo; text-transform: ${whichMapping}case; }
p { font-family: foo; font-size: 12px; text-transform: ${whichMapping}case; }
</style>
</head>
<body>
@ -202,7 +202,7 @@ __END__
<meta http-equiv="Content-type" content="text/html; charset=utf-8">
<style type="text/css">
\@font-face { font-family: foo; src: url($testFont); }
p { font-family: foo; }
p { font-family: foo; font-size: 12px; }
</style>
</head>
<body>

View File

@ -9,8 +9,8 @@
#include "mozilla/ArrayUtils.h" // for ArrayLength
#include <stdlib.h> // for bsearch
/* SpecialCasing-8.0.0.txt */
/* Date: 2014-12-16, 23:08:04 GMT [MD] */
/* SpecialCasing-10.0.0.txt */
/* Date: 2017-04-14, 05:40:43 GMT */
using mozilla::unicode::MultiCharMapping;

View File

@ -106,11 +106,6 @@ js::Nursery::Nursery(JSRuntime* rt)
, previousPromotionRate_(0)
, profileThreshold_(0)
, enableProfiling_(false)
#ifdef MOZ_GECKO_PROFILER
, trackTimings_(true)
#else
, trackTimings_(false)
#endif
, reportTenurings_(0)
, minorGCTriggerReason_(JS::gcreason::NO_REASON)
, minorGcCount_(0)
@ -153,7 +148,6 @@ js::Nursery::init(uint32_t maxNurseryBytes, AutoLockGC& lock)
exit(0);
}
enableProfiling_ = true;
trackTimings_ = true;
profileThreshold_ = TimeDuration::FromMicroseconds(atoi(env));
}
@ -491,12 +485,8 @@ FOR_EACH_NURSERY_PROFILE_TIME(EXTRACT_NAME)
"" };
size_t i = 0;
if (trackTimings_) {
for (auto time : profileDurations_)
json.property(names[i++], time, json.MICROSECONDS);
} else {
json.property(names[0], *profileDurations_.begin(), json.MICROSECONDS);
}
for (auto time : profileDurations_)
json.property(names[i++], time, json.MICROSECONDS);
json.endObject();
}
@ -532,10 +522,8 @@ js::Nursery::printTotalProfileTimes()
void
js::Nursery::maybeClearProfileDurations()
{
if (trackTimings_) {
for (auto& duration : profileDurations_)
duration = mozilla::TimeDuration();
}
for (auto& duration : profileDurations_)
duration = mozilla::TimeDuration();
}
inline void
@ -551,20 +539,6 @@ js::Nursery::endProfile(ProfileKey key)
totalDurations_[key] += profileDurations_[key];
}
inline void
js::Nursery::maybeStartProfile(ProfileKey key)
{
if (trackTimings_)
startProfile(key);
}
inline void
js::Nursery::maybeEndProfile(ProfileKey key)
{
if (trackTimings_)
endProfile(key);
}
void
js::Nursery::collect(JS::gcreason::Reason reason)
{
@ -608,15 +582,15 @@ js::Nursery::collect(JS::gcreason::Reason reason)
promotionRate = doCollection(reason, tenureCounts);
// Resize the nursery.
maybeStartProfile(ProfileKey::Resize);
startProfile(ProfileKey::Resize);
maybeResizeNursery(reason, promotionRate);
maybeEndProfile(ProfileKey::Resize);
endProfile(ProfileKey::Resize);
// If we are promoting the nursery, or exhausted the store buffer with
// pointers to nursery things, which will force a collection well before
// the nursery is full, look for object groups that are getting promoted
// excessively and try to pretenure them.
maybeStartProfile(ProfileKey::Pretenure);
startProfile(ProfileKey::Pretenure);
uint32_t pretenureCount = 0;
if (promotionRate > 0.8 || reason == JS::gcreason::FULL_STORE_BUFFER) {
JSContext* cx = TlsContext.get();
@ -631,7 +605,7 @@ js::Nursery::collect(JS::gcreason::Reason reason)
}
}
}
maybeEndProfile(ProfileKey::Pretenure);
endProfile(ProfileKey::Pretenure);
// We ignore gcMaxBytes when allocating for minor collection. However, if we
// overflowed, we disable the nursery. The next time we allocate, we'll fail
@ -694,90 +668,90 @@ js::Nursery::doCollection(JS::gcreason::Reason reason,
// The MIR graph only contains nursery pointers if cancelIonCompilations()
// is set on the store buffer, in which case we cancel all compilations.
maybeStartProfile(ProfileKey::CancelIonCompilations);
startProfile(ProfileKey::CancelIonCompilations);
if (sb.cancelIonCompilations())
js::CancelOffThreadIonCompile(rt);
maybeEndProfile(ProfileKey::CancelIonCompilations);
endProfile(ProfileKey::CancelIonCompilations);
maybeStartProfile(ProfileKey::TraceValues);
startProfile(ProfileKey::TraceValues);
sb.traceValues(mover);
maybeEndProfile(ProfileKey::TraceValues);
endProfile(ProfileKey::TraceValues);
maybeStartProfile(ProfileKey::TraceCells);
startProfile(ProfileKey::TraceCells);
sb.traceCells(mover);
maybeEndProfile(ProfileKey::TraceCells);
endProfile(ProfileKey::TraceCells);
maybeStartProfile(ProfileKey::TraceSlots);
startProfile(ProfileKey::TraceSlots);
sb.traceSlots(mover);
maybeEndProfile(ProfileKey::TraceSlots);
endProfile(ProfileKey::TraceSlots);
maybeStartProfile(ProfileKey::TraceWholeCells);
startProfile(ProfileKey::TraceWholeCells);
sb.traceWholeCells(mover);
maybeEndProfile(ProfileKey::TraceWholeCells);
endProfile(ProfileKey::TraceWholeCells);
maybeStartProfile(ProfileKey::TraceGenericEntries);
startProfile(ProfileKey::TraceGenericEntries);
sb.traceGenericEntries(&mover);
maybeEndProfile(ProfileKey::TraceGenericEntries);
endProfile(ProfileKey::TraceGenericEntries);
maybeStartProfile(ProfileKey::MarkRuntime);
startProfile(ProfileKey::MarkRuntime);
rt->gc.traceRuntimeForMinorGC(&mover, session.lock);
maybeEndProfile(ProfileKey::MarkRuntime);
endProfile(ProfileKey::MarkRuntime);
maybeStartProfile(ProfileKey::MarkDebugger);
startProfile(ProfileKey::MarkDebugger);
{
gcstats::AutoPhase ap(rt->gc.stats(), gcstats::PhaseKind::MARK_ROOTS);
Debugger::traceAllForMovingGC(&mover);
}
maybeEndProfile(ProfileKey::MarkDebugger);
endProfile(ProfileKey::MarkDebugger);
maybeStartProfile(ProfileKey::ClearNewObjectCache);
startProfile(ProfileKey::ClearNewObjectCache);
rt->caches().newObjectCache.clearNurseryObjects(rt);
maybeEndProfile(ProfileKey::ClearNewObjectCache);
endProfile(ProfileKey::ClearNewObjectCache);
// Most of the work is done here. This loop iterates over objects that have
// been moved to the major heap. If these objects have any outgoing pointers
// to the nursery, then those nursery objects get moved as well, until no
// objects are left to move. That is, we iterate to a fixed point.
maybeStartProfile(ProfileKey::CollectToFP);
startProfile(ProfileKey::CollectToFP);
collectToFixedPoint(mover, tenureCounts);
maybeEndProfile(ProfileKey::CollectToFP);
endProfile(ProfileKey::CollectToFP);
// Sweep compartments to update the array buffer object's view lists.
maybeStartProfile(ProfileKey::SweepArrayBufferViewList);
startProfile(ProfileKey::SweepArrayBufferViewList);
for (CompartmentsIter c(rt, SkipAtoms); !c.done(); c.next())
c->sweepAfterMinorGC(&mover);
maybeEndProfile(ProfileKey::SweepArrayBufferViewList);
endProfile(ProfileKey::SweepArrayBufferViewList);
// Update any slot or element pointers whose destination has been tenured.
maybeStartProfile(ProfileKey::UpdateJitActivations);
startProfile(ProfileKey::UpdateJitActivations);
js::jit::UpdateJitActivationsForMinorGC(rt, &mover);
forwardedBuffers.finish();
maybeEndProfile(ProfileKey::UpdateJitActivations);
endProfile(ProfileKey::UpdateJitActivations);
maybeStartProfile(ProfileKey::ObjectsTenuredCallback);
startProfile(ProfileKey::ObjectsTenuredCallback);
rt->gc.callObjectsTenuredCallback();
maybeEndProfile(ProfileKey::ObjectsTenuredCallback);
endProfile(ProfileKey::ObjectsTenuredCallback);
// Sweep.
maybeStartProfile(ProfileKey::FreeMallocedBuffers);
startProfile(ProfileKey::FreeMallocedBuffers);
freeMallocedBuffers();
maybeEndProfile(ProfileKey::FreeMallocedBuffers);
endProfile(ProfileKey::FreeMallocedBuffers);
maybeStartProfile(ProfileKey::Sweep);
startProfile(ProfileKey::Sweep);
sweep();
maybeEndProfile(ProfileKey::Sweep);
endProfile(ProfileKey::Sweep);
maybeStartProfile(ProfileKey::ClearStoreBuffer);
startProfile(ProfileKey::ClearStoreBuffer);
runtime()->gc.storeBuffer().clear();
maybeEndProfile(ProfileKey::ClearStoreBuffer);
endProfile(ProfileKey::ClearStoreBuffer);
// Make sure hashtables have been updated after the collection.
maybeStartProfile(ProfileKey::CheckHashTables);
startProfile(ProfileKey::CheckHashTables);
#ifdef JS_GC_ZEAL
if (rt->hasZealMode(ZealMode::CheckHashTablesOnMinorGC))
CheckHashTablesAfterMovingGC(rt);
#endif
maybeEndProfile(ProfileKey::CheckHashTables);
endProfile(ProfileKey::CheckHashTables);
// Calculate and return the promotion rate.
return mover.tenuredSize / double(initialNurserySize);

View File

@ -276,7 +276,6 @@ class Nursery
void clearMinorGCRequest() { minorGCTriggerReason_ = JS::gcreason::NO_REASON; }
bool enableProfiling() const { return enableProfiling_; }
bool trackTimings() const { return trackTimings_; }
private:
/* The amount of space in the mapped nursery available to allocations. */
@ -323,12 +322,6 @@ class Nursery
mozilla::TimeDuration profileThreshold_;
bool enableProfiling_;
/*
* Track timings if either enableProfiling_ or the Gecko profiler is
* compiled in.
*/
bool trackTimings_;
/* Report ObjectGroups with at lest this many instances tenured. */
int64_t reportTenurings_;
@ -476,8 +469,6 @@ class Nursery
void maybeClearProfileDurations();
void startProfile(ProfileKey key);
void endProfile(ProfileKey key);
void maybeStartProfile(ProfileKey key);
void maybeEndProfile(ProfileKey key);
static void printProfileDurations(const ProfileDurations& times);
friend class TenuringTracer;

View File

@ -179,7 +179,7 @@ Zone::sweepWeakMaps()
}
void
Zone::discardJitCode(FreeOp* fop, bool discardBaselineCode, bool addMarkers)
Zone::discardJitCode(FreeOp* fop, bool discardBaselineCode)
{
if (!jitZone())
return;
@ -202,7 +202,7 @@ Zone::discardJitCode(FreeOp* fop, bool discardBaselineCode, bool addMarkers)
jit::InvalidateAll(fop, this);
for (auto script = cellIter<JSScript>(); !script.done(); script.next()) {
jit::FinishInvalidation(fop, script, addMarkers);
jit::FinishInvalidation(fop, script);
/*
* Discard baseline script if it's not marked as active. Note that

View File

@ -174,7 +174,7 @@ struct Zone : public JS::shadow::Zone,
void findOutgoingEdges(js::gc::ZoneComponentFinder& finder);
void discardJitCode(js::FreeOp* fop, bool discardBaselineCode = true, bool addMarkers = true);
void discardJitCode(js::FreeOp* fop, bool discardBaselineCode = true);
void addSizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf,
size_t* typePool,

View File

@ -0,0 +1,41 @@
m = {
i() {},
n() {},
d() {},
n() {},
n() {},
n() {},
s() {}
};
function c()
function ()
function ()
function ()
function ()[{
f() {}
}, {
v() {}
}, {
n() {}
}, {
v() {}
}, {
f() {}
}, {
n() {}
}, {
n() {}
}, {
n() {}
}, {
n() {}
}, {
v() {}
}, {
n() {}
}, {
n() {}
}];
t = function () {};
getLcovInfo();
relazifyFunctions();

View File

@ -0,0 +1,34 @@
function f(y) {
return Math.min(0, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8,
9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7,
9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7,
9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7,
9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7,
8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6,
8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6,
8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6,
8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6,
8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6,
8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6,
8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6,
8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6,
8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6,
8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6,
8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6,
7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5,
6, 7, 8, 9);
}
function g() {
return f({});
}
x = 0
for (var j = 0; j < 3000; j++) {
g([j]);
if (inIon())
break;
}

View File

@ -519,29 +519,6 @@ jit::FinishOffThreadBuilder(JSRuntime* runtime, IonBuilder* builder,
FreeIonBuilder(builder);
}
static void
MarkJitProfilerEvent(JSRuntime* rt, JSScript* script, const char* event)
{
if (rt->geckoProfiler().enabled()) {
// Register event with profiler.
// Format of event payload string:
// "<filename>:<lineno>"
// Get the script filename, if any, and its length.
const char* filename = script->filename();
if (filename == nullptr)
filename = "<unknown>";
// Construct the descriptive string.
UniqueChars buf = JS_smprintf("Invalidate %s:%" PRIuSIZE, filename, script->lineno());
// Ignore the event on allocation failure.
if (buf) {
rt->geckoProfiler().markEvent(buf.get());
}
}
}
static bool
LinkCodeGen(JSContext* cx, IonBuilder* builder, CodeGenerator *codegen)
{
@ -554,8 +531,6 @@ LinkCodeGen(JSContext* cx, IonBuilder* builder, CodeGenerator *codegen)
if (!codegen->link(cx, builder->constraints()))
return false;
MarkJitProfilerEvent(cx->runtime(), script, "Ion compilation finished");
return true;
}
@ -3184,8 +3159,6 @@ jit::Invalidate(TypeZone& types, FreeOp* fop,
JitSpew(JitSpew_IonInvalidate, " Invalidate %s:%" PRIuSIZE ", IonScript %p",
co->script()->filename(), co->script()->lineno(), co->ion());
MarkJitProfilerEvent(fop->runtime(), co->script(), "Invalidate");
// Keep the ion script alive during the invalidation and flag this
// ionScript as being invalidated. This increment is removed by the
// loop after the calls to InvalidateActivation.
@ -3266,6 +3239,25 @@ jit::Invalidate(JSContext* cx, JSScript* script, bool resetUses, bool cancelOffT
{
MOZ_ASSERT(script->hasIonScript());
if (cx->runtime()->geckoProfiler().enabled()) {
// Register invalidation with profiler.
// Format of event payload string:
// "<filename>:<lineno>"
// Get the script filename, if any, and its length.
const char* filename = script->filename();
if (filename == nullptr)
filename = "<unknown>";
// Construct the descriptive string.
UniqueChars buf = JS_smprintf("Invalidate %s:%" PRIuSIZE, filename, script->lineno());
// Ignore the event on allocation failure.
if (buf) {
cx->runtime()->geckoProfiler().markEvent(buf.get());
}
}
// RecompileInfoVector has inline space for at least one element.
RecompileInfoVector scripts;
MOZ_ASSERT(script->hasIonScript());
@ -3276,7 +3268,7 @@ jit::Invalidate(JSContext* cx, JSScript* script, bool resetUses, bool cancelOffT
}
static void
FinishInvalidationOf(FreeOp* fop, JSScript* script, IonScript* ionScript, bool addMarker)
FinishInvalidationOf(FreeOp* fop, JSScript* script, IonScript* ionScript)
{
TypeZone& types = script->zone()->types;
@ -3289,20 +3281,16 @@ FinishInvalidationOf(FreeOp* fop, JSScript* script, IonScript* ionScript, bool a
// true. In this case we have to wait until destroying it.
if (!ionScript->invalidated())
jit::IonScript::Destroy(fop, ionScript);
// Register invalidation with profiler, if appropriate.
if (addMarker)
MarkJitProfilerEvent(fop->runtime(), script, "Invalidate (GC)");
}
void
jit::FinishInvalidation(FreeOp* fop, JSScript* script, bool addMarker)
jit::FinishInvalidation(FreeOp* fop, JSScript* script)
{
// In all cases, nullptr out script->ion to avoid re-entry.
if (script->hasIonScript()) {
IonScript* ion = script->ionScript();
script->setIonScript(nullptr, nullptr);
FinishInvalidationOf(fop, script, ion, addMarker);
FinishInvalidationOf(fop, script, ion);
}
}
@ -3318,8 +3306,6 @@ jit::ForbidCompilation(JSContext* cx, JSScript* script)
Invalidate(cx, script, false);
script->setIonScript(cx->runtime(), ION_DISABLED_SCRIPT);
MarkJitProfilerEvent(cx->runtime(), script, "Ion compilation disabled");
}
AutoFlushICache*

View File

@ -628,7 +628,7 @@ class JitCompartment
// Called from JSCompartment::discardJitCode().
void InvalidateAll(FreeOp* fop, JS::Zone* zone);
void FinishInvalidation(FreeOp* fop, JSScript* script, bool addMarker);
void FinishInvalidation(FreeOp* fop, JSScript* script);
// On windows systems, really large frames need to be incrementally touched.
// The following constant defines the minimum increment of the touch.

View File

@ -1471,7 +1471,9 @@ IonBuilder::inlineMathMinMax(CallInfo& callInfo, bool max)
current->add(last);
for (unsigned i = 2; i < cases.length(); i++) {
MMinMax* ins = MMinMax::New(alloc(), last, cases[i], returnType, max);
MMinMax* ins = MMinMax::New(alloc().fallible(), last, cases[i], returnType, max);
if (!ins)
return abort(AbortReason::Alloc);
current->add(ins);
last = ins;
}

View File

@ -85,6 +85,7 @@ JSCompartment::JSCompartment(Zone* zone, const JS::CompartmentOptions& options =
randomKeyGenerator_(runtime_->forkRandomKeyGenerator()),
watchpointMap(nullptr),
scriptCountsMap(nullptr),
scriptNameMap(nullptr),
debugScriptMap(nullptr),
debugEnvs(nullptr),
enumerators(nullptr),
@ -115,6 +116,7 @@ JSCompartment::~JSCompartment()
js_delete(jitCompartment_);
js_delete(watchpointMap);
js_delete(scriptCountsMap);
js_delete(scriptNameMap);
js_delete(debugScriptMap);
js_delete(debugEnvs);
js_delete(objectMetadataTable);
@ -810,6 +812,7 @@ JSCompartment::finishRoots()
objectMetadataTable->clear();
clearScriptCounts();
clearScriptNames();
if (nonSyntacticLexicalEnvironments_)
nonSyntacticLexicalEnvironments_->clear();
@ -1008,6 +1011,14 @@ JSCompartment::fixupScriptMapsAfterMovingGC()
}
}
if (scriptNameMap) {
for (ScriptNameMap::Enum e(*scriptNameMap); !e.empty(); e.popFront()) {
JSScript* script = e.front().key();
if (!IsAboutToBeFinalizedUnbarriered(&script) && script != e.front().key())
e.rekeyFront(script);
}
}
if (debugScriptMap) {
for (DebugScriptMap::Enum e(*debugScriptMap); !e.empty(); e.popFront()) {
JSScript* script = e.front().key();
@ -1030,6 +1041,15 @@ JSCompartment::checkScriptMapsAfterMovingGC()
}
}
if (scriptNameMap) {
for (auto r = scriptNameMap->all(); !r.empty(); r.popFront()) {
JSScript* script = r.front().key();
CheckGCThingAfterMovingGC(script);
auto ptr = scriptNameMap->lookup(script);
MOZ_RELEASE_ASSERT(ptr.found() && &*ptr == &r.front());
}
}
if (debugScriptMap) {
for (auto r = debugScriptMap->all(); !r.empty(); r.popFront()) {
JSScript* script = r.front().key();
@ -1274,6 +1294,7 @@ JSCompartment::updateDebuggerObservesCoverage()
return;
clearScriptCounts();
clearScriptNames();
}
bool
@ -1315,6 +1336,19 @@ JSCompartment::clearScriptCounts()
scriptCountsMap = nullptr;
}
void
JSCompartment::clearScriptNames()
{
if (!scriptNameMap)
return;
for (ScriptNameMap::Range r = scriptNameMap->all(); !r.empty(); r.popFront())
js_delete(r.front().value());
js_delete(scriptNameMap);
scriptNameMap = nullptr;
}
void
JSCompartment::clearBreakpointsIn(FreeOp* fop, js::Debugger* dbg, HandleObject handler)
{

View File

@ -1090,6 +1090,7 @@ struct JSCompartment
bool collectCoverageForDebug() const;
bool collectCoverageForPGO() const;
void clearScriptCounts();
void clearScriptNames();
bool needsDelazificationForDebugger() const {
return debugModeBits & DebuggerNeedsDelazification;
@ -1116,6 +1117,7 @@ struct JSCompartment
js::WatchpointMap* watchpointMap;
js::ScriptCountsMap* scriptCountsMap;
js::ScriptNameMap* scriptNameMap;
js::DebugScriptMap* debugScriptMap;

View File

@ -7315,6 +7315,30 @@ gc::MergeCompartments(JSCompartment* source, JSCompartment* target)
// Atoms which are marked in source's zone are now marked in target's zone.
cx->atomMarking().adoptMarkedAtoms(target->zone(), source->zone());
// Merge script name maps in the target compartment's map.
if (cx->runtime()->lcovOutput().isEnabled() && source->scriptNameMap) {
AutoEnterOOMUnsafeRegion oomUnsafe;
if (!target->scriptNameMap) {
target->scriptNameMap = cx->new_<ScriptNameMap>();
if (!target->scriptNameMap)
oomUnsafe.crash("Failed to create a script name map.");
if (!target->scriptNameMap->init())
oomUnsafe.crash("Failed to initialize a script name map.");
}
for (ScriptNameMap::Range r = source->scriptNameMap->all(); !r.empty(); r.popFront()) {
JSScript* key = r.front().key();
const char* value = r.front().value();
if (!target->scriptNameMap->putNew(key, value))
oomUnsafe.crash("Failed to add an entry in the script name map.");
}
source->scriptNameMap->clear();
}
}
void
@ -7416,14 +7440,14 @@ void PreventGCDuringInteractiveDebug()
#endif
void
js::ReleaseAllJITCode(FreeOp* fop, bool addMarkers)
js::ReleaseAllJITCode(FreeOp* fop)
{
js::CancelOffThreadIonCompile(fop->runtime());
JSRuntime::AutoProhibitActiveContextChange apacc(fop->runtime());
for (ZonesIter zone(fop->runtime(), SkipAtoms); !zone.done(); zone.next()) {
zone->setPreservingCode(false);
zone->discardJitCode(fop, /* discardBaselineCode = */ true, addMarkers);
zone->discardJitCode(fop);
}
}

View File

@ -837,7 +837,7 @@ extern void
TraceRuntime(JSTracer* trc);
extern void
ReleaseAllJITCode(FreeOp* op, bool addMarkers = true);
ReleaseAllJITCode(FreeOp* op);
extern void
PrepareForDebugGC(JSRuntime* rt);

View File

@ -2966,7 +2966,6 @@ GenerateLcovInfo(JSContext* cx, JSCompartment* comp, GenericPrinter& out)
coverage::LCovCompartment compCover;
for (JSScript* topLevel: topScripts) {
RootedScript topScript(cx, topLevel);
compCover.collectSourceFile(comp, &topScript->scriptSourceUnwrap());
// We found the top-level script, visit all the functions reachable
// from the top-level function, and delazify them.
@ -2978,7 +2977,18 @@ GenerateLcovInfo(JSContext* cx, JSCompartment* comp, GenericPrinter& out)
RootedFunction fun(cx);
do {
script = queue.popCopy();
compCover.collectCodeCoverageInfo(comp, script->sourceObject(), script);
bool createdScriptName = false;
if (!script->hasScriptName()) {
createdScriptName = true;
if (!script->initScriptName(cx))
return false;
}
compCover.collectCodeCoverageInfo(comp, script);
// Destroy the script name if we have created it in this function.
if (createdScriptName)
script->destroyScriptName();
// Iterate from the last to the first object in order to have
// the functions them visited in the opposite order when popping

View File

@ -1159,6 +1159,15 @@ static inline ScriptCountsMap::Ptr GetScriptCountsMapEntry(JSScript* script)
return p;
}
static inline ScriptNameMap::Ptr
GetScriptNameMapEntry(JSScript* script)
{
ScriptNameMap* map = script->compartment()->scriptNameMap;
auto p = map->lookup(script);
MOZ_ASSERT(p);
return p;
}
ScriptCounts&
JSScript::getScriptCounts()
{
@ -1166,6 +1175,13 @@ JSScript::getScriptCounts()
return *p->value();
}
const char*
JSScript::getScriptName()
{
auto p = GetScriptNameMapEntry(this);
return p->value();
}
js::PCCounts*
ScriptCounts::maybeGetPCCounts(size_t offset) {
PCCounts searched = PCCounts(offset);
@ -1347,6 +1363,24 @@ JSScript::destroyScriptCounts(FreeOp* fop)
}
}
void
JSScript::destroyScriptName()
{
auto p = GetScriptNameMapEntry(this);
js_delete(p->value());
compartment()->scriptNameMap->remove(p);
}
bool
JSScript::hasScriptName()
{
if (!compartment()->scriptNameMap)
return false;
auto p = compartment()->scriptNameMap->lookup(this);
return p.found();
}
void
ScriptSourceObject::trace(JSTracer* trc, JSObject* obj)
{
@ -1367,12 +1401,6 @@ ScriptSourceObject::finalize(FreeOp* fop, JSObject* obj)
{
MOZ_ASSERT(fop->onActiveCooperatingThread());
ScriptSourceObject* sso = &obj->as<ScriptSourceObject>();
// If code coverage is enabled, record the filename associated with this
// source object.
if (fop->runtime()->lcovOutput().isEnabled())
sso->compartment()->lcovOutput.collectSourceFile(sso->compartment(), sso);
sso->source()->decref();
sso->setReservedSlot(SOURCE_SLOT, PrivateValue(nullptr));
}
@ -2666,6 +2694,8 @@ JSScript::Create(JSContext* cx, const ReadOnlyCompileOptions& options,
MOZ_ASSERT(script->getVersion() == options.version); // assert that no overflow occurred
script->setSourceObject(sourceObject);
if (cx->runtime()->lcovOutput().isEnabled() && !script->initScriptName(cx))
return nullptr;
script->sourceStart_ = bufStart;
script->sourceEnd_ = bufEnd;
script->toStringStart_ = toStringStart;
@ -2678,6 +2708,48 @@ JSScript::Create(JSContext* cx, const ReadOnlyCompileOptions& options,
return script;
}
bool
JSScript::initScriptName(JSContext* cx)
{
MOZ_ASSERT(!hasScriptName());
if (!filename())
return true;
// Create compartment's scriptNameMap if necessary.
ScriptNameMap* map = compartment()->scriptNameMap;
if (!map) {
map = cx->new_<ScriptNameMap>();
if (!map) {
ReportOutOfMemory(cx);
return false;
}
if (!map->init()) {
js_delete(map);
ReportOutOfMemory(cx);
return false;
}
compartment()->scriptNameMap = map;
}
char* name = js_strdup(filename());
if (!name) {
ReportOutOfMemory(cx);
return false;
}
// Register the script name in the compartment's map.
if (!map->putNew(this, name)) {
js_delete(name);
ReportOutOfMemory(cx);
return false;
}
return true;
}
static inline uint8_t*
AllocScriptData(JS::Zone* zone, size_t size)
{
@ -3090,8 +3162,11 @@ JSScript::finalize(FreeOp* fop)
// Collect code coverage information for this script and all its inner
// scripts, and store the aggregated information on the compartment.
if (fop->runtime()->lcovOutput().isEnabled())
compartment()->lcovOutput.collectCodeCoverageInfo(compartment(), sourceObject(), this);
MOZ_ASSERT_IF(hasScriptName(), fop->runtime()->lcovOutput().isEnabled());
if (fop->runtime()->lcovOutput().isEnabled() && hasScriptName()) {
compartment()->lcovOutput.collectCodeCoverageInfo(compartment(), this);
destroyScriptName();
}
fop->runtime()->geckoProfiler().onScriptFinalized(this);

View File

@ -240,6 +240,10 @@ typedef HashMap<JSScript*,
ScriptCounts*,
DefaultHasher<JSScript*>,
SystemAllocPolicy> ScriptCountsMap;
typedef HashMap<JSScript*,
const char*,
DefaultHasher<JSScript*>,
SystemAllocPolicy> ScriptNameMap;
class DebugScript
{
@ -1419,6 +1423,7 @@ class JSScript : public js::gc::TenuredCell
void setIsDefaultClassConstructor() { isDefaultClassConstructor_ = true; }
bool hasScriptCounts() const { return hasScriptCounts_; }
bool hasScriptName();
bool hasFreezeConstraints() const { return hasFreezeConstraints_; }
void setHasFreezeConstraints() { hasFreezeConstraints_ = true; }
@ -1783,7 +1788,9 @@ class JSScript : public js::gc::TenuredCell
public:
bool initScriptCounts(JSContext* cx);
bool initScriptName(JSContext* cx);
js::ScriptCounts& getScriptCounts();
const char* getScriptName();
js::PCCounts* maybeGetPCCounts(jsbytecode* pc);
const js::PCCounts* maybeGetThrowCounts(jsbytecode* pc);
js::PCCounts* getThrowCounts(jsbytecode* pc);
@ -1793,6 +1800,7 @@ class JSScript : public js::gc::TenuredCell
js::jit::IonScriptCounts* getIonCounts();
void releaseScriptCounts(js::ScriptCounts* counts);
void destroyScriptCounts(js::FreeOp* fop);
void destroyScriptName();
// The entry should be removed after using this function.
void takeOverScriptCountsMapEntry(js::ScriptCounts* entryValue);

View File

@ -95,6 +95,9 @@ WrappedAsyncFunction(JSContext* cx, unsigned argc, Value* vp)
return true;
}
if (!cx->isExceptionPending())
return false;
// Steps 1, 4.
RootedValue exc(cx);
if (!GetAndClearException(cx, &exc))

View File

@ -63,9 +63,8 @@
namespace js {
namespace coverage {
LCovSource::LCovSource(LifoAlloc* alloc, JSObject* sso)
: source_(sso),
outSF_(alloc),
LCovSource::LCovSource(LifoAlloc* alloc, const char* name)
: name_(name),
outFN_(alloc),
outFNDA_(alloc),
numFunctionsFound_(0),
@ -76,19 +75,40 @@ LCovSource::LCovSource(LifoAlloc* alloc, JSObject* sso)
outDA_(alloc),
numLinesInstrumented_(0),
numLinesHit_(0),
hasFilename_(false),
hasTopLevelScript_(false)
{
}
LCovSource::LCovSource(LCovSource&& src)
: name_(src.name_),
outFN_(src.outFN_),
outFNDA_(src.outFNDA_),
numFunctionsFound_(src.numFunctionsFound_),
numFunctionsHit_(src.numFunctionsHit_),
outBRDA_(src.outBRDA_),
numBranchesFound_(src.numBranchesFound_),
numBranchesHit_(src.numBranchesHit_),
outDA_(src.outDA_),
numLinesInstrumented_(src.numLinesInstrumented_),
numLinesHit_(src.numLinesHit_),
hasTopLevelScript_(src.hasTopLevelScript_)
{
src.name_ = nullptr;
}
LCovSource::~LCovSource()
{
js_delete(name_);
}
void
LCovSource::exportInto(GenericPrinter& out) const
{
// Only write if everything got recorded.
if (!hasFilename_ || !hasTopLevelScript_)
if (!hasTopLevelScript_)
return;
outSF_.exportInto(out);
out.printf("SF:%s\n", name_);
outFN_.exportInto(out);
outFNDA_.exportInto(out);
@ -106,17 +126,6 @@ LCovSource::exportInto(GenericPrinter& out) const
out.put("end_of_record\n");
}
bool
LCovSource::writeSourceFilename(ScriptSourceObject* sso)
{
outSF_.printf("SF:%s\n", sso->source()->filename());
if (outSF_.hadOutOfMemory())
return false;
hasFilename_ = true;
return true;
}
bool
LCovSource::writeScriptName(LSprinter& out, JSScript* script)
{
@ -404,8 +413,7 @@ LCovCompartment::LCovCompartment()
}
void
LCovCompartment::collectCodeCoverageInfo(JSCompartment* comp, JSObject* sso,
JSScript* script)
LCovCompartment::collectCodeCoverageInfo(JSCompartment* comp, JSScript* script)
{
// Skip any operation if we already some out-of memory issues.
if (outTN_.hadOutOfMemory())
@ -415,7 +423,7 @@ LCovCompartment::collectCodeCoverageInfo(JSCompartment* comp, JSObject* sso,
return;
// Get the existing source LCov summary, or create a new one.
LCovSource* source = lookupOrAdd(comp, sso);
LCovSource* source = lookupOrAdd(comp, script->getScriptName());
if (!source)
return;
@ -426,31 +434,8 @@ LCovCompartment::collectCodeCoverageInfo(JSCompartment* comp, JSObject* sso,
}
}
void
LCovCompartment::collectSourceFile(JSCompartment* comp, ScriptSourceObject* sso)
{
// Do not add sources if there is no file name associated to it.
if (!sso->source()->filename())
return;
// Skip any operation if we already some out-of memory issues.
if (outTN_.hadOutOfMemory())
return;
// Get the existing source LCov summary, or create a new one.
LCovSource* source = lookupOrAdd(comp, sso);
if (!source)
return;
// Write source filename into the LCovSource.
if (!source->writeSourceFilename(sso)) {
outTN_.reportOutOfMemory();
return;
}
}
LCovSource*
LCovCompartment::lookupOrAdd(JSCompartment* comp, JSObject* sso)
LCovCompartment::lookupOrAdd(JSCompartment* comp, const char* name)
{
// On the first call, write the compartment name, and allocate a LCovSource
// vector in the LifoAlloc.
@ -468,13 +453,19 @@ LCovCompartment::lookupOrAdd(JSCompartment* comp, JSObject* sso)
} else {
// Find the first matching source.
for (LCovSource& source : *sources_) {
if (source.match(sso))
if (source.match(name))
return &source;
}
}
char* source_name = js_strdup(name);
if (!source_name) {
outTN_.reportOutOfMemory();
return nullptr;
}
// Allocate a new LCovSource for the current top-level.
if (!sources_->append(Move(LCovSource(&alloc_, sso)))) {
if (!sources_->append(Move(LCovSource(&alloc_, source_name)))) {
outTN_.reportOutOfMemory();
return nullptr;
}

View File

@ -28,16 +28,18 @@ class LCovCompartment;
class LCovSource
{
public:
explicit LCovSource(LifoAlloc* alloc, JSObject* sso);
LCovSource(LifoAlloc* alloc, const char* name);
LCovSource(LCovSource&& src);
~LCovSource();
// Whether the given script source object matches this LCovSource.
bool match(JSObject* sso) const {
return sso == source_;
// Whether the given script name matches this LCovSource.
bool match(const char* name) const {
return strcmp(name_, name) == 0;
}
// Whether the current source is complete and if it can be flushed.
bool isComplete() const {
return hasFilename_ && hasTopLevelScript_;
return hasTopLevelScript_;
}
// Iterate over the bytecode and collect the lcov output based on the
@ -48,19 +50,13 @@ class LCovSource
// the runtime code coverage trace file.
void exportInto(GenericPrinter& out) const;
// Write the script name in out.
bool writeSourceFilename(ScriptSourceObject* sso);
private:
// Write the script name in out.
bool writeScriptName(LSprinter& out, JSScript* script);
private:
// Weak pointer of the Script Source Object used by the current source.
JSObject *source_;
// LifoAlloc string which hold the filename of the source.
LSprinter outSF_;
// Name of the source file.
const char* name_;
// LifoAlloc strings which hold the filename of each function as
// well as the number of hits for each function.
@ -80,7 +76,6 @@ class LCovSource
size_t numLinesHit_;
// Status flags.
bool hasFilename_ : 1;
bool hasTopLevelScript_ : 1;
};
@ -90,10 +85,7 @@ class LCovCompartment
LCovCompartment();
// Collect code coverage information for the given source.
void collectCodeCoverageInfo(JSCompartment* comp, JSObject* sso, JSScript* topLevel);
// Create an ebtry for the current ScriptSourceObject.
void collectSourceFile(JSCompartment* comp, ScriptSourceObject* sso);
void collectCodeCoverageInfo(JSCompartment* comp, JSScript* topLevel);
// Write the Lcov output in a buffer, such as the one associated with
// the runtime code coverage trace file.
@ -104,7 +96,7 @@ class LCovCompartment
bool writeCompartmentName(JSCompartment* comp);
// Return the LCovSource entry which matches the given ScriptSourceObject.
LCovSource* lookupOrAdd(JSCompartment* comp, JSObject* sso);
LCovSource* lookupOrAdd(JSCompartment* comp, const char* name);
private:
typedef mozilla::Vector<LCovSource, 16, LifoAllocPolicy<Fallible>> LCovSourceVector;

View File

@ -99,12 +99,9 @@ GeckoProfiler::enable(bool enabled)
/*
* Ensure all future generated code will be instrumented, or that all
* currently instrumented code is discarded.
*
* We don't add markers, because that makes us call back into the profiler,
* which leads to deadlock on the profiler's main mutex.
* currently instrumented code is discarded
*/
ReleaseAllJITCode(rt->defaultFreeOp(), /* addMarkers = */ false);
ReleaseAllJITCode(rt->defaultFreeOp());
// This function is called when the Gecko profiler makes a new Sampler
// (and thus, a new circular buffer). Set all current entries in the

Some files were not shown because too many files have changed in this diff Show More