Merge mozilla-inbound to mozilla-central. a=merge

This commit is contained in:
Dorel Luca 2018-06-20 00:54:45 +03:00
Родитель 86ddf36acf e3c9a3fc67
Коммит e06ba10d0b
115 изменённых файлов: 4729 добавлений и 1069 удалений

Просмотреть файл

@ -107,7 +107,7 @@
is(anode, node.accessibleNode, "an AccessibleNode is properly cached");
// Adopting node to another document doesn't change .accessibleNode
anotherDoc = document.implementation.createDocument("", "", null);
let anotherDoc = document.implementation.createDocument("", "", null);
let adopted_node = anotherDoc.adoptNode(node);
is(anode, adopted_node.accessibleNode, "adopting node to another document doesn't change node.accessibleNode");

Просмотреть файл

@ -38,7 +38,6 @@ exports.ORDERED_PROPS = [
"value",
"DOMNode",
"description",
"help",
"keyboardShortcut",
"childCount",
"indexInParent",
@ -52,7 +51,6 @@ exports.ACCESSIBLE_EVENTS = [
"actions-change",
"attributes-change",
"description-change",
"help-change",
"name-change",
"reorder",
"shortcut-change",

Просмотреть файл

@ -4,6 +4,8 @@ subsuite = devtools
support-files =
head.js
!/devtools/client/shared/test/shared-head.js
!/devtools/client/shared/test/test-actor.js
!/devtools/client/shared/test/test-actor-registry.js
!/devtools/client/inspector/test/shared-head.js
!/devtools/client/shared/test/shared-redux-head.js
!/devtools/client/shared/test/telemetry-test-helpers.js

Просмотреть файл

@ -50,7 +50,6 @@ const tests = [{
actions: [],
value: "",
description: "",
help: "",
keyboardShortcut: "",
childCount: 1,
indexInParent: 1,

Просмотреть файл

@ -29,7 +29,6 @@ const tests = [{
actions: [],
value: "",
description: "",
help: "",
keyboardShortcut: "",
childCount: 0,
indexInParent: 0,

Просмотреть файл

@ -36,7 +36,6 @@ const tests = [{
actions: [],
value: "",
description: "",
help: "",
keyboardShortcut: "",
childCount: 2,
indexInParent: 0,
@ -81,7 +80,6 @@ const tests = [{
actions: [],
value: "",
description: "",
help: "",
keyboardShortcut: "",
childCount: 1,
indexInParent: 0,
@ -98,7 +96,6 @@ const tests = [{
actions: [],
value: "",
description: "",
help: "",
keyboardShortcut: "",
childCount: 0,
indexInParent: 0,
@ -119,7 +116,6 @@ const tests = [{
actions: [],
value: "",
description: "",
help: "",
keyboardShortcut: "",
childCount: 2,
indexInParent: 0,

Просмотреть файл

@ -54,6 +54,7 @@ const PORTRAIT_MODE_WIDTH_THRESHOLD = 700;
// mode.
const SIDE_PORTAIT_MODE_WIDTH_THRESHOLD = 1000;
const THREE_PANE_FIRST_RUN_PREF = "devtools.inspector.three-pane-first-run";
const SHOW_THREE_PANE_ONBOARDING_PREF = "devtools.inspector.show-three-pane-tooltip";
const THREE_PANE_ENABLED_PREF = "devtools.inspector.three-pane-enabled";
const THREE_PANE_ENABLED_SCALAR = "devtools.inspector.three_pane_enabled";
@ -120,6 +121,7 @@ function Inspector(toolbox) {
this.previousURL = this.target.url;
this.is3PaneModeEnabled = Services.prefs.getBoolPref(THREE_PANE_ENABLED_PREF);
this.is3PaneModeFirstRun = Services.prefs.getBoolPref(THREE_PANE_FIRST_RUN_PREF);
this.show3PaneTooltip = Services.prefs.getBoolPref(SHOW_THREE_PANE_ONBOARDING_PREF);
this.nodeMenuTriggerInfo = null;
@ -250,6 +252,14 @@ Inspector.prototype = {
this._updateDebuggerPausedWarning();
}
// Resets the inspector sidebar widths if this is the first run of the 3 pane mode.
if (this.is3PaneModeFirstRun) {
Services.prefs.clearUserPref("devtools.toolsidebar-width.inspector");
Services.prefs.clearUserPref("devtools.toolsidebar-height.inspector");
Services.prefs.clearUserPref("devtools.toolsidebar-width.inspector.splitsidebar");
Services.prefs.setBoolPref(THREE_PANE_FIRST_RUN_PREF, false);
}
this._initMarkup();
this.isReady = false;
@ -1396,6 +1406,7 @@ Inspector.prototype = {
this._toolbox = null;
this.breadcrumbs = null;
this.is3PaneModeEnabled = null;
this.is3PaneModeFirstRun = null;
this.panelDoc = null;
this.panelWin.inspector = null;
this.panelWin = null;

Просмотреть файл

@ -1,5 +1,3 @@
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
/* vim: set ts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
@ -8,31 +6,31 @@
const promise = require("promise");
const Rule = require("devtools/client/inspector/rules/models/rule");
const {promiseWarn} = require("devtools/client/inspector/shared/utils");
const {ELEMENT_STYLE} = require("devtools/shared/specs/styles");
const {getCssProperties, isCssVariable} = require("devtools/shared/fronts/css-properties");
const UserProperties = require("devtools/client/inspector/rules/models/user-properties");
const { promiseWarn } = require("devtools/client/inspector/shared/utils");
const { getCssProperties, isCssVariable } = require("devtools/shared/fronts/css-properties");
const { ELEMENT_STYLE } = require("devtools/shared/specs/styles");
/**
* ElementStyle is responsible for the following:
* Keeps track of which properties are overridden.
* Maintains a list of Rule objects for a given element.
*
* @param {Element} element
* The element whose style we are viewing.
* @param {CssRuleView} ruleView
* The instance of the rule-view panel.
* @param {Object} store
* The ElementStyle can use this object to store metadata
* that might outlast the rule view, particularly the current
* set of disabled properties.
* @param {PageStyleFront} pageStyle
* Front for the page style actor that will be providing
* the style information.
* @param {Boolean} showUserAgentStyles
* Should user agent styles be inspected?
* @param {Element} element
* The element whose style we are viewing.
* @param {CssRuleView} ruleView
* The instance of the rule-view panel.
* @param {Object} store
* The ElementStyle can use this object to store metadata
* that might outlast the rule view, particularly the current
* set of disabled properties.
* @param {PageStyleFront} pageStyle
* Front for the page style actor that will be providing
* the style information.
* @param {Boolean} showUserAgentStyles
* Should user agent styles be inspected?
*/
function ElementStyle(element, ruleView, store, pageStyle,
showUserAgentStyles) {
function ElementStyle(element, ruleView, store, pageStyle, showUserAgentStyles) {
this.element = element;
this.ruleView = ruleView;
this.store = store || {};
@ -54,13 +52,11 @@ function ElementStyle(element, ruleView, store, pageStyle,
}
ElementStyle.prototype = {
// The element we're looking at.
element: null,
destroy: function() {
if (this.destroyed) {
return;
}
this.destroyed = true;
for (const rule of this.rules) {
@ -93,17 +89,12 @@ ElementStyle.prototype = {
matchedSelectors: true,
filter: this.showUserAgentStyles ? "ua" : undefined,
}).then(entries => {
if (this.destroyed) {
return promise.resolve(undefined);
}
if (this.populated !== populated) {
// Don't care anymore.
if (this.destroyed || this.populated !== populated) {
return promise.resolve(undefined);
}
// Store the current list of rules (if any) during the population
// process. They will be reused if possible.
// process. They will be reused if possible.
const existingRules = this.rules;
this.rules = [];
@ -141,7 +132,7 @@ ElementStyle.prototype = {
* Get the font families in use by the element.
*
* Returns a promise that will be resolved to a list of CSS family
* names. The list might have duplicates.
* names. The list might have duplicates.
*/
getUsedFontFamilies: function() {
return new Promise((resolve, reject) => {
@ -167,25 +158,21 @@ ElementStyle.prototype = {
},
/**
* Add a rule if it's one we care about. Filters out duplicates and
* Add a rule if it's one we care about. Filters out duplicates and
* inherited styles with no inherited properties.
*
* @param {Object} options
* Options for creating the Rule, see the Rule constructor.
* @param {Array} existingRules
* Rules to reuse if possible. If a rule is reused, then it
* it will be deleted from this array.
* @param {Object} options
* Options for creating the Rule, see the Rule constructor.
* @param {Array} existingRules
* Rules to reuse if possible. If a rule is reused, then it
* it will be deleted from this array.
* @return {Boolean} true if we added the rule.
*/
_maybeAddRule: function(options, existingRules) {
// If we've already included this domRule (for example, when a
// common selector is inherited), ignore it.
if (options.rule &&
this.rules.some(rule => rule.domRule === options.rule)) {
return false;
}
if (options.system) {
if (options.system ||
(options.rule && this.rules.some(rule => rule.domRule === options.rule))) {
return false;
}
@ -232,9 +219,9 @@ ElementStyle.prototype = {
* Mark the properties listed in this.rules for a given pseudo element
* with an overridden flag if an earlier property overrides it.
*
* @param {String} pseudo
* Which pseudo element to flag as overridden.
* Empty string or undefined will default to no pseudo element.
* @param {String} pseudo
* Which pseudo element to flag as overridden.
* Empty string or undefined will default to no pseudo element.
*/
markOverridden: function(pseudo = "") {
// Gather all the text properties applied by these rules, ordered
@ -262,7 +249,7 @@ ElementStyle.prototype = {
computedProps = computedProps.concat(textProp.computed);
}
// Walk over the computed properties. As we see a property name
// Walk over the computed properties. As we see a property name
// for the first time, mark that property's name as taken by this
// property.
//
@ -291,13 +278,14 @@ ElementStyle.prototype = {
computedProp.overridden = true;
continue;
}
let overridden;
if (earlier &&
computedProp.priority === "important" &&
earlier.priority !== "important" &&
(earlier.textProp.rule.inherited ||
!computedProp.textProp.rule.inherited)) {
// New property is higher priority. Mark the earlier property
// New property is higher priority. Mark the earlier property
// overridden (which will reverse its dirty state).
earlier._overriddenDirty = !earlier._overriddenDirty;
earlier.overridden = true;
@ -309,6 +297,7 @@ ElementStyle.prototype = {
computedProp._overriddenDirty =
(!!computedProp.overridden !== overridden);
computedProp.overridden = overridden;
if (!computedProp.overridden && computedProp.textProp.enabled) {
taken[computedProp.name] = computedProp;
@ -319,8 +308,8 @@ ElementStyle.prototype = {
}
// For each TextProperty, mark it overridden if all of its
// computed properties are marked overridden. Update the text
// property's associated editor, if any. This will clear the
// computed properties are marked overridden. Update the text
// property's associated editor, if any. This will clear the
// _overriddenDirty state on all computed properties.
for (const textProp of textProps) {
// _updatePropertyOverridden will return true if the
@ -333,21 +322,23 @@ ElementStyle.prototype = {
/**
* Mark a given TextProperty as overridden or not depending on the
* state of its computed properties. Clears the _overriddenDirty state
* state of its computed properties. Clears the _overriddenDirty state
* on all computed properties.
*
* @param {TextProperty} prop
* The text property to update.
* @param {TextProperty} prop
* The text property to update.
* @return {Boolean} true if the TextProperty's overridden state (or any of
* its computed properties overridden state) changed.
*/
_updatePropertyOverridden: function(prop) {
let overridden = true;
let dirty = false;
for (const computedProp of prop.computed) {
if (!computedProp.overridden) {
overridden = false;
}
dirty = computedProp._overriddenDirty || dirty;
delete computedProp._overriddenDirty;
}
@ -371,82 +362,4 @@ ElementStyle.prototype = {
},
};
/**
* Store of CSSStyleDeclarations mapped to properties that have been changed by
* the user.
*/
function UserProperties() {
this.map = new Map();
}
UserProperties.prototype = {
/**
* Get a named property for a given CSSStyleDeclaration.
*
* @param {CSSStyleDeclaration} style
* The CSSStyleDeclaration against which the property is mapped.
* @param {String} name
* The name of the property to get.
* @param {String} value
* Default value.
* @return {String}
* The property value if it has previously been set by the user, null
* otherwise.
*/
getProperty: function(style, name, value) {
const key = this.getKey(style);
const entry = this.map.get(key, null);
if (entry && name in entry) {
return entry[name];
}
return value;
},
/**
* Set a named property for a given CSSStyleDeclaration.
*
* @param {CSSStyleDeclaration} style
* The CSSStyleDeclaration against which the property is to be mapped.
* @param {String} name
* The name of the property to set.
* @param {String} userValue
* The value of the property to set.
*/
setProperty: function(style, name, userValue) {
const key = this.getKey(style, name);
const entry = this.map.get(key, null);
if (entry) {
entry[name] = userValue;
} else {
const props = {};
props[name] = userValue;
this.map.set(key, props);
}
},
/**
* Check whether a named property for a given CSSStyleDeclaration is stored.
*
* @param {CSSStyleDeclaration} style
* The CSSStyleDeclaration against which the property would be mapped.
* @param {String} name
* The name of the property to check.
*/
contains: function(style, name) {
const key = this.getKey(style, name);
const entry = this.map.get(key, null);
return !!entry && name in entry;
},
getKey: function(style, name) {
return style.actorID + ":" + name;
},
clear: function() {
this.map.clear();
}
};
module.exports = ElementStyle;

Просмотреть файл

@ -8,4 +8,5 @@ DevToolsModules(
'element-style.js',
'rule.js',
'text-property.js',
'user-properties.js',
)

Просмотреть файл

@ -0,0 +1,85 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
/**
* Store of CSSStyleDeclarations mapped to properties that have been changed by
* the user.
*/
function UserProperties() {
this.map = new Map();
}
UserProperties.prototype = {
/**
* Get a named property for a given CSSStyleDeclaration.
*
* @param {CSSStyleDeclaration} style
* The CSSStyleDeclaration against which the property is mapped.
* @param {String} name
* The name of the property to get.
* @param {String} value
* Default value.
* @return {String}
* The property value if it has previously been set by the user, null
* otherwise.
*/
getProperty: function(style, name, value) {
const key = this.getKey(style);
const entry = this.map.get(key, null);
if (entry && name in entry) {
return entry[name];
}
return value;
},
/**
* Set a named property for a given CSSStyleDeclaration.
*
* @param {CSSStyleDeclaration} style
* The CSSStyleDeclaration against which the property is to be mapped.
* @param {String} name
* The name of the property to set.
* @param {String} userValue
* The value of the property to set.
*/
setProperty: function(style, name, userValue) {
const key = this.getKey(style, name);
const entry = this.map.get(key, null);
if (entry) {
entry[name] = userValue;
} else {
const props = {};
props[name] = userValue;
this.map.set(key, props);
}
},
/**
* Check whether a named property for a given CSSStyleDeclaration is stored.
*
* @param {CSSStyleDeclaration} style
* The CSSStyleDeclaration against which the property would be mapped.
* @param {String} name
* The name of the property to check.
*/
contains: function(style, name) {
const key = this.getKey(style, name);
const entry = this.map.get(key, null);
return !!entry && name in entry;
},
getKey: function(style, name) {
return style.actorID + ":" + name;
},
clear: function() {
this.map.clear();
}
};
module.exports = UserProperties;

Просмотреть файл

@ -215,6 +215,8 @@ devtools.jar:
skin/images/tool-application.svg (themes/images/tool-application.svg)
skin/images/close.svg (themes/images/close.svg)
skin/images/clear.svg (themes/images/clear.svg)
skin/images/close-3-pane.svg (themes/images/close-3-pane.svg)
skin/images/open-3-pane.svg (themes/images/open-3-pane.svg)
skin/images/vview-delete.png (themes/images/vview-delete.png)
skin/images/vview-delete@2x.png (themes/images/vview-delete@2x.png)
skin/images/vview-edit.png (themes/images/vview-edit.png)

Просмотреть файл

@ -44,7 +44,9 @@ pref("devtools.inspector.show-three-pane-tooltip", false);
#endif
// Enable the 3 pane mode in the inspector
pref("devtools.inspector.three-pane-enabled", true);
// Whether or not this is the first run of the 3 pane mode. Used to reset the default
// inspector sidebar widths for its first run.
pref("devtools.inspector.three-pane-first-run", true);
// Collapse pseudo-elements by default in the rule-view
pref("devtools.inspector.show_pseudo_elements", false);
// The default size for image preview tooltips in the rule-view/computed-view/markup-view

Просмотреть файл

@ -0,0 +1,10 @@
<!-- This Source Code Form is subject to the terms of the Mozilla Public
- License, v. 2.0. If a copy of the MPL was not distributed with this
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
<g fill="context-fill #0b0b0b">
<rect width="3" height="10" x="11" y="3" fill-opacity=".2"/>
<path d="M2,3.00247329 L2,3.00247329 L2,12.9975267 C2,12.9944441 2.00555363,13 2.00684547,13 L13.9931545,13 C13.9983241,13 14,12.9983304 14,12.9975267 L14,3.00247329 C14,3.00555595 13.9944464,3 13.9931545,3 L2.00684547,3 C2.00167589,3 2,3.00166957 2,3.00247329 L2,3.00247329 L2,3.00247329 L2,3.00247329 L2,3.00247329 L2,3.00247329 Z M1,3.00247329 C1,2.44882258 1.44994876,2 2.00684547,2 L13.9931545,2 C14.5492199,2 15,2.45576096 15,3.00247329 L15,12.9975267 C15,13.5511774 14.5500512,14 13.9931545,14 L2.00684547,14 C1.45078007,14 1,13.544239 1,12.9975267 L1,3.00247329 Z M10,3.45454545 L10,12.5454545 L10,13 L11,13 L11,12.5454545 L11,3.45454545 L11,3 L10,3 L10,3.45454545 Z"/>
<polygon points="4 10.75 4 6 8.5 8.375"/>
</g>
</svg>

После

Ширина:  |  Высота:  |  Размер: 1.1 KiB

Просмотреть файл

@ -0,0 +1,10 @@
<!-- This Source Code Form is subject to the terms of the Mozilla Public
- License, v. 2.0. If a copy of the MPL was not distributed with this
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
<g fill="context-fill #0b0b0b">
<rect width="5" height="10" x="10" y="3" fill-opacity=".2"/>
<path d="M2,3.00247329 L2,3.00247329 L2,12.9975267 C2,12.9944441 2.00601643,13 2.00741593,13 L14.9925841,13 C14.9981844,13 15,12.9983304 15,12.9975267 L15,3.00247329 C15,3.00555595 14.9939836,3 14.9925841,3 L2.00741593,3 C2.00181555,3 2,3.00166957 2,3.00247329 L2,3.00247329 L2,3.00247329 L2,3.00247329 L2,3.00247329 L2,3.00247329 Z M2.07876301,2 L14.921237,2 C15.5170213,2 16,2.45576096 16,3.00247329 L16,12.9975267 C16,13.5511774 15.517912,14 14.921237,14 L2.07876301,14 C1.48297865,14 1,13.544239 1,12.9975267 L1,3.00247329 C1,2.44882258 1.48208795,2 2.07876301,2 Z M12,12.5454545 L12,13 L13,13 L13,12.5454545 L13,3.45454545 L13,3 L12,3 L12,3.45454545 L12,12.5454545 Z M9,3.45454545 L9,12.5454545 L9,13 L10,13 L10,12.5454545 L10,3.45454545 L10,3 L9,3 L9,3.45454545 Z"/>
<polygon points="3 10.75 3 6 7.5 8.375" transform="rotate(-180 5.25 8.375)"/>
</g>
</svg>

После

Ширина:  |  Высота:  |  Размер: 1.2 KiB

Просмотреть файл

@ -64,9 +64,14 @@ window {
}
#inspector-splitter-box .sidebar-toggle::before {
background-image: url("chrome://devtools/skin/images/close-3-pane.svg");
transform: unset;
}
#inspector-splitter-box .sidebar-toggle.pane-collapsed::before {
background-image: url("chrome://devtools/skin/images/open-3-pane.svg");
}
/* Use flex layout for the Inspector toolbar. For now, it's done
specifically for the Inspector toolbar since general rule applied
on .devtools-toolbar breaks breadcrumbs and also toolbars in other

Просмотреть файл

@ -37,7 +37,6 @@ const {
EVENT_DEFACTION_CHANGE,
EVENT_DESCRIPTION_CHANGE,
EVENT_DOCUMENT_ATTRIBUTES_CHANGED,
EVENT_HELP_CHANGE,
EVENT_HIDE,
EVENT_NAME_CHANGE,
EVENT_OBJECT_ATTRIBUTE_CHANGED,
@ -234,18 +233,16 @@ const AccessibleActor = ActorClassWithSpec(accessibleSpec, {
return this.rawAccessible.description;
},
get help() {
if (this.isDefunct) {
return null;
}
return this.rawAccessible.help;
},
get keyboardShortcut() {
if (this.isDefunct) {
return null;
}
return this.rawAccessible.keyboardShortcut;
// Gecko accessibility exposes two key bindings: Accessible::AccessKey and
// Accessible::KeyboardShortcut. The former is used for accesskey, where the latter
// is used for global shortcuts defined by XUL menu items, etc. Here - do what the
// Windows implementation does: try AccessKey first, and if that's empty, use
// KeyboardShortcut.
return this.rawAccessible.accessKey || this.rawAccessible.keyboardShortcut;
},
get childCount() {
@ -361,7 +358,6 @@ const AccessibleActor = ActorClassWithSpec(accessibleSpec, {
name: this.name,
value: this.value,
description: this.description,
help: this.help,
keyboardShortcut: this.keyboardShortcut,
childCount: this.childCount,
domNodeType: this.domNodeType,
@ -644,11 +640,6 @@ const AccessibleWalkerActor = ActorClassWithSpec(accessibleWalkerSpec, {
events.emit(accessible, "description-change", rawAccessible.description);
}
break;
case EVENT_HELP_CHANGE:
if (accessible) {
events.emit(accessible, "help-change", rawAccessible.help);
}
break;
case EVENT_REORDER:
if (accessible) {
accessible.children().forEach(child =>
@ -684,9 +675,10 @@ const AccessibleWalkerActor = ActorClassWithSpec(accessibleWalkerSpec, {
events.emit(accessible, "attributes-change", accessible.attributes);
}
break;
// EVENT_ACCELERATOR_CHANGE is currently not fired by gecko accessibility.
case EVENT_ACCELERATOR_CHANGE:
if (accessible) {
events.emit(accessible, "shortcut-change", rawAccessible.keyboardShortcut);
events.emit(accessible, "shortcut-change", accessible.keyboardShortcut);
}
break;
default:

Просмотреть файл

@ -9,6 +9,7 @@
add_task(async function() {
const {client, walker, accessibility} =
await initAccessibilityFrontForUrl(MAIN_DOMAIN + "doc_accessibility.html");
const modifiers = Services.appinfo.OS === "Darwin" ? "\u2303\u2325" : "Alt+Shift+";
const a11yWalker = await accessibility.getWalker();
await accessibility.enable();
@ -20,8 +21,7 @@ add_task(async function() {
role: "pushbutton",
value: "",
description: "Accessibility Test",
help: "",
keyboardShortcut: "",
keyboardShortcut: modifiers + "b",
childCount: 1,
domNodeType: 1,
indexInParent: 1,

Просмотреть файл

@ -9,6 +9,7 @@
add_task(async function() {
const {client, walker, accessibility} =
await initAccessibilityFrontForUrl(MAIN_DOMAIN + "doc_accessibility.html");
const modifiers = Services.appinfo.OS === "Darwin" ? "\u2303\u2325" : "Alt+Shift+";
const a11yWalker = await accessibility.getWalker();
await accessibility.enable();
@ -25,8 +26,7 @@ add_task(async function() {
role: "pushbutton",
value: "",
description: "Accessibility Test",
help: "",
keyboardShortcut: "",
keyboardShortcut: modifiers + "b",
childCount: 1,
domNodeType: 1,
indexInParent: 1,

Просмотреть файл

@ -5,7 +5,7 @@
</head>
<body>
<h1 id="h1">Accessibility Test</h1>
<button id="button" aria-describedby="h1">Accessible Button</button>
<button id="button" aria-describedby="h1" accesskey="b">Accessible Button</button>
<div id="slider" role="slider" aria-valuenow="5"
aria-valuemin="0" aria-valuemax="7">slider</div>
</body>

Просмотреть файл

@ -41,10 +41,6 @@ const AccessibleFront = FrontClassWithSpec(accessibleSpec, {
return this._form.description;
},
get help() {
return this._form.help;
},
get keyboardShortcut() {
return this._form.keyboardShortcut;
},
@ -100,10 +96,6 @@ const AccessibleFront = FrontClassWithSpec(accessibleSpec, {
this._form.description = description;
}),
helpChange: preEvent("help-change", function(help) {
this._form.help = help;
}),
shortcutChange: preEvent("shortcut-change", function(keyboardShortcut) {
this._form.keyboardShortcut = keyboardShortcut;
}),

Просмотреть файл

@ -50,10 +50,6 @@ const accessibleSpec = generateActorSpec({
type: "attributesChange",
attributes: Arg(0, "json")
},
"help-change": {
type: "helpChange",
help: Arg(0, "string")
},
"shortcut-change": {
type: "shortcutChange",
shortcut: Arg(0, "string")

Просмотреть файл

@ -228,7 +228,9 @@ AnonymousContent::GetComputedStylePropertyValue(const nsAString& aElementId,
}
RefPtr<nsComputedDOMStyle> cs =
new nsComputedDOMStyle(element, NS_LITERAL_STRING(""), shell,
new nsComputedDOMStyle(element,
NS_LITERAL_STRING(""),
element->OwnerDoc(),
nsComputedDOMStyle::eAll);
aRv = cs->GetPropertyValue(aPropertyName, aResult);
}

Просмотреть файл

@ -289,18 +289,6 @@ Attr::InsertChildBefore(nsIContent* aKid, nsIContent* aBeforeThis,
return NS_ERROR_NOT_IMPLEMENTED;
}
nsresult
Attr::InsertChildAt_Deprecated(nsIContent* aKid, uint32_t aIndex,
bool aNotify)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
void
Attr::RemoveChildAt_Deprecated(uint32_t aIndex, bool aNotify)
{
}
void
Attr::RemoveChildNode(nsIContent* aKid, bool aNotify)
{

Просмотреть файл

@ -63,9 +63,6 @@ public:
virtual int32_t ComputeIndexOf(const nsINode* aPossibleChild) const override;
virtual nsresult InsertChildBefore(nsIContent* aKid, nsIContent* aBeforeThis,
bool aNotify) override;
virtual nsresult InsertChildAt_Deprecated(nsIContent* aKid, uint32_t aIndex,
bool aNotify) override;
virtual void RemoveChildAt_Deprecated(uint32_t aIndex, bool aNotify) override;
virtual void RemoveChildNode(nsIContent* aKid, bool aNotify) override;
virtual nsresult Clone(mozilla::dom::NodeInfo *aNodeInfo, nsINode **aResult,
bool aPreallocateChildren) const override;

Просмотреть файл

@ -634,19 +634,6 @@ CharacterData::InsertChildBefore(nsIContent* aKid,
return NS_OK;
}
nsresult
CharacterData::InsertChildAt_Deprecated(nsIContent* aKid,
uint32_t aIndex,
bool aNotify)
{
return NS_OK;
}
void
CharacterData::RemoveChildAt_Deprecated(uint32_t aIndex, bool aNotify)
{
}
void
CharacterData::RemoveChildNode(nsIContent* aKid, bool aNotify)
{

Просмотреть файл

@ -105,9 +105,6 @@ public:
virtual int32_t ComputeIndexOf(const nsINode* aPossibleChild) const override;
virtual nsresult InsertChildBefore(nsIContent* aKid, nsIContent* aBeforeThis,
bool aNotify) override;
virtual nsresult InsertChildAt_Deprecated(nsIContent* aKid, uint32_t aIndex,
bool aNotify) override;
virtual void RemoveChildAt_Deprecated(uint32_t aIndex, bool aNotify) override;
virtual void RemoveChildNode(nsIContent* aKid, bool aNotify) override;
virtual void GetTextContentInternal(nsAString& aTextContent,
OOMReporter& aError) override

Просмотреть файл

@ -1225,27 +1225,6 @@ FragmentOrElement::InsertChildBefore(nsIContent* aKid,
return doInsertChildAt(aKid, index, aNotify, mAttrsAndChildren);
}
nsresult
FragmentOrElement::InsertChildAt_Deprecated(nsIContent* aKid,
uint32_t aIndex,
bool aNotify)
{
MOZ_ASSERT(aKid, "null ptr");
return doInsertChildAt(aKid, aIndex, aNotify, mAttrsAndChildren);
}
void
FragmentOrElement::RemoveChildAt_Deprecated(uint32_t aIndex, bool aNotify)
{
nsCOMPtr<nsIContent> oldKid = mAttrsAndChildren.GetSafeChildAt(aIndex);
NS_ASSERTION(oldKid == GetChildAt_Deprecated(aIndex), "Unexpected child in RemoveChildAt_Deprecated");
if (oldKid) {
doRemoveChildAt(aIndex, aNotify, oldKid, mAttrsAndChildren);
}
}
void
FragmentOrElement::RemoveChildNode(nsIContent* aKid, bool aNotify)
{

Просмотреть файл

@ -98,9 +98,6 @@ public:
virtual int32_t ComputeIndexOf(const nsINode* aPossibleChild) const override;
virtual nsresult InsertChildBefore(nsIContent* aKid, nsIContent* aBeforeThis,
bool aNotify) override;
virtual nsresult InsertChildAt_Deprecated(nsIContent* aKid, uint32_t aIndex,
bool aNotify) override;
virtual void RemoveChildAt_Deprecated(uint32_t aIndex, bool aNotify) override;
virtual void RemoveChildNode(nsIContent* aKid, bool aNotify) override;
virtual void GetTextContentInternal(nsAString& aTextContent,
mozilla::OOMReporter& aError) override;

Просмотреть файл

@ -4109,46 +4109,6 @@ nsIDocument::InsertChildBefore(nsIContent* aKid,
return doInsertChildAt(aKid, index, aNotify, mChildren);
}
nsresult
nsIDocument::InsertChildAt_Deprecated(nsIContent* aKid,
uint32_t aIndex,
bool aNotify)
{
if (aKid->IsElement() && GetRootElement()) {
NS_WARNING("Inserting root element when we already have one");
return NS_ERROR_DOM_HIERARCHY_REQUEST_ERR;
}
return doInsertChildAt(aKid, aIndex, aNotify, mChildren);
}
void
nsIDocument::RemoveChildAt_Deprecated(uint32_t aIndex, bool aNotify)
{
nsCOMPtr<nsIContent> oldKid = GetChildAt_Deprecated(aIndex);
if (!oldKid) {
return;
}
if (oldKid->IsElement()) {
// Destroy the link map up front before we mess with the child list.
DestroyElementMaps();
}
// Preemptively clear mCachedRootElement, since we may be about to remove it
// from our child list, and we don't want to return this maybe-obsolete value
// from any GetRootElement() calls that happen inside of doRemoveChildAt().
// (NOTE: for this to be useful, doRemoveChildAt() must NOT trigger any
// GetRootElement() calls until after it's removed the child from mChildren.
// Any call before that point would restore this soon-to-be-obsolete cached
// answer, and our clearing here would be fruitless.)
mCachedRootElement = nullptr;
doRemoveChildAt(aIndex, aNotify, oldKid, mChildren);
MOZ_ASSERT(mCachedRootElement != oldKid,
"Stale pointer in mCachedRootElement, after we tried to clear it "
"(maybe somebody called GetRootElement() too early?)");
}
void
nsIDocument::RemoveChildNode(nsIContent* aKid, bool aNotify)
{

Просмотреть файл

@ -6691,35 +6691,12 @@ nsGlobalWindowOuter::GetComputedStyleHelperOuter(Element& aElt,
const nsAString& aPseudoElt,
bool aDefaultStylesOnly)
{
if (!mDocShell) {
if (!mDoc) {
return nullptr;
}
nsCOMPtr<nsIPresShell> presShell = mDocShell->GetPresShell();
if (!presShell) {
// Try flushing frames on our parent in case there's a pending
// style change that will create the presshell.
auto* parent = nsGlobalWindowOuter::Cast(GetPrivateParent());
if (!parent) {
return nullptr;
}
parent->FlushPendingNotifications(FlushType::Frames);
// Might have killed mDocShell
if (!mDocShell) {
return nullptr;
}
presShell = mDocShell->GetPresShell();
if (!presShell) {
return nullptr;
}
}
RefPtr<nsICSSDeclaration> compStyle =
NS_NewComputedDOMStyle(&aElt, aPseudoElt, presShell,
NS_NewComputedDOMStyle(&aElt, aPseudoElt, mDoc,
aDefaultStylesOnly ? nsComputedDOMStyle::eDefaultOnly :
nsComputedDOMStyle::eAll);

Просмотреть файл

@ -548,9 +548,6 @@ public:
nsresult InsertChildBefore(nsIContent* aKid, nsIContent* aBeforeThis,
bool aNotify) override;
nsresult InsertChildAt_Deprecated(nsIContent* aKid, uint32_t aIndex,
bool aNotify) override;
void RemoveChildAt_Deprecated(uint32_t aIndex, bool aNotify) final;
void RemoveChildNode(nsIContent* aKid, bool aNotify) final;
nsresult Clone(mozilla::dom::NodeInfo* aNodeInfo,
nsINode **aResult,

Просмотреть файл

@ -533,7 +533,7 @@ nsINode::GetNodeValueInternal(nsAString& aNodeValue)
nsINode*
nsINode::RemoveChild(nsINode& aOldChild, ErrorResult& aError)
{
if (IsCharacterData()) {
if (!aOldChild.IsContent()) {
// aOldChild can't be one of our children.
aError.Throw(NS_ERROR_DOM_NOT_FOUND_ERR);
return nullptr;
@ -543,14 +543,16 @@ nsINode::RemoveChild(nsINode& aOldChild, ErrorResult& aError)
nsContentUtils::MaybeFireNodeRemoved(&aOldChild, this);
}
int32_t index = ComputeIndexOf(&aOldChild);
if (index == -1) {
// Check again, we may not be the child's parent anymore.
// Can be triggered by dom/base/crashtests/293388-1.html
if (aOldChild.AsContent()->IsRootOfAnonymousSubtree() ||
aOldChild.GetParentNode() != this) {
// aOldChild isn't one of our children.
aError.Throw(NS_ERROR_DOM_NOT_FOUND_ERR);
return nullptr;
}
RemoveChildAt_Deprecated(index, true);
RemoveChildNode(aOldChild.AsContent(), true);
return &aOldChild;
}
@ -640,7 +642,7 @@ nsINode::Normalize()
"Should always have a parent unless "
"mutation events messed us up");
if (parent) {
parent->RemoveChildAt_Deprecated(parent->ComputeIndexOf(node), true);
parent->RemoveChildNode(node, true);
}
}
}
@ -1997,11 +1999,12 @@ nsINode::ReplaceOrInsertBefore(bool aReplace, nsINode* aNewChild,
}
// Record the node to insert before, if any
nsINode* nodeToInsertBefore;
nsIContent* nodeToInsertBefore;
if (aReplace) {
nodeToInsertBefore = aRefChild->GetNextSibling();
} else {
nodeToInsertBefore = aRefChild;
// Since aRefChild is our child, it must be an nsIContent object.
nodeToInsertBefore = aRefChild ? aRefChild->AsContent() : nullptr;
}
if (nodeToInsertBefore == aNewChild) {
// We're going to remove aNewChild from its parent, so use its next sibling
@ -2015,14 +2018,6 @@ nsINode::ReplaceOrInsertBefore(bool aReplace, nsINode* aNewChild,
nsIContent* newContent = aNewChild->AsContent();
nsCOMPtr<nsINode> oldParent = newContent->GetParentNode();
if (oldParent) {
int32_t removeIndex = oldParent->ComputeIndexOf(newContent);
if (removeIndex < 0) {
// newContent is anonymous. We can't deal with this, so just bail
NS_ERROR("How come our flags didn't catch this?");
aError.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
return nullptr;
}
// Hold a strong ref to nodeToInsertBefore across the removal of newContent
nsCOMPtr<nsINode> kungFuDeathGrip = nodeToInsertBefore;
@ -2034,11 +2029,14 @@ nsINode::ReplaceOrInsertBefore(bool aReplace, nsINode* aNewChild,
{
mozAutoDocUpdate batch(newContent->GetComposedDoc(), true);
nsAutoMutationBatch mb(oldParent, true, true);
oldParent->RemoveChildAt_Deprecated(removeIndex, true);
// ScriptBlocker ensures previous and next stay alive.
nsIContent* previous = aNewChild->GetPreviousSibling();
nsIContent* next = aNewChild->GetNextSibling();
oldParent->RemoveChildNode(aNewChild->AsContent(), true);
if (nsAutoMutationBatch::GetCurrentBatch() == &mb) {
mb.RemovalDone();
mb.SetPrevSibling(oldParent->GetChildAt_Deprecated(removeIndex - 1));
mb.SetNextSibling(oldParent->GetChildAt_Deprecated(removeIndex));
mb.SetPrevSibling(previous);
mb.SetNextSibling(next);
}
}
@ -2077,7 +2075,7 @@ nsINode::ReplaceOrInsertBefore(bool aReplace, nsINode* aNewChild,
if (aReplace) {
nodeToInsertBefore = aRefChild->GetNextSibling();
} else {
nodeToInsertBefore = aRefChild;
nodeToInsertBefore = aRefChild ? aRefChild->AsContent() : nullptr;
}
}
}
@ -2112,8 +2110,8 @@ nsINode::ReplaceOrInsertBefore(bool aReplace, nsINode* aNewChild,
mozAutoDocUpdate batch(newContent->GetComposedDoc(), true);
nsAutoMutationBatch mb(newContent, false, true);
for (uint32_t i = count; i > 0;) {
newContent->RemoveChildAt_Deprecated(--i, true);
while (newContent->HasChildren()) {
newContent->RemoveChildNode(newContent->GetLastChild(), true);
}
}
@ -2151,7 +2149,8 @@ nsINode::ReplaceOrInsertBefore(bool aReplace, nsINode* aNewChild,
if (aReplace) {
nodeToInsertBefore = aRefChild->GetNextSibling();
} else {
nodeToInsertBefore = aRefChild;
// If aRefChild has 'this' as a parent, it must be an nsIContent.
nodeToInsertBefore = aRefChild ? aRefChild->AsContent() : nullptr;
}
// And verify that newContent is still allowed as our child. Sadly, we
@ -2182,23 +2181,6 @@ nsINode::ReplaceOrInsertBefore(bool aReplace, nsINode* aNewChild,
mozAutoDocUpdate batch(GetComposedDoc(), true);
nsAutoMutationBatch mb;
// Figure out which index we want to insert at. Note that we use
// nodeToInsertBefore to determine this, because it's possible that
// aRefChild == aNewChild, in which case we just removed it from the
// parent list.
int32_t insPos;
if (nodeToInsertBefore) {
insPos = ComputeIndexOf(nodeToInsertBefore);
if (insPos < 0) {
// XXXbz How the heck would _that_ happen, exactly?
aError.Throw(NS_ERROR_DOM_NOT_FOUND_ERR);
return nullptr;
}
}
else {
insPos = GetChildCount();
}
// If we're replacing and we haven't removed aRefChild yet, do so now
if (aReplace && aRefChild != aNewChild) {
mb.Init(this, true, true);
@ -2208,11 +2190,11 @@ nsINode::ReplaceOrInsertBefore(bool aReplace, nsINode* aNewChild,
NS_ASSERTION(aRefChild->GetNextSibling() == nodeToInsertBefore,
"Unexpected nodeToInsertBefore");
// An since nodeToInsertBefore is at index insPos, we want to remove
// at the previous index.
NS_ASSERTION(insPos >= 1, "insPos too small");
RemoveChildAt_Deprecated(insPos-1, true);
--insPos;
nsIContent* toBeRemoved = nodeToInsertBefore ?
nodeToInsertBefore->GetPreviousSibling() : GetLastChild();
MOZ_ASSERT(toBeRemoved);
RemoveChildNode(toBeRemoved, true);
}
// Move new child over to our document if needed. Do this after removing
@ -2246,8 +2228,9 @@ nsINode::ReplaceOrInsertBefore(bool aReplace, nsINode* aNewChild,
nsAutoMutationBatch* mutationBatch = nsAutoMutationBatch::GetCurrentBatch();
if (mutationBatch) {
mutationBatch->RemovalDone();
mutationBatch->SetPrevSibling(GetChildAt_Deprecated(insPos - 1));
mutationBatch->SetNextSibling(GetChildAt_Deprecated(insPos));
mutationBatch->SetPrevSibling(nodeToInsertBefore ?
nodeToInsertBefore->GetPreviousSibling() : GetLastChild());
mutationBatch->SetNextSibling(nodeToInsertBefore);
}
uint32_t count = fragChildren->Length();
@ -2255,16 +2238,16 @@ nsINode::ReplaceOrInsertBefore(bool aReplace, nsINode* aNewChild,
return result;
}
bool appending = !IsDocument() && uint32_t(insPos) == GetChildCount();
bool appending = !IsDocument() && !nodeToInsertBefore;
nsIContent* firstInsertedContent = fragChildren->ElementAt(0);
// Iterate through the fragment's children, and insert them in the new
// parent
for (uint32_t i = 0; i < count; ++i, ++insPos) {
for (uint32_t i = 0; i < count; ++i) {
// XXXbz how come no reparenting here? That seems odd...
// Insert the child.
aError = InsertChildAt_Deprecated(fragChildren->ElementAt(i), insPos,
!appending);
aError = InsertChildBefore(fragChildren->ElementAt(i), nodeToInsertBefore,
!appending);
if (aError.Failed()) {
// Make sure to notify on any children that we did succeed to insert
if (appending && i != 0) {
@ -2300,13 +2283,13 @@ nsINode::ReplaceOrInsertBefore(bool aReplace, nsINode* aNewChild,
// We need to reparent here for nodes for which the parent of their
// wrapper is not the wrapper for their ownerDocument (XUL elements,
// form controls, ...). Also applies in the fragment code above.
if (nsAutoMutationBatch::GetCurrentBatch() == &mb) {
mb.RemovalDone();
mb.SetPrevSibling(GetChildAt_Deprecated(insPos - 1));
mb.SetNextSibling(GetChildAt_Deprecated(insPos));
mb.SetPrevSibling(nodeToInsertBefore ?
nodeToInsertBefore->GetPreviousSibling() : GetLastChild());
mb.SetNextSibling(nodeToInsertBefore);
}
aError = InsertChildAt_Deprecated(newContent, insPos, true);
aError = InsertChildBefore(newContent, nodeToInsertBefore, true);
if (aError.Failed()) {
return nullptr;
}

Просмотреть файл

@ -821,29 +821,6 @@ public:
virtual nsresult InsertChildBefore(nsIContent* aKid, nsIContent* aBeforeThis,
bool aNotify) = 0;
/**
* Insert a content node at a particular index. This method handles calling
* BindToTree on the child appropriately.
*
* @param aKid the content to insert
* @param aIndex the index it is being inserted at (the index it will have
* after it is inserted)
* @param aNotify whether to notify the document (current document for
* nsIContent, and |this| for nsIDocument) that the insert has
* occurred
*
* @throws NS_ERROR_DOM_HIERARCHY_REQUEST_ERR if one attempts to have more
* than one element node as a child of a document. Doing this will also
* assert -- you shouldn't be doing it! Check with
* nsIDocument::GetRootElement() first if you're not sure. Apart from this
* one constraint, this doesn't do any checking on whether aKid is a valid
* child of |this|.
*
* @throws NS_ERROR_OUT_OF_MEMORY in some cases (from BindToTree).
*/
virtual nsresult InsertChildAt_Deprecated(nsIContent* aKid, uint32_t aIndex,
bool aNotify) = 0;
/**
* Append a content node to the end of the child list. This method handles
* calling BindToTree on the child appropriately.
@ -864,25 +841,9 @@ public:
*/
nsresult AppendChildTo(nsIContent* aKid, bool aNotify)
{
return InsertChildAt_Deprecated(aKid, GetChildCount(), aNotify);
return InsertChildBefore(aKid, nullptr, aNotify);
}
/**
* NOTE: this function is going to be removed soon (hopefully!) Don't use it
* in new code.
*
* Remove a child from this node. This method handles calling UnbindFromTree
* on the child appropriately.
*
* @param aIndex the index of the child to remove
* @param aNotify whether to notify the document (current document for
* nsIContent, and |this| for nsIDocument) that the remove has
* occurred
*
* Note: If there is no child at aIndex, this method will simply do nothing.
*/
virtual void RemoveChildAt_Deprecated(uint32_t aIndex, bool aNotify) = 0;
/**
* Remove a child from this node. This method handles calling UnbindFromTree
* on the child appropriately.

Просмотреть файл

@ -236,11 +236,13 @@ public:
MOZ_ASSERT(aTouchEvent,
"mRetargetedTouchTargets should be empty when dispatching non-touch events.");
WidgetTouchEvent::TouchArray& touches = aTouchEvent->mTouches;
MOZ_ASSERT(!touches.Length() ||
touches.Length() == mRetargetedTouchTargets->Length());
for (uint32_t i = 0; i < touches.Length(); ++i) {
touches[i]->mTarget = mRetargetedTouchTargets->ElementAt(i);
if (mRetargetedTouchTargets.isSome()) {
WidgetTouchEvent::TouchArray& touches = aTouchEvent->mTouches;
MOZ_ASSERT(!touches.Length() ||
touches.Length() == mRetargetedTouchTargets->Length());
for (uint32_t i = 0; i < touches.Length(); ++i) {
touches[i]->mTarget = mRetargetedTouchTargets->ElementAt(i);
}
}
if (aDOMEvent) {

Просмотреть файл

@ -171,64 +171,6 @@ HTMLFieldSetElement::InsertChildBefore(nsIContent* aChild,
return rv;
}
nsresult
HTMLFieldSetElement::InsertChildAt_Deprecated(nsIContent* aChild,
uint32_t aIndex,
bool aNotify)
{
bool firstLegendHasChanged = false;
if (aChild->IsHTMLElement(nsGkAtoms::legend)) {
if (!mFirstLegend) {
mFirstLegend = aChild;
// We do not want to notify the first time mFirstElement is set.
} else {
// If mFirstLegend is before aIndex, we do not change it.
// Otherwise, mFirstLegend is now aChild.
if (int32_t(aIndex) <= ComputeIndexOf(mFirstLegend)) {
mFirstLegend = aChild;
firstLegendHasChanged = true;
}
}
}
nsresult rv =
nsGenericHTMLFormElement::InsertChildAt_Deprecated(aChild, aIndex, aNotify);
NS_ENSURE_SUCCESS(rv, rv);
if (firstLegendHasChanged) {
NotifyElementsForFirstLegendChange(aNotify);
}
return rv;
}
void
HTMLFieldSetElement::RemoveChildAt_Deprecated(uint32_t aIndex, bool aNotify)
{
bool firstLegendHasChanged = false;
if (mFirstLegend && (GetChildAt_Deprecated(aIndex) == mFirstLegend)) {
// If we are removing the first legend we have to found another one.
nsIContent* child = mFirstLegend->GetNextSibling();
mFirstLegend = nullptr;
firstLegendHasChanged = true;
for (; child; child = child->GetNextSibling()) {
if (child->IsHTMLElement(nsGkAtoms::legend)) {
mFirstLegend = child;
break;
}
}
}
nsGenericHTMLFormElement::RemoveChildAt_Deprecated(aIndex, aNotify);
if (firstLegendHasChanged) {
NotifyElementsForFirstLegendChange(aNotify);
}
}
void
HTMLFieldSetElement::RemoveChildNode(nsIContent* aKid, bool aNotify)
{

Просмотреть файл

@ -42,9 +42,6 @@ public:
virtual nsresult InsertChildBefore(nsIContent* aChild, nsIContent* aBeforeThis,
bool aNotify) override;
virtual nsresult InsertChildAt_Deprecated(nsIContent* aChild, uint32_t aIndex,
bool aNotify) override;
virtual void RemoveChildAt_Deprecated(uint32_t aIndex, bool aNotify) override;
virtual void RemoveChildNode(nsIContent* aKid, bool aNotify) override;
// nsIFormControl

Просмотреть файл

@ -86,28 +86,6 @@ HTMLOptGroupElement::InsertChildBefore(nsIContent* aKid,
return rv;
}
nsresult
HTMLOptGroupElement::InsertChildAt_Deprecated(nsIContent* aKid,
uint32_t aIndex,
bool aNotify)
{
SafeOptionListMutation safeMutation(GetSelect(), this, aKid, aIndex, aNotify);
nsresult rv = nsGenericHTMLElement::InsertChildAt_Deprecated(aKid, aIndex,
aNotify);
if (NS_FAILED(rv)) {
safeMutation.MutationFailed();
}
return rv;
}
void
HTMLOptGroupElement::RemoveChildAt_Deprecated(uint32_t aIndex, bool aNotify)
{
SafeOptionListMutation safeMutation(GetSelect(), this, nullptr, aIndex,
aNotify);
nsGenericHTMLElement::RemoveChildAt_Deprecated(aIndex, aNotify);
}
void
HTMLOptGroupElement::RemoveChildNode(nsIContent* aKid, bool aNotify)
{

Просмотреть файл

@ -28,9 +28,6 @@ public:
// nsINode
virtual nsresult InsertChildBefore(nsIContent* aKid, nsIContent* aBeforeThis,
bool aNotify) override;
virtual nsresult InsertChildAt_Deprecated(nsIContent* aKid, uint32_t aIndex,
bool aNotify) override;
virtual void RemoveChildAt_Deprecated(uint32_t aIndex, bool aNotify) override;
virtual void RemoveChildNode(nsIContent* aKid, bool aNotify) override;
// nsIContent

Просмотреть файл

@ -30,32 +30,6 @@ HTMLPictureElement::~HTMLPictureElement()
NS_IMPL_ELEMENT_CLONE(HTMLPictureElement)
void
HTMLPictureElement::RemoveChildAt_Deprecated(uint32_t aIndex, bool aNotify)
{
nsCOMPtr<nsIContent> child = GetChildAt_Deprecated(aIndex);
if (child && child->IsHTMLElement(nsGkAtoms::img)) {
HTMLImageElement* img = HTMLImageElement::FromNode(child);
if (img) {
img->PictureSourceRemoved(child->AsContent());
}
} else if (child && child->IsHTMLElement(nsGkAtoms::source)) {
// Find all img siblings after this <source> to notify them of its demise
nsCOMPtr<nsIContent> nextSibling = child->GetNextSibling();
if (nextSibling && nextSibling->GetParentNode() == this) {
do {
HTMLImageElement* img = HTMLImageElement::FromNode(nextSibling);
if (img) {
img->PictureSourceRemoved(child->AsContent());
}
} while ( (nextSibling = nextSibling->GetNextSibling()) );
}
}
nsGenericHTMLElement::RemoveChildAt_Deprecated(aIndex, aNotify);
}
void
HTMLPictureElement::RemoveChildNode(nsIContent* aKid, bool aNotify)
{
@ -111,35 +85,6 @@ HTMLPictureElement::InsertChildBefore(nsIContent* aKid, nsIContent* aBeforeThis,
return rv;
}
nsresult
HTMLPictureElement::InsertChildAt_Deprecated(nsIContent* aKid, uint32_t aIndex, bool aNotify)
{
nsresult rv = nsGenericHTMLElement::InsertChildAt_Deprecated(aKid, aIndex, aNotify);
NS_ENSURE_SUCCESS(rv, rv);
NS_ENSURE_TRUE(aKid, rv);
if (aKid->IsHTMLElement(nsGkAtoms::img)) {
HTMLImageElement* img = HTMLImageElement::FromNode(aKid);
if (img) {
img->PictureSourceAdded(aKid->AsContent());
}
} else if (aKid->IsHTMLElement(nsGkAtoms::source)) {
// Find all img siblings after this <source> to notify them of its insertion
nsCOMPtr<nsIContent> nextSibling = aKid->GetNextSibling();
if (nextSibling && nextSibling->GetParentNode() == this) {
do {
HTMLImageElement* img = HTMLImageElement::FromNode(nextSibling);
if (img) {
img->PictureSourceAdded(aKid->AsContent());
}
} while ( (nextSibling = nextSibling->GetNextSibling()) );
}
}
return rv;
}
JSObject*
HTMLPictureElement::WrapNode(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
{

Просмотреть файл

@ -23,12 +23,9 @@ public:
virtual nsresult Clone(mozilla::dom::NodeInfo* aNodeInfo, nsINode** aResult,
bool aPreallocateChildren) const override;
virtual void RemoveChildAt_Deprecated(uint32_t aIndex, bool aNotify) override;
virtual void RemoveChildNode(nsIContent* aKid, bool aNotify) override;
virtual nsresult InsertChildBefore(nsIContent* aKid, nsIContent* aBeforeThis,
bool aNotify) override;
virtual nsresult InsertChildAt_Deprecated(nsIContent* aKid, uint32_t aIndex,
bool aNotify) override;
protected:
virtual ~HTMLPictureElement();

Просмотреть файл

@ -217,28 +217,6 @@ HTMLSelectElement::InsertChildBefore(nsIContent* aKid,
return rv;
}
nsresult
HTMLSelectElement::InsertChildAt_Deprecated(nsIContent* aKid,
uint32_t aIndex,
bool aNotify)
{
SafeOptionListMutation safeMutation(this, this, aKid, aIndex, aNotify);
nsresult rv =
nsGenericHTMLFormElementWithState::InsertChildAt_Deprecated(aKid, aIndex,
aNotify);
if (NS_FAILED(rv)) {
safeMutation.MutationFailed();
}
return rv;
}
void
HTMLSelectElement::RemoveChildAt_Deprecated(uint32_t aIndex, bool aNotify)
{
SafeOptionListMutation safeMutation(this, this, nullptr, aIndex, aNotify);
nsGenericHTMLFormElementWithState::RemoveChildAt_Deprecated(aIndex, aNotify);
}
void
HTMLSelectElement::RemoveChildNode(nsIContent* aKid, bool aNotify)
{

Просмотреть файл

@ -247,9 +247,6 @@ public:
virtual bool IsHTMLFocusable(bool aWithMouse, bool* aIsFocusable, int32_t* aTabIndex) override;
virtual nsresult InsertChildBefore(nsIContent* aKid, nsIContent* aBeforeThis,
bool aNotify) override;
virtual nsresult InsertChildAt_Deprecated(nsIContent* aKid, uint32_t aIndex,
bool aNotify) override;
virtual void RemoveChildAt_Deprecated(uint32_t aIndex, bool aNotify) override;
virtual void RemoveChildNode(nsIContent* aKid, bool aNotify) override;
// Overriden nsIFormControl methods

Просмотреть файл

@ -50,23 +50,6 @@ SVGDocument::InsertChildBefore(nsIContent* aKid, nsIContent* aBeforeThis,
return XMLDocument::InsertChildBefore(aKid, aBeforeThis, aNotify);
}
nsresult
SVGDocument::InsertChildAt_Deprecated(nsIContent* aKid, uint32_t aIndex,
bool aNotify)
{
if (aKid->IsElement() && !aKid->IsSVGElement()) {
// We can get here when well formed XML with a non-SVG root element is
// served with the SVG MIME type, for example. In that case we need to load
// the non-SVG UA sheets or else we can get bugs like bug 1016145. Note
// that we have to do this _before_ the
// XMLDocument::InsertChildAt_Deprecated call, since that can try to
// construct frames, and we need to have the sheets loaded by then.
EnsureNonSVGUserAgentStyleSheetsLoaded();
}
return XMLDocument::InsertChildAt_Deprecated(aKid, aIndex, aNotify);
}
nsresult
SVGDocument::Clone(mozilla::dom::NodeInfo *aNodeInfo, nsINode **aResult,
bool aPreallocateChildren) const

Просмотреть файл

@ -35,8 +35,6 @@ public:
virtual nsresult InsertChildBefore(nsIContent* aKid, nsIContent* aBeforeThis,
bool aNotify) override;
virtual nsresult InsertChildAt_Deprecated(nsIContent* aKid, uint32_t aIndex,
bool aNotify) override;
virtual nsresult Clone(mozilla::dom::NodeInfo *aNodeInfo, nsINode **aResult,
bool aPreallocateChildren) const override;

Просмотреть файл

@ -93,26 +93,6 @@ SVGSwitchElement::InsertChildBefore(nsIContent* aKid, nsIContent* aBeforeThis,
return rv;
}
nsresult
SVGSwitchElement::InsertChildAt_Deprecated(nsIContent* aKid,
uint32_t aIndex,
bool aNotify)
{
nsresult rv = SVGSwitchElementBase::InsertChildAt_Deprecated(aKid, aIndex,
aNotify);
if (NS_SUCCEEDED(rv)) {
MaybeInvalidate();
}
return rv;
}
void
SVGSwitchElement::RemoveChildAt_Deprecated(uint32_t aIndex, bool aNotify)
{
SVGSwitchElementBase::RemoveChildAt_Deprecated(aIndex, aNotify);
MaybeInvalidate();
}
void
SVGSwitchElement::RemoveChildNode(nsIContent* aKid, bool aNotify)
{

Просмотреть файл

@ -42,9 +42,6 @@ public:
// nsINode
virtual nsresult InsertChildBefore(nsIContent* aKid, nsIContent* aBeforeThis,
bool aNotify) override;
virtual nsresult InsertChildAt_Deprecated(nsIContent* aKid, uint32_t aIndex,
bool aNotify) override;
virtual void RemoveChildAt_Deprecated(uint32_t aIndex, bool aNotify) override;
virtual void RemoveChildNode(nsIContent* aKid, bool aNotify) override;
// nsIContent

Просмотреть файл

@ -827,103 +827,6 @@ nsXULElement::UnbindFromTree(bool aDeep, bool aNullParent)
nsStyledElement::UnbindFromTree(aDeep, aNullParent);
}
void
nsXULElement::RemoveChildAt_Deprecated(uint32_t aIndex, bool aNotify)
{
nsCOMPtr<nsIContent> oldKid = mAttrsAndChildren.GetSafeChildAt(aIndex);
if (!oldKid) {
return;
}
// On the removal of a <treeitem>, <treechildren>, or <treecell> element,
// the possibility exists that some of the items in the removed subtree
// are selected (and therefore need to be deselected). We need to account for this.
nsCOMPtr<nsIDOMXULMultiSelectControlElement> controlElement;
nsCOMPtr<nsIListBoxObject> listBox;
bool fireSelectionHandler = false;
// -1 = do nothing, -2 = null out current item
// anything else = index to re-set as current
int32_t newCurrentIndex = -1;
if (oldKid->NodeInfo()->Equals(nsGkAtoms::listitem, kNameSpaceID_XUL)) {
// This is the nasty case. We have (potentially) a slew of selected items
// and cells going away.
// First, retrieve the tree.
// Check first whether this element IS the tree
controlElement = do_QueryObject(this);
// If it's not, look at our parent
if (!controlElement)
GetParentTree(getter_AddRefs(controlElement));
nsCOMPtr<nsIContent> controlContent(do_QueryInterface(controlElement));
RefPtr<nsXULElement> xulElement = FromNodeOrNull(controlContent);
if (xulElement) {
// Iterate over all of the items and find out if they are contained inside
// the removed subtree.
int32_t length;
controlElement->GetSelectedCount(&length);
for (int32_t i = 0; i < length; i++) {
nsCOMPtr<nsIDOMXULSelectControlItemElement> item;
controlElement->MultiGetSelectedItem(i, getter_AddRefs(item));
nsCOMPtr<nsINode> node = do_QueryInterface(item);
if (node == oldKid &&
NS_SUCCEEDED(controlElement->RemoveItemFromSelection(item))) {
length--;
i--;
fireSelectionHandler = true;
}
}
nsCOMPtr<nsIDOMXULSelectControlItemElement> curItem;
controlElement->GetCurrentItem(getter_AddRefs(curItem));
nsCOMPtr<nsIContent> curNode = do_QueryInterface(curItem);
if (curNode && nsContentUtils::ContentIsDescendantOf(curNode, oldKid)) {
// Current item going away
nsCOMPtr<nsIBoxObject> box = xulElement->GetBoxObject(IgnoreErrors());
listBox = do_QueryInterface(box);
if (listBox) {
listBox->GetIndexOfItem(oldKid->AsElement(), &newCurrentIndex);
}
// If any of this fails, we'll just set the current item to null
if (newCurrentIndex == -1)
newCurrentIndex = -2;
}
}
}
nsStyledElement::RemoveChildAt_Deprecated(aIndex, aNotify);
if (newCurrentIndex == -2) {
controlElement->SetCurrentItem(nullptr);
} else if (newCurrentIndex > -1) {
// Make sure the index is still valid
int32_t treeRows;
listBox->GetRowCount(&treeRows);
if (treeRows > 0) {
newCurrentIndex = std::min((treeRows - 1), newCurrentIndex);
RefPtr<Element> newCurrentItem;
listBox->GetItemAtIndex(newCurrentIndex, getter_AddRefs(newCurrentItem));
nsCOMPtr<nsIDOMXULSelectControlItemElement> xulCurItem = do_QueryInterface(newCurrentItem);
if (xulCurItem)
controlElement->SetCurrentItem(xulCurItem);
} else {
controlElement->SetCurrentItem(nullptr);
}
}
nsIDocument* doc;
if (fireSelectionHandler && (doc = GetComposedDoc())) {
nsContentUtils::DispatchTrustedEvent(doc,
static_cast<nsIContent*>(this),
NS_LITERAL_STRING("select"),
false,
true);
}
}
void
nsXULElement::RemoveChildNode(nsIContent* aKid, bool aNotify)
{

Просмотреть файл

@ -368,7 +368,6 @@ public:
nsIContent* aBindingParent,
bool aCompileEventHandlers) override;
virtual void UnbindFromTree(bool aDeep, bool aNullParent) override;
virtual void RemoveChildAt_Deprecated(uint32_t aIndex, bool aNotify) override;
virtual void RemoveChildNode(nsIContent* aKid, bool aNotify) override;
virtual void DestroyContent() override;

Просмотреть файл

@ -556,11 +556,8 @@ CSSEditUtils::GetComputedStyle(Element* aElement)
nsIDocument* doc = aElement->GetComposedDoc();
NS_ENSURE_TRUE(doc, nullptr);
nsIPresShell* presShell = doc->GetShell();
NS_ENSURE_TRUE(presShell, nullptr);
RefPtr<nsComputedDOMStyle> style =
NS_NewComputedDOMStyle(aElement, EmptyString(), presShell);
NS_NewComputedDOMStyle(aElement, EmptyString(), doc);
return style.forget();
}

Просмотреть файл

@ -384,6 +384,9 @@ GPUParent::RecvSimulateDeviceReset(GPUDeviceData* aOut)
#if defined(XP_WIN)
DeviceManagerDx::Get()->ForceDeviceReset(ForcedDeviceResetReason::COMPOSITOR_UPDATED);
DeviceManagerDx::Get()->MaybeResetAndReacquireDevices();
if (gfxVars::UseWebRender()) {
wr::RenderThread::Get()->SimulateDeviceReset();
}
#endif
RecvGetDeviceStatus(aOut);
return IPC_OK();

Просмотреть файл

@ -972,7 +972,9 @@ static float* qcms_modular_transform_data(struct qcms_modular_transform *transfo
assert(0 && "Unsupported transform module");
return NULL;
}
if (transform->grid_size <= 0) {
if (transform->grid_size <= 0 &&
(transform_fn == qcms_transform_module_clut ||
transform_fn == qcms_transform_module_clut_only)) {
assert(0 && "Invalid transform");
return NULL;
}

Просмотреть файл

@ -162,6 +162,7 @@ static Mutex* gGfxPlatformPrefsLock = nullptr;
static qcms_profile *gCMSOutputProfile = nullptr;
static qcms_profile *gCMSsRGBProfile = nullptr;
static bool gCMSRGBTransformFailed = false;
static qcms_transform *gCMSRGBTransform = nullptr;
static qcms_transform *gCMSInverseRGBTransform = nullptr;
static qcms_transform *gCMSRGBATransform = nullptr;
@ -2088,7 +2089,7 @@ gfxPlatform::GetCMSsRGBProfile()
qcms_transform *
gfxPlatform::GetCMSRGBTransform()
{
if (!gCMSRGBTransform) {
if (!gCMSRGBTransform && !gCMSRGBTransformFailed) {
qcms_profile *inProfile, *outProfile;
outProfile = GetCMSOutputProfile();
inProfile = GetCMSsRGBProfile();
@ -2099,6 +2100,9 @@ gfxPlatform::GetCMSRGBTransform()
gCMSRGBTransform = qcms_transform_create(inProfile, QCMS_DATA_RGB_8,
outProfile, QCMS_DATA_RGB_8,
QCMS_INTENT_PERCEPTUAL);
if (!gCMSRGBTransform) {
gCMSRGBTransformFailed = true;
}
}
return gCMSRGBTransform;

Просмотреть файл

@ -311,7 +311,7 @@ bool
RenderCompositorANGLE::BeginFrame()
{
if (mDevice->GetDeviceRemovedReason() != S_OK) {
RenderThread::Get()->HandleDeviceReset("BeginFrame");
RenderThread::Get()->HandleDeviceReset("BeginFrame", /* aNotify */ true);
return false;
}
@ -329,7 +329,7 @@ RenderCompositorANGLE::BeginFrame()
if (mSyncObject) {
if (!mSyncObject->Synchronize()) {
// It's timeout or other error. Handle the device-reset here.
RenderThread::Get()->HandleDeviceReset("SyncObject");
RenderThread::Get()->HandleDeviceReset("SyncObject", /* aNotify */ true);
return false;
}
}

Просмотреть файл

@ -552,7 +552,7 @@ RenderThread::ProgramCacheTask()
}
void
RenderThread::HandleDeviceReset(const char* aWhere)
RenderThread::HandleDeviceReset(const char* aWhere, bool aNotify)
{
MOZ_ASSERT(IsInRenderThread());
@ -560,9 +560,11 @@ RenderThread::HandleDeviceReset(const char* aWhere)
return;
}
gfxCriticalNote << "GFX: RenderThread detected a device reset in " << aWhere;
if (XRE_IsGPUProcess()) {
gfx::GPUParent::GetSingleton()->NotifyDeviceReset();
if (aNotify) {
gfxCriticalNote << "GFX: RenderThread detected a device reset in " << aWhere;
if (XRE_IsGPUProcess()) {
gfx::GPUParent::GetSingleton()->NotifyDeviceReset();
}
}
{
@ -584,6 +586,21 @@ RenderThread::IsHandlingDeviceReset()
return mHandlingDeviceReset;
}
void
RenderThread::SimulateDeviceReset()
{
if (!IsInRenderThread()) {
Loop()->PostTask(NewRunnableMethod(
"RenderThread::SimulateDeviceReset",
this, &RenderThread::SimulateDeviceReset
));
} else {
// When this function is called GPUProcessManager::SimulateDeviceReset() already
// triggers destroying all CompositorSessions before re-creating them.
HandleDeviceReset("SimulateDeviceReset", /* aNotify */ false);
}
}
WebRenderProgramCache*
RenderThread::ProgramCache()
{

Просмотреть файл

@ -168,9 +168,11 @@ public:
WebRenderProgramCache* ProgramCache();
/// Can only be called from the render thread.
void HandleDeviceReset(const char* aWhere);
void HandleDeviceReset(const char* aWhere, bool aNotify);
/// Can only be called from the render thread.
bool IsHandlingDeviceReset();
/// Can be called from any thread.
void SimulateDeviceReset();
size_t RendererCount();

Просмотреть файл

@ -2968,7 +2968,7 @@ GCRuntime::updateZonePointersToRelocatedCells(Zone* zone)
* Update runtime-wide pointers to relocated cells.
*/
void
GCRuntime::updateRuntimePointersToRelocatedCells(AutoTraceSession& session)
GCRuntime::updateRuntimePointersToRelocatedCells(AutoGCSession& session)
{
MOZ_ASSERT(!rt->isBeingDestroyed());
@ -4262,8 +4262,7 @@ ShouldCollectZone(Zone* zone, JS::gcreason::Reason reason)
}
bool
GCRuntime::prepareZonesForCollection(JS::gcreason::Reason reason, bool* isFullOut,
AutoLockForExclusiveAccess& lock)
GCRuntime::prepareZonesForCollection(JS::gcreason::Reason reason, bool* isFullOut)
{
#ifdef DEBUG
/* Assert that zone state is as we expect */
@ -4355,7 +4354,7 @@ PurgeShapeTablesForShrinkingGC(JSRuntime* rt)
{
gcstats::AutoPhase ap(rt->gc.stats(), gcstats::PhaseKind::PURGE_SHAPE_TABLES);
for (GCZonesIter zone(rt); !zone.done(); zone.next()) {
if (zone->keepShapeTables() || zone->isSelfHostingZone())
if (!CanRelocateZone(zone) || zone->keepShapeTables())
continue;
for (auto baseShape = zone->cellIter<BaseShape>(); !baseShape.done(); baseShape.next())
baseShape->maybePurgeTable();
@ -4384,21 +4383,19 @@ BufferGrayRoots(GCParallelTask* task)
}
bool
GCRuntime::beginMarkPhase(JS::gcreason::Reason reason, AutoTraceSession& session)
GCRuntime::beginMarkPhase(JS::gcreason::Reason reason, AutoGCSession& session)
{
MOZ_ASSERT(session.maybeLock.isSome());
#ifdef DEBUG
if (fullCompartmentChecks)
checkForCompartmentMismatches();
#endif
if (!prepareZonesForCollection(reason, &isFull.ref(), session.lock()))
if (!prepareZonesForCollection(reason, &isFull.ref()))
return false;
/* If we're not collecting the atoms zone we can release the lock now. */
if (!atomsZone->isCollecting())
session.maybeLock.reset();
/* * Check it's safe to access the atoms zone if we are collecting it. */
if (atomsZone->isCollecting())
session.maybeCheckAtomsAccess.emplace(rt);
/*
* In an incremental GC, clear the area free lists to ensure that subsequent
@ -4666,7 +4663,7 @@ class js::gc::MarkingValidator
public:
explicit MarkingValidator(GCRuntime* gc);
~MarkingValidator();
void nonIncrementalMark(AutoTraceSession& session);
void nonIncrementalMark(AutoGCSession& session);
void validate();
private:
@ -4692,7 +4689,7 @@ js::gc::MarkingValidator::~MarkingValidator()
}
void
js::gc::MarkingValidator::nonIncrementalMark(AutoTraceSession& session)
js::gc::MarkingValidator::nonIncrementalMark(AutoGCSession& session)
{
/*
* Perform a non-incremental mark for all collecting zones and record
@ -4908,7 +4905,7 @@ js::gc::MarkingValidator::validate()
#endif // JS_GC_ZEAL
void
GCRuntime::computeNonIncrementalMarkingForValidation(AutoTraceSession& session)
GCRuntime::computeNonIncrementalMarkingForValidation(AutoGCSession& session)
{
#ifdef JS_GC_ZEAL
MOZ_ASSERT(!markingValidator);
@ -5884,7 +5881,7 @@ GCRuntime::endSweepingSweepGroup(FreeOp* fop, SliceBudget& budget)
}
void
GCRuntime::beginSweepPhase(JS::gcreason::Reason reason, AutoTraceSession& session)
GCRuntime::beginSweepPhase(JS::gcreason::Reason reason, AutoGCSession& session)
{
/*
* Sweep phase.
@ -6759,7 +6756,7 @@ GCRuntime::beginCompactPhase()
IncrementalProgress
GCRuntime::compactPhase(JS::gcreason::Reason reason, SliceBudget& sliceBudget,
AutoTraceSession& session)
AutoGCSession& session)
{
assertBackgroundSweepingFinished();
MOZ_ASSERT(startedCompacting);
@ -6870,7 +6867,7 @@ HeapStateToLabel(JS::HeapState heapState)
}
/* Start a new heap session. */
AutoTraceSession::AutoTraceSession(JSRuntime* rt, JS::HeapState heapState)
AutoHeapSession::AutoHeapSession(JSRuntime* rt, JS::HeapState heapState)
: runtime(rt),
prevState(rt->heapState_),
profilingStackFrame(rt->mainContextFromOwnThread(), HeapStateToLabel(heapState),
@ -6881,13 +6878,10 @@ AutoTraceSession::AutoTraceSession(JSRuntime* rt, JS::HeapState heapState)
MOZ_ASSERT(heapState != JS::HeapState::Idle);
MOZ_ASSERT_IF(heapState == JS::HeapState::MajorCollecting, rt->gc.nursery().isEmpty());
// Session always begins with lock held, see comment in class definition.
maybeLock.emplace(rt);
rt->heapState_ = heapState;
}
AutoTraceSession::~AutoTraceSession()
AutoHeapSession::~AutoHeapSession()
{
MOZ_ASSERT(JS::RuntimeHeapIsBusy());
runtime->heapState_ = prevState;
@ -6900,7 +6894,7 @@ JS::RuntimeHeapState()
}
GCRuntime::IncrementalResult
GCRuntime::resetIncrementalGC(gc::AbortReason reason, AutoTraceSession& session)
GCRuntime::resetIncrementalGC(gc::AbortReason reason, AutoGCSession& session)
{
MOZ_ASSERT(reason != gc::AbortReason::None);
@ -7092,15 +7086,8 @@ ShouldCleanUpEverything(JS::gcreason::Reason reason, JSGCInvocationKind gckind)
void
GCRuntime::incrementalCollectSlice(SliceBudget& budget, JS::gcreason::Reason reason,
AutoTraceSession& session)
AutoGCSession& session)
{
/*
* Drop the exclusive access lock if we are in an incremental collection
* that does not touch the atoms zone.
*/
if (isIncrementalGCInProgress() && !atomsZone->isCollecting())
session.maybeLock.reset();
AutoDisableBarriers disableBarriers(rt);
bool destroyingRuntime = (reason == JS::gcreason::DESTROY_RUNTIME);
@ -7328,7 +7315,7 @@ CheckZoneIsScheduled(Zone* zone, JS::gcreason::Reason reason, const char* trigge
GCRuntime::IncrementalResult
GCRuntime::budgetIncrementalGC(bool nonincrementalByAPI, JS::gcreason::Reason reason,
SliceBudget& budget, AutoTraceSession& session)
SliceBudget& budget, AutoGCSession& session)
{
if (nonincrementalByAPI) {
stats().nonincremental(gc::AbortReason::NonIncrementalRequested);
@ -7495,7 +7482,7 @@ GCRuntime::gcCycle(bool nonincrementalByAPI, SliceBudget& budget, JS::gcreason::
minorGC(reason, gcstats::PhaseKind::EVICT_NURSERY_FOR_MAJOR_GC);
AutoTraceSession session(rt, JS::HeapState::MajorCollecting);
AutoGCSession session(rt, JS::HeapState::MajorCollecting);
majorGCTriggerReason = JS::gcreason::NO_REASON;
@ -7528,8 +7515,9 @@ GCRuntime::gcCycle(bool nonincrementalByAPI, SliceBudget& budget, JS::gcreason::
}
// We don't allow off-thread parsing to start while we're doing an
// incremental GC.
MOZ_ASSERT_IF(rt->activeGCInAtomsZone(), !rt->hasHelperThreadZones());
// incremental GC of the atoms zone.
if (rt->activeGCInAtomsZone())
session.maybeCheckAtomsAccess.emplace(rt);
auto result = budgetIncrementalGC(nonincrementalByAPI, reason, budget, session);
@ -7973,12 +7961,6 @@ js::gc::FinishGC(JSContext* cx)
cx->nursery().waitBackgroundFreeEnd();
}
AutoPrepareForTracing::AutoPrepareForTracing(JSContext* cx)
{
js::gc::FinishGC(cx);
session_.emplace(cx->runtime());
}
Realm*
js::NewRealm(JSContext* cx, JSPrincipals* principals, const JS::RealmOptions& options)
{

Просмотреть файл

@ -14,6 +14,7 @@
#include "mozilla/ArrayUtils.h"
#include "mozilla/Maybe.h"
#include "gc/GC.h"
#include "gc/RelocationOverlay.h"
#include "gc/Zone.h"
#include "vm/HelperThreads.h"
@ -22,43 +23,94 @@
namespace js {
namespace gc {
/*
* This class should be used by any code that needs to exclusive access to the
* heap in order to trace through it...
*/
class MOZ_RAII AutoTraceSession
class MOZ_RAII AutoCheckCanAccessAtomsDuringGC
{
public:
explicit AutoTraceSession(JSRuntime* rt, JS::HeapState state = JS::HeapState::Tracing);
~AutoTraceSession();
// Constructing an AutoTraceSession takes the exclusive access lock, but GC
// may release it during a trace session if we're not collecting the atoms
// zone.
mozilla::Maybe<AutoLockForExclusiveAccess> maybeLock;
AutoLockForExclusiveAccess& lock() {
return maybeLock.ref();
}
protected:
#ifdef DEBUG
JSRuntime* runtime;
private:
AutoTraceSession(const AutoTraceSession&) = delete;
void operator=(const AutoTraceSession&) = delete;
public:
explicit AutoCheckCanAccessAtomsDuringGC(JSRuntime* rt)
: runtime(rt)
{
// Ensure we're only used from within the GC.
MOZ_ASSERT(JS::RuntimeHeapIsMajorCollecting());
// Ensure there is no off-thread parsing running.
MOZ_ASSERT(!rt->hasHelperThreadZones());
// Set up a check to assert if we try to start an off-thread parse.
runtime->setOffThreadParsingBlocked(true);
}
~AutoCheckCanAccessAtomsDuringGC() {
runtime->setOffThreadParsingBlocked(false);
}
#else
public:
explicit AutoCheckCanAccessAtomsDuringGC(JSRuntime* rt) {}
#endif
};
// Abstract base class for exclusive heap access for tracing or GC.
class MOZ_RAII AutoHeapSession
{
public:
~AutoHeapSession();
protected:
AutoHeapSession(JSRuntime* rt, JS::HeapState state);
private:
AutoHeapSession(const AutoHeapSession&) = delete;
void operator=(const AutoHeapSession&) = delete;
JSRuntime* runtime;
JS::HeapState prevState;
AutoGeckoProfilerEntry profilingStackFrame;
};
class MOZ_RAII AutoPrepareForTracing
class MOZ_RAII AutoGCSession : public AutoHeapSession
{
mozilla::Maybe<AutoTraceSession> session_;
public:
explicit AutoPrepareForTracing(JSContext* cx);
AutoTraceSession& session() { return session_.ref(); }
explicit AutoGCSession(JSRuntime* rt, JS::HeapState state)
: AutoHeapSession(rt, state)
{}
AutoCheckCanAccessAtomsDuringGC& checkAtomsAccess() {
return maybeCheckAtomsAccess.ref();
}
// During a GC we can check that it's not possible for anything else to be
// using the atoms zone.
mozilla::Maybe<AutoCheckCanAccessAtomsDuringGC> maybeCheckAtomsAccess;
};
class MOZ_RAII AutoTraceSession : public AutoLockForExclusiveAccess,
public AutoHeapSession
{
public:
explicit AutoTraceSession(JSRuntime* rt)
: AutoLockForExclusiveAccess(rt),
AutoHeapSession(rt, JS::HeapState::Tracing)
{}
};
struct MOZ_RAII AutoFinishGC
{
explicit AutoFinishGC(JSContext* cx) {
FinishGC(cx);
}
};
// This class should be used by any code that needs to exclusive access to the
// heap in order to trace through it.
class MOZ_RAII AutoPrepareForTracing : private AutoFinishGC,
public AutoTraceSession
{
public:
explicit AutoPrepareForTracing(JSContext* cx)
: AutoFinishGC(cx),
AutoTraceSession(cx->runtime())
{}
};
AbortReason

Просмотреть файл

@ -14,6 +14,7 @@
namespace js {
class AutoAccessAtomsZone;
class WeakMapBase;
static const size_t NON_INCREMENTAL_MARK_STACK_BASE_CAPACITY = 4096;
@ -281,7 +282,7 @@ class GCMarker : public JSTracer
void setGCMode(JSGCMode mode) { stack.setGCMode(mode); }
size_t sizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf,
const AutoLockForExclusiveAccess& lock) const;
const AutoAccessAtomsZone& access) const;
#ifdef DEBUG

Просмотреть файл

@ -26,6 +26,7 @@
namespace js {
class AutoAccessAtomsZone;
class AutoLockGC;
class AutoLockGCBgAlloc;
class AutoLockHelperThreadState;
@ -37,6 +38,7 @@ using BlackGrayEdgeVector = Vector<TenuredCell*, 0, SystemAllocPolicy>;
using ZoneVector = Vector<JS::Zone*, 4, SystemAllocPolicy>;
class AutoCallGCCallbacks;
class AutoGCSession;
class AutoRunParallelTask;
class AutoTraceSession;
class MarkingValidator;
@ -264,7 +266,7 @@ class GCRuntime
MarkRuntime
};
void traceRuntime(JSTracer* trc, AutoTraceSession& session);
void traceRuntimeForMinorGC(JSTracer* trc, AutoTraceSession& session);
void traceRuntimeForMinorGC(JSTracer* trc, AutoGCSession& session);
void purgeRuntimeForMinorGC();
@ -540,8 +542,8 @@ class GCRuntime
void requestMajorGC(JS::gcreason::Reason reason);
SliceBudget defaultBudget(JS::gcreason::Reason reason, int64_t millis);
IncrementalResult budgetIncrementalGC(bool nonincrementalByAPI, JS::gcreason::Reason reason,
SliceBudget& budget, AutoTraceSession& session);
IncrementalResult resetIncrementalGC(AbortReason reason, AutoTraceSession& session);
SliceBudget& budget, AutoGCSession& session);
IncrementalResult resetIncrementalGC(AbortReason reason, AutoGCSession& session);
// Assert if the system state is such that we should never
// receive a request to do GC work.
@ -557,23 +559,21 @@ class GCRuntime
JS::gcreason::Reason reason);
bool shouldRepeatForDeadZone(JS::gcreason::Reason reason);
void incrementalCollectSlice(SliceBudget& budget, JS::gcreason::Reason reason,
AutoTraceSession& session);
AutoGCSession& session);
friend class AutoCallGCCallbacks;
void maybeCallGCCallback(JSGCStatus status);
void pushZealSelectedObjects();
void purgeRuntime();
MOZ_MUST_USE bool beginMarkPhase(JS::gcreason::Reason reason, AutoTraceSession& session);
bool prepareZonesForCollection(JS::gcreason::Reason reason, bool* isFullOut,
AutoLockForExclusiveAccess& lock);
MOZ_MUST_USE bool beginMarkPhase(JS::gcreason::Reason reason, AutoGCSession& session);
bool prepareZonesForCollection(JS::gcreason::Reason reason, bool* isFullOut);
bool shouldPreserveJITCode(JS::Realm* realm, int64_t currentTime,
JS::gcreason::Reason reason, bool canAllocateMoreCode);
void traceRuntimeForMajorGC(JSTracer* trc, AutoTraceSession& session);
void traceRuntimeAtoms(JSTracer* trc, AutoLockForExclusiveAccess& lock);
void traceRuntimeForMajorGC(JSTracer* trc, AutoGCSession& session);
void traceRuntimeAtoms(JSTracer* trc, const AutoAccessAtomsZone& atomsAccess);
void traceKeptAtoms(JSTracer* trc);
void traceRuntimeCommon(JSTracer* trc, TraceOrMarkRuntime traceOrMark,
AutoTraceSession& session);
void traceRuntimeCommon(JSTracer* trc, TraceOrMarkRuntime traceOrMark);
void maybeDoCycleCollection();
void markCompartments();
IncrementalProgress drainMarkStack(SliceBudget& sliceBudget, gcstats::PhaseKind phase);
@ -585,7 +585,7 @@ class GCRuntime
void markAllWeakReferences(gcstats::PhaseKind phase);
void markAllGrayReferences(gcstats::PhaseKind phase);
void beginSweepPhase(JS::gcreason::Reason reason, AutoTraceSession& session);
void beginSweepPhase(JS::gcreason::Reason reason, AutoGCSession& session);
void groupZonesForSweeping(JS::gcreason::Reason reason);
MOZ_MUST_USE bool findInterZoneEdges();
void getNextSweepGroup();
@ -618,7 +618,7 @@ class GCRuntime
bool shouldCompact();
void beginCompactPhase();
IncrementalProgress compactPhase(JS::gcreason::Reason reason, SliceBudget& sliceBudget,
AutoTraceSession& session);
AutoGCSession& session);
void endCompactPhase();
void sweepTypesAfterCompacting(Zone* zone);
void sweepZoneAfterCompacting(Zone* zone);
@ -628,14 +628,14 @@ class GCRuntime
void updateCellPointers(Zone* zone, AllocKinds kinds, size_t bgTaskCount);
void updateAllCellPointers(MovingTracer* trc, Zone* zone);
void updateZonePointersToRelocatedCells(Zone* zone);
void updateRuntimePointersToRelocatedCells(AutoTraceSession& session);
void updateRuntimePointersToRelocatedCells(AutoGCSession& session);
void protectAndHoldArenas(Arena* arenaList);
void unprotectHeldRelocatedArenas();
void releaseRelocatedArenas(Arena* arenaList);
void releaseRelocatedArenasWithoutUnlocking(Arena* arenaList, const AutoLockGC& lock);
void finishCollection();
void computeNonIncrementalMarkingForValidation(AutoTraceSession& session);
void computeNonIncrementalMarkingForValidation(AutoGCSession& session);
void validateIncrementalMarking();
void finishMarkingValidation();
@ -992,7 +992,6 @@ class GCRuntime
friend class js::GCHelperState;
friend class MarkingValidator;
friend class AutoTraceSession;
friend class AutoEnterIteration;
};

Просмотреть файл

@ -2563,7 +2563,7 @@ GCMarker::checkZone(void* p)
size_t
GCMarker::sizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf,
const AutoLockForExclusiveAccess& lock) const
const AutoAccessAtomsZone& access) const
{
size_t size = stack.sizeOfExcludingThis(mallocSizeOf);
for (ZonesIter zone(runtime(), WithAtoms); !zone.done(); zone.next())

Просмотреть файл

@ -772,7 +772,7 @@ js::Nursery::collect(JS::gcreason::Reason reason)
}
}
mozilla::Maybe<AutoTraceSession> session;
mozilla::Maybe<AutoGCSession> session;
for (ZonesIter zone(rt, SkipAtoms); !zone.done(); zone.next()) {
if (shouldPretenure && zone->allocNurseryStrings && zone->tenuredStrings >= 30 * 1000) {
if (!session.isSome())
@ -846,7 +846,7 @@ void
js::Nursery::doCollection(JS::gcreason::Reason reason, TenureCountCache& tenureCounts)
{
JSRuntime* rt = runtime();
AutoTraceSession session(rt, JS::HeapState::MinorCollecting);
AutoGCSession session(rt, JS::HeapState::MinorCollecting);
AutoSetThreadIsPerformingGC performingGC;
AutoStopVerifyingBarriers av(rt, false);
AutoDisableProxyCheck disableStrictProxyChecking;

Просмотреть файл

@ -51,7 +51,7 @@ js::IterateHeapUnbarriered(JSContext* cx, void* data,
IterateArenaCallback arenaCallback,
IterateCellCallback cellCallback)
{
AutoPrepareForTracing prop(cx);
AutoPrepareForTracing prep(cx);
for (ZonesIter zone(cx->runtime(), WithAtoms); !zone.done(); zone.next()) {
(*zoneCallback)(cx->runtime(), data, zone);
@ -67,7 +67,7 @@ js::IterateHeapUnbarrieredForZone(JSContext* cx, Zone* zone, void* data,
IterateArenaCallback arenaCallback,
IterateCellCallback cellCallback)
{
AutoPrepareForTracing prop(cx);
AutoPrepareForTracing prep(cx);
(*zoneCallback)(cx->runtime(), data, zone);
IterateRealmsArenasCellsUnbarriered(cx, zone, data,

Просмотреть файл

@ -262,10 +262,9 @@ PropertyDescriptor::trace(JSTracer* trc)
}
void
js::gc::GCRuntime::traceRuntimeForMajorGC(JSTracer* trc, AutoTraceSession& session)
js::gc::GCRuntime::traceRuntimeForMajorGC(JSTracer* trc, AutoGCSession& session)
{
MOZ_ASSERT(!TlsContext.get()->suppressGC);
MOZ_ASSERT_IF(atomsZone->isCollecting(), session.maybeLock.isSome());
// FinishRoots will have asserted that every root that we do not expect
// is gone, so we can simply skip traceRuntime here.
@ -274,14 +273,14 @@ js::gc::GCRuntime::traceRuntimeForMajorGC(JSTracer* trc, AutoTraceSession& sessi
gcstats::AutoPhase ap(stats(), gcstats::PhaseKind::MARK_ROOTS);
if (atomsZone->isCollecting())
traceRuntimeAtoms(trc, session.lock());
traceRuntimeAtoms(trc, session.checkAtomsAccess());
traceKeptAtoms(trc);
Compartment::traceIncomingCrossCompartmentEdgesForZoneGC(trc);
traceRuntimeCommon(trc, MarkRuntime, session);
traceRuntimeCommon(trc, MarkRuntime);
}
void
js::gc::GCRuntime::traceRuntimeForMinorGC(JSTracer* trc, AutoTraceSession& session)
js::gc::GCRuntime::traceRuntimeForMinorGC(JSTracer* trc, AutoGCSession& session)
{
MOZ_ASSERT(!TlsContext.get()->suppressGC);
@ -296,7 +295,7 @@ js::gc::GCRuntime::traceRuntimeForMinorGC(JSTracer* trc, AutoTraceSession& sessi
jit::JitRuntime::TraceJitcodeGlobalTableForMinorGC(trc);
traceRuntimeCommon(trc, TraceRuntime, session);
traceRuntimeCommon(trc, TraceRuntime);
}
void
@ -308,7 +307,7 @@ js::TraceRuntime(JSTracer* trc)
rt->gc.evictNursery();
AutoPrepareForTracing prep(rt->mainContextFromOwnThread());
gcstats::AutoPhase ap(rt->gc.stats(), gcstats::PhaseKind::TRACE_HEAP);
rt->gc.traceRuntime(trc, prep.session());
rt->gc.traceRuntime(trc, prep);
}
void
@ -317,18 +316,19 @@ js::gc::GCRuntime::traceRuntime(JSTracer* trc, AutoTraceSession& session)
MOZ_ASSERT(!rt->isBeingDestroyed());
gcstats::AutoPhase ap(stats(), gcstats::PhaseKind::MARK_ROOTS);
traceRuntimeAtoms(trc, session.lock());
traceRuntimeCommon(trc, TraceRuntime, session);
traceRuntimeAtoms(trc, session);
traceRuntimeCommon(trc, TraceRuntime);
}
void
js::gc::GCRuntime::traceRuntimeAtoms(JSTracer* trc, AutoLockForExclusiveAccess& lock)
js::gc::GCRuntime::traceRuntimeAtoms(JSTracer* trc, const AutoAccessAtomsZone& access)
{
gcstats::AutoPhase ap(stats(), gcstats::PhaseKind::MARK_RUNTIME_DATA);
TracePermanentAtoms(trc);
TraceAtoms(trc, lock);
TraceAtoms(trc, access);
TraceWellKnownSymbols(trc);
jit::JitRuntime::Trace(trc, lock);
jit::JitRuntime::Trace(trc, access);
}
void
@ -344,8 +344,7 @@ js::gc::GCRuntime::traceKeptAtoms(JSTracer* trc)
}
void
js::gc::GCRuntime::traceRuntimeCommon(JSTracer* trc, TraceOrMarkRuntime traceOrMark,
AutoTraceSession& session)
js::gc::GCRuntime::traceRuntimeCommon(JSTracer* trc, TraceOrMarkRuntime traceOrMark)
{
{
gcstats::AutoPhase ap(stats(), gcstats::PhaseKind::MARK_STACK);
@ -386,7 +385,7 @@ js::gc::GCRuntime::traceRuntimeCommon(JSTracer* trc, TraceOrMarkRuntime traceOrM
r->traceRoots(trc, traceOrMark);
// Trace helper thread roots.
HelperThreadState().trace(trc, session);
HelperThreadState().trace(trc);
// Trace the embedding's black and gray roots.
if (!JS::RuntimeHeapIsMinorCollecting()) {
@ -450,9 +449,9 @@ js::gc::GCRuntime::finishRoots()
grayRootTracer = Callback<JSTraceDataOp>(nullptr, nullptr);
AssertNoRootsTracer trc(rt, TraceWeakMapKeysValues);
AutoPrepareForTracing prep(TlsContext.get());
AutoTraceSession session(rt);
gcstats::AutoPhase ap(rt->gc.stats(), gcstats::PhaseKind::TRACE_HEAP);
traceRuntime(&trc, prep.session());
traceRuntime(&trc, session);
// Restore the wrapper tracing so that we leak instead of leaving dangling
// pointers.

Просмотреть файл

@ -221,7 +221,7 @@ gc::GCRuntime::startVerifyPreBarriers()
incrementalState = State::MarkRoots;
/* Make all the roots be edges emanating from the root node. */
traceRuntime(trc, prep.session());
traceRuntime(trc, prep);
VerifyNode* node;
node = trc->curnode;
@ -655,7 +655,7 @@ CheckHeapTracer::check(AutoTraceSession& session)
void
js::gc::CheckHeapAfterGC(JSRuntime* rt)
{
AutoTraceSession session(rt, JS::HeapState::Tracing);
AutoTraceSession session(rt);
CheckHeapTracer tracer(rt);
if (tracer.init())
tracer.check(session);
@ -724,7 +724,7 @@ js::CheckGrayMarkingState(JSRuntime* rt)
return true;
gcstats::AutoPhase ap(rt->gc.stats(), gcstats::PhaseKind::TRACE_HEAP);
AutoTraceSession session(rt, JS::HeapState::Tracing);
AutoTraceSession session(rt);
CheckGrayMarkingTracer tracer(rt);
if (!tracer.init())
return true; // Ignore failure

Просмотреть файл

@ -61,12 +61,12 @@ JS::Zone::Zone(JSRuntime* rt)
data(this, nullptr),
isSystem(this, false),
#ifdef DEBUG
gcLastSweepGroupIndex(this, 0),
gcLastSweepGroupIndex(0),
#endif
jitZone_(this, nullptr),
gcScheduled_(false),
gcScheduledSaved_(false),
gcPreserveCode_(this, false),
gcPreserveCode_(false),
keepShapeTables_(this, false),
listNext_(NotOnList)
{

Просмотреть файл

@ -583,7 +583,7 @@ class Zone : public JS::shadow::Zone,
js::ZoneData<bool> isSystem;
#ifdef DEBUG
js::ZoneData<unsigned> gcLastSweepGroupIndex;
js::MainThreadData<unsigned> gcLastSweepGroupIndex;
#endif
static js::HashNumber UniqueIdToHash(uint64_t uid) {
@ -737,11 +737,11 @@ class Zone : public JS::shadow::Zone,
uint32_t detachedTypedObjects = 0;
private:
js::ZoneData<js::jit::JitZone*> jitZone_;
js::ZoneOrGCTaskData<js::jit::JitZone*> jitZone_;
js::MainThreadData<bool> gcScheduled_;
js::MainThreadData<bool> gcScheduledSaved_;
js::ZoneData<bool> gcPreserveCode_;
js::MainThreadData<bool> gcPreserveCode_;
js::ZoneData<bool> keepShapeTables_;
// Allow zones to be linked into a list

Просмотреть файл

@ -582,7 +582,7 @@ jit::LazyLinkTopActivation(JSContext* cx, LazyLinkExitFrameLayout* frame)
}
/* static */ void
JitRuntime::Trace(JSTracer* trc, AutoLockForExclusiveAccess& lock)
JitRuntime::Trace(JSTracer* trc, const AutoAccessAtomsZone& access)
{
MOZ_ASSERT(!JS::RuntimeHeapIsMinorCollecting());
@ -591,7 +591,7 @@ JitRuntime::Trace(JSTracer* trc, AutoLockForExclusiveAccess& lock)
if (trc->runtime()->atomsAreFinished())
return;
Zone* zone = trc->runtime()->atomsZone(lock);
Zone* zone = trc->runtime()->atomsZone(access);
for (auto i = zone->cellIter<JitCode>(); !i.done(); i.next()) {
JitCode* code = i;
TraceRoot(trc, &code, "wrapper");

Просмотреть файл

@ -193,7 +193,7 @@ class JitRuntime
~JitRuntime();
MOZ_MUST_USE bool initialize(JSContext* cx, js::AutoLockForExclusiveAccess& lock);
static void Trace(JSTracer* trc, js::AutoLockForExclusiveAccess& lock);
static void Trace(JSTracer* trc, const js::AutoAccessAtomsZone& access);
static void TraceJitcodeGlobalTableForMinorGC(JSTracer* trc);
static MOZ_MUST_USE bool MarkJitcodeGlobalTableIteratively(GCMarker* marker);
static void SweepJitcodeGlobalTable(JSRuntime* rt);

Просмотреть файл

@ -1252,9 +1252,9 @@ js::DumpHeap(JSContext* cx, FILE* fp, js::DumpHeapNurseryBehaviour nurseryBehavi
fprintf(dtrc.output, "# Roots.\n");
{
JSRuntime* rt = cx->runtime();
js::gc::AutoPrepareForTracing prep(cx);
js::gc::AutoTraceSession session(rt);
gcstats::AutoPhase ap(rt->gc.stats(), gcstats::PhaseKind::TRACE_HEAP);
rt->gc.traceRuntime(&dtrc, prep.session());
rt->gc.traceRuntime(&dtrc, session);
}
fprintf(dtrc.output, "# Weak maps.\n");

Просмотреть файл

@ -65,17 +65,19 @@ CheckZone<Helper>::check() const
if (OnHelperThread<Helper>())
return;
JSContext* cx = TlsContext.get();
JSRuntime* runtime = TlsContext.get()->runtime();
if (zone->isAtomsZone()) {
// The atoms zone is protected by the exclusive access lock.
MOZ_ASSERT(cx->runtime()->currentThreadHasExclusiveAccess());
// The atoms zone is protected by the exclusive access lock, but can be
// also accessed when off-thread parsing is blocked.
MOZ_ASSERT(runtime->currentThreadHasExclusiveAccess() ||
(!runtime->isOffThreadParseRunning() && runtime->isOffThreadParsingBlocked()));
} else if (zone->usedByHelperThread()) {
// This may only be accessed by the helper thread using this zone.
MOZ_ASSERT(zone->ownedByCurrentHelperThread());
} else {
// The main thread is permitted access to all zones. These accesses
// are threadsafe if the zone is not in use by a helper thread.
MOZ_ASSERT(CurrentThreadCanAccessRuntime(cx->runtime()));
MOZ_ASSERT(CurrentThreadCanAccessRuntime(runtime));
}
}

Просмотреть файл

@ -13,10 +13,24 @@
# if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__DragonFly__)
# include <pthread_np.h>
# endif
# if defined(SOLARIS) || defined(AIX)
# include <ucontext.h>
# endif
# if defined(ANDROID) && !defined(__aarch64__)
# include <sys/types.h>
# include <unistd.h>
# endif
# if defined(XP_LINUX) && !defined(ANDROID) && defined(__GLIBC__)
# include <dlfcn.h>
# include <sys/syscall.h>
# include <sys/types.h>
# include <unistd.h>
static pid_t
gettid()
{
return syscall(__NR_gettid);
}
# endif
#else
# error "Unsupported platform"
#endif
@ -34,8 +48,6 @@ js::GetNativeStackBaseImpl()
#elif defined(SOLARIS)
#include <ucontext.h>
JS_STATIC_ASSERT(JS_STACK_GROWTH_DIRECTION < 0);
void*
@ -48,8 +60,6 @@ js::GetNativeStackBaseImpl()
#elif defined(AIX)
#include <ucontext.h>
JS_STATIC_ASSERT(JS_STACK_GROWTH_DIRECTION < 0);
void*
@ -61,6 +71,52 @@ js::GetNativeStackBaseImpl()
context.uc_stack.ss_size;
}
#elif defined(XP_LINUX) && !defined(ANDROID) && defined(__GLIBC__)
void*
js::GetNativeStackBaseImpl()
{
// On the main thread, get stack base from glibc's __libc_stack_end rather than pthread APIs
// to avoid filesystem calls /proc/self/maps. Non-main threads spawned with pthreads can read
// this information directly from their pthread struct, but the main thread must go parse
// /proc/self/maps to figure the mapped stack address space ranges. We want to avoid reading
// from /proc/ so that firefox can run in sandboxed environments where /proc may not be mounted
if (gettid() == getpid()) {
void** pLibcStackEnd = (void**)dlsym(RTLD_DEFAULT, "__libc_stack_end");
// If __libc_stack_end is not found, architecture specific frame pointer hopping will need
// to be implemented.
MOZ_RELEASE_ASSERT(pLibcStackEnd, "__libc_stack_end unavailable, unable to setup stack range for JS");
void* stackBase = *pLibcStackEnd;
MOZ_RELEASE_ASSERT(stackBase, "invalid stack base, unable to setup stack range for JS");
// We don't need to fix stackBase, as it already roughly points to beginning of the stack
return stackBase;
}
// Non-main threads have the required info stored in memory, so no filesystem calls are made.
pthread_t thread = pthread_self();
pthread_attr_t sattr;
pthread_attr_init(&sattr);
pthread_getattr_np(thread, &sattr);
// stackBase will be the *lowest* address on all architectures.
void* stackBase = nullptr;
size_t stackSize = 0;
int rc = pthread_attr_getstack(&sattr, &stackBase, &stackSize);
if (rc) {
MOZ_CRASH("call to pthread_attr_getstack failed, unable to setup stack range for JS");
}
MOZ_RELEASE_ASSERT(stackBase, "invalid stack base, unable to setup stack range for JS");
pthread_attr_destroy(&sattr);
# if JS_STACK_GROWTH_DIRECTION > 0
return stackBase;
# else
return static_cast<char*>(stackBase) + stackSize;
# endif
}
#else /* XP_UNIX */
void*

Просмотреть файл

@ -2896,6 +2896,7 @@ GenerateLcovInfo(JSContext* cx, JS::Realm* realm, GenericPrinter& out)
{
js::gc::AutoPrepareForTracing apft(cx);
}
Rooted<ScriptVector> topScripts(cx, ScriptVector(cx));
for (ZonesIter zone(rt, SkipAtoms); !zone.done(); zone.next()) {
for (auto script = zone->cellIter<JSScript>(); !script.done(); script.next()) {

Просмотреть файл

@ -2099,9 +2099,12 @@ HelperThread::handleParseWorkload(AutoLockHelperThreadState& locked)
currentTask.emplace(HelperThreadState().parseWorklist(locked).popCopy());
ParseTask* task = parseTask();
JSRuntime* runtime = task->parseGlobal->runtimeFromAnyThread();
runtime->incOffThreadParsesRunning();
{
AutoUnlockHelperThreadState unlock(locked);
AutoSetContextRuntime ascr(task->parseGlobal->runtimeFromAnyThread());
AutoSetContextRuntime ascr(runtime);
JSContext* cx = TlsContext.get();
@ -2125,6 +2128,8 @@ HelperThread::handleParseWorkload(AutoLockHelperThreadState& locked)
// migrate it into the correct compartment.
HelperThreadState().parseFinishedList(locked).insertBack(task);
runtime->decOffThreadParsesRunning();
currentTask.reset();
// Notify the main thread in case it is waiting for the parse/emit to finish.
@ -2267,7 +2272,7 @@ js::StartOffThreadPromiseHelperTask(PromiseHelperTask* task)
}
void
GlobalHelperThreadState::trace(JSTracer* trc, gc::AutoTraceSession& session)
GlobalHelperThreadState::trace(JSTracer* trc)
{
AutoLockHelperThreadState lock;
for (auto builder : ionWorklist(lock))

Просмотреть файл

@ -311,7 +311,7 @@ class GlobalHelperThreadState
void mergeParseTaskRealm(JSContext* cx, ParseTask* parseTask, JS::Realm* dest);
void trace(JSTracer* trc, js::gc::AutoTraceSession& session);
void trace(JSTracer* trc);
JSScript* finishScriptParseTask(JSContext* cx, JS::OffThreadToken* token);
JSScript* finishScriptDecodeTask(JSContext* cx, JS::OffThreadToken* token);

Просмотреть файл

@ -255,14 +255,14 @@ TracePinnedAtoms(JSTracer* trc, const AtomSet& atoms)
}
void
js::TraceAtoms(JSTracer* trc, AutoLockForExclusiveAccess& lock)
js::TraceAtoms(JSTracer* trc, const AutoAccessAtomsZone& access)
{
JSRuntime* rt = trc->runtime();
if (rt->atomsAreFinished())
return;
TracePinnedAtoms(trc, rt->atoms(lock));
TracePinnedAtoms(trc, rt->atoms(access));
if (rt->atomsAddedWhileSweeping())
TracePinnedAtoms(trc, *rt->atomsAddedWhileSweeping());
}

Просмотреть файл

@ -39,13 +39,13 @@ FOR_EACH_COMMON_PROPERTYNAME(DECLARE_CONST_CHAR_STR)
namespace js {
class AutoLockForExclusiveAccess;
class AutoAccessAtomsZone;
/*
* Atom tracing and garbage collection hooks.
*/
void
TraceAtoms(JSTracer* trc, AutoLockForExclusiveAccess& lock);
TraceAtoms(JSTracer* trc, const AutoAccessAtomsZone& atomsAccess);
void
TracePermanentAtoms(JSTracer* trc);

Просмотреть файл

@ -34,6 +34,7 @@ class DebugModeOSRVolatileJitFrameIter;
} // namespace jit
namespace gc {
class AutoCheckCanAccessAtomsDuringGC;
class AutoSuppressNurseryCellAlloc;
}
@ -264,14 +265,14 @@ struct JSContext : public JS::RootingContext,
inline js::Handle<js::GlobalObject*> global() const;
// Methods to access runtime data that must be protected by locks.
js::AtomSet& atoms(js::AutoLockForExclusiveAccess& lock) {
return runtime_->atoms(lock);
js::AtomSet& atoms(const js::AutoAccessAtomsZone& access) {
return runtime_->atoms(access);
}
const JS::Zone* atomsZone(js::AutoLockForExclusiveAccess& lock) {
return runtime_->atomsZone(lock);
const JS::Zone* atomsZone(const js::AutoAccessAtomsZone& access) {
return runtime_->atomsZone(access);
}
js::SymbolRegistry& symbolRegistry(js::AutoLockForExclusiveAccess& lock) {
return runtime_->symbolRegistry(lock);
js::SymbolRegistry& symbolRegistry(const js::AutoAccessAtomsZone& access) {
return runtime_->symbolRegistry(access);
}
js::ScriptDataTable& scriptDataTable(js::AutoLockScriptData& lock) {
return runtime_->scriptDataTable(lock);
@ -540,6 +541,8 @@ struct JSContext : public JS::RootingContext,
js::ThreadData<unsigned> compactingDisabledCount;
bool canCollectAtoms() const {
// TODO: We may be able to improve this by collecting if
// !isOffThreadParseRunning() (bug 1468422).
return !runtime()->hasHelperThreadZones();
}
@ -1170,6 +1173,22 @@ class MOZ_RAII AutoLockScriptData
MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
};
// A token used to prove you can safely access the atoms zone. This zone is
// accessed by the main thread and by off-thread parsing. There are two
// situations in which it is safe:
//
// - the current thread holds the exclusive access lock (off-thread parsing may
// be running and this must also take the lock for access)
//
// - the GC is running and is collecting the atoms zone (this cannot be started
// while off-thread parsing is happening)
class MOZ_STACK_CLASS AutoAccessAtomsZone
{
public:
MOZ_IMPLICIT AutoAccessAtomsZone(const AutoLockForExclusiveAccess& lock) {}
MOZ_IMPLICIT AutoAccessAtomsZone(const gc::AutoCheckCanAccessAtomsDuringGC& canAccess) {}
};
class MOZ_RAII AutoKeepAtoms
{
JSContext* cx;

Просмотреть файл

@ -166,6 +166,10 @@ JSRuntime::JSRuntime(JSRuntime* parentRuntime)
jitSupportsSimd(false),
offthreadIonCompilationEnabled_(true),
parallelParsingEnabled_(true),
#ifdef DEBUG
offThreadParsesRunning_(0),
offThreadParsingBlocked_(false),
#endif
autoWritableJitCodeActive_(false),
oomCallback(nullptr),
debuggerMallocSizeOf(ReturnZeroSize),
@ -808,6 +812,7 @@ JSRuntime::setUsedByHelperThread(Zone* zone)
{
MOZ_ASSERT(!zone->usedByHelperThread());
MOZ_ASSERT(!zone->wasGCStarted());
MOZ_ASSERT(!isOffThreadParsingBlocked());
zone->setUsedByHelperThread();
numActiveHelperThreadZones++;
}

Просмотреть файл

@ -61,6 +61,10 @@ class EnterDebuggeeNoExecute;
class TraceLoggerThread;
#endif
namespace gc {
class AutoHeapSession;
}
} // namespace js
struct DtoaState;
@ -702,15 +706,15 @@ struct JSRuntime : public js::MallocProvider<JSRuntime>
private:
// Set of all atoms other than those in permanentAtoms and staticStrings.
// Reading or writing this set requires the calling thread to use
// AutoLockForExclusiveAccess.
// AutoAccessAtomsZone.
js::ExclusiveAccessLockOrGCTaskData<js::AtomSet*> atoms_;
// Set of all atoms added while the main atoms table is being swept.
js::ExclusiveAccessLockData<js::AtomSet*> atomsAddedWhileSweeping_;
js::ExclusiveAccessLockOrGCTaskData<js::AtomSet*> atomsAddedWhileSweeping_;
// Set of all live symbols produced by Symbol.for(). All such symbols are
// allocated in the atomsZone. Reading or writing the symbol registry
// requires the calling thread to use AutoLockForExclusiveAccess.
// allocated in the atoms zone. Reading or writing the symbol registry
// requires the calling thread to use AutoAccessAtomsZone.
js::ExclusiveAccessLockOrGCTaskData<js::SymbolRegistry> symbolRegistry_;
public:
@ -723,7 +727,7 @@ struct JSRuntime : public js::MallocProvider<JSRuntime>
return atoms_;
}
js::AtomSet& atoms(js::AutoLockForExclusiveAccess& lock) {
js::AtomSet& atoms(const js::AutoAccessAtomsZone& access) {
MOZ_ASSERT(atoms_);
return *atoms_;
}
@ -738,10 +742,10 @@ struct JSRuntime : public js::MallocProvider<JSRuntime>
return atomsAddedWhileSweeping_;
}
const JS::Zone* atomsZone(const js::AutoLockForExclusiveAccess& lock) const {
const JS::Zone* atomsZone(const js::AutoAccessAtomsZone& access) const {
return gc.atomsZone;
}
JS::Zone* atomsZone(const js::AutoLockForExclusiveAccess& lock) {
JS::Zone* atomsZone(const js::AutoAccessAtomsZone& access) {
return gc.atomsZone;
}
JS::Zone* unsafeAtomsZone() {
@ -754,7 +758,7 @@ struct JSRuntime : public js::MallocProvider<JSRuntime>
bool activeGCInAtomsZone();
js::SymbolRegistry& symbolRegistry(js::AutoLockForExclusiveAccess& lock) {
js::SymbolRegistry& symbolRegistry(const js::AutoAccessAtomsZone& access) {
return symbolRegistry_.ref();
}
js::SymbolRegistry& unsafeSymbolRegistry() {
@ -857,6 +861,11 @@ struct JSRuntime : public js::MallocProvider<JSRuntime>
mozilla::Atomic<bool> offthreadIonCompilationEnabled_;
mozilla::Atomic<bool> parallelParsingEnabled_;
#ifdef DEBUG
mozilla::Atomic<uint32_t> offThreadParsesRunning_;
mozilla::Atomic<bool> offThreadParsingBlocked_;
#endif
js::MainThreadData<bool> autoWritableJitCodeActive_;
public:
@ -876,6 +885,38 @@ struct JSRuntime : public js::MallocProvider<JSRuntime>
return parallelParsingEnabled_;
}
#ifdef DEBUG
bool isOffThreadParseRunning() const {
return offThreadParsesRunning_;
}
void incOffThreadParsesRunning() {
MOZ_ASSERT(!isOffThreadParsingBlocked());
offThreadParsesRunning_++;
}
void decOffThreadParsesRunning() {
MOZ_ASSERT(isOffThreadParseRunning());
offThreadParsesRunning_--;
}
bool isOffThreadParsingBlocked() const {
return offThreadParsingBlocked_;
}
void setOffThreadParsingBlocked(bool blocked) {
MOZ_ASSERT(offThreadParsingBlocked_ != blocked);
MOZ_ASSERT(!isOffThreadParseRunning());
offThreadParsingBlocked_ = blocked;
}
#else
void incOffThreadParsesRunning() {}
void decOffThreadParsesRunning() {}
#endif
void toggleAutoWritableJitCodeActive(bool b) {
MOZ_ASSERT(autoWritableJitCodeActive_ != b, "AutoWritableJitCode should not be nested.");
autoWritableJitCodeActive_ = b;
@ -921,7 +962,7 @@ struct JSRuntime : public js::MallocProvider<JSRuntime>
}
// For inherited heap state accessors.
friend class js::gc::AutoTraceSession;
friend class js::gc::AutoHeapSession;
friend class JS::AutoEnterCycleCollection;
private:

Просмотреть файл

@ -20,9 +20,9 @@ using namespace js;
Symbol*
Symbol::newInternal(JSContext* cx, JS::SymbolCode code, uint32_t hash, JSAtom* description,
AutoLockForExclusiveAccess& lock)
const AutoAccessAtomsZone& access)
{
MOZ_ASSERT(cx->zone() == cx->atomsZone(lock));
MOZ_ASSERT(cx->zone() == cx->atomsZone(access));
// Following js::AtomizeString, we grudgingly forgo last-ditch GC here.
Symbol* p = Allocate<JS::Symbol, NoGC>(cx);

Просмотреть файл

@ -25,7 +25,7 @@
#include "vm/StringType.h"
namespace js {
class AutoLockForExclusiveAccess;
class AutoAccessAtomsZone;
} // namespace js
namespace JS {
@ -60,7 +60,7 @@ class Symbol : public js::gc::TenuredCell
static Symbol*
newInternal(JSContext* cx, SymbolCode code, js::HashNumber hash,
JSAtom* description, js::AutoLockForExclusiveAccess& lock);
JSAtom* description, const js::AutoAccessAtomsZone& access);
public:
static Symbol* new_(JSContext* cx, SymbolCode code, JSString* description);

Просмотреть файл

@ -511,12 +511,6 @@ SERVO_BINDING_FUNC(Servo_AnimationValue_Compute,
ComputedStyleBorrowed style,
RawServoStyleSetBorrowed raw_data)
// There's no reason we couldn't expose more stuff here, but GetCssText is
// pretty much all we'd ever want.
SERVO_BINDING_FUNC(Servo_UnlockedDeclarationBlock_GetCssText, void,
const RawServoUnlockedDeclarationBlock* declarations,
nsAString* result)
// Style attribute
SERVO_BINDING_FUNC(Servo_ParseStyleAttribute, RawServoDeclarationBlockStrong,
const nsACString* data,

Просмотреть файл

@ -83,19 +83,12 @@ typedef nsTArray<nsCSSPropertyID> RawGeckoCSSPropertyIDList;
typedef mozilla::gfx::Float RawGeckoGfxMatrix4x4[16];
typedef mozilla::dom::StyleChildrenIterator RawGeckoStyleChildrenIterator;
// A struct which to be used as an opaque pointer to a DeclarationBlock that has
// been read.
//
// This is effectively a *const PropertyDeclarationBlock in Rust.
struct RawServoUnlockedDeclarationBlock;
// A callback that can be sent via FFI which will be invoked _right before_
// being mutated, and at most once.
struct DeclarationBlockMutationClosure
{
// The callback function, first argument is the unlocked servo declaration
// block, second is `data`.
void (*function)(const RawServoUnlockedDeclarationBlock*, void*) = nullptr;
// The callback function. The argument is `data`.
void (*function)(void*) = nullptr;
void* data = nullptr;
};

Просмотреть файл

@ -425,7 +425,6 @@ mapped-generic-types = [
{ generic = false, gecko = "mozilla::ServoComputedValueFlags", servo = "::properties::computed_value_flags::ComputedValueFlags" },
{ generic = true, gecko = "mozilla::ServoRawOffsetArc", servo = "::servo_arc::RawOffsetArc" },
{ generic = false, gecko = "ComputedStyleStrong", servo = "::gecko_bindings::sugar::ownership::Strong<::properties::ComputedValues>" },
{ generic = false, gecko = "RawServoUnlockedDeclarationBlock", servo = "::properties::PropertyDeclarationBlock" },
]
fixups = [
{ pat = "\\broot\\s*::\\s*nsString\\b", rep = "::nsstring::nsStringRepr" },
@ -469,7 +468,6 @@ structs-types = [
"mozilla::UniquePtr",
"ServoRawOffsetArc",
"DeclarationBlockMutationClosure",
"RawServoUnlockedDeclarationBlock",
"nsIContent",
"nsINode",
"nsIDocument",

Просмотреть файл

@ -68,12 +68,13 @@ using namespace mozilla::dom;
*/
already_AddRefed<nsComputedDOMStyle>
NS_NewComputedDOMStyle(dom::Element* aElement, const nsAString& aPseudoElt,
nsIPresShell* aPresShell,
NS_NewComputedDOMStyle(dom::Element* aElement,
const nsAString& aPseudoElt,
nsIDocument* aDocument,
nsComputedDOMStyle::StyleType aStyleType)
{
RefPtr<nsComputedDOMStyle> computedStyle =
new nsComputedDOMStyle(aElement, aPseudoElt, aPresShell, aStyleType);
new nsComputedDOMStyle(aElement, aPseudoElt, aDocument, aStyleType);
return computedStyle.forget();
}
@ -117,7 +118,7 @@ DocumentNeedsRestyle(
nsPresContext* presContext = shell->GetPresContext();
MOZ_ASSERT(presContext);
// Unfortunately we don't know if the sheet change affects mContent or not, so
// Unfortunately we don't know if the sheet change affects mElement or not, so
// just assume it will and that we need to flush normally.
ServoStyleSet* styleSet = shell->StyleSet();
if (styleSet->StyleSheetsHaveChanged()) {
@ -312,7 +313,7 @@ ComputedStyleMap::Update()
nsComputedDOMStyle::nsComputedDOMStyle(dom::Element* aElement,
const nsAString& aPseudoElt,
nsIPresShell* aPresShell,
nsIDocument* aDocument,
StyleType aStyleType)
: mDocumentWeak(nullptr)
, mOuterFrame(nullptr)
@ -326,11 +327,12 @@ nsComputedDOMStyle::nsComputedDOMStyle(dom::Element* aElement,
, mFlushedPendingReflows(false)
#endif
{
MOZ_ASSERT(aElement && aPresShell);
MOZ_ASSERT(aPresShell->GetPresContext());
mDocumentWeak = do_GetWeakReference(aPresShell->GetDocument());
mContent = aElement;
MOZ_ASSERT(aElement);
MOZ_ASSERT(aDocument);
// TODO(emilio, bug 548397, https://github.com/w3c/csswg-drafts/issues/2403):
// Should use aElement->OwnerDoc() instead.
mDocumentWeak = do_GetWeakReference(aDocument);
mElement = aElement;
mPseudo = nsCSSPseudoElements::GetPseudoAtom(aPseudoElt);
}
@ -342,13 +344,13 @@ nsComputedDOMStyle::~nsComputedDOMStyle()
NS_IMPL_CYCLE_COLLECTION_CLASS(nsComputedDOMStyle)
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsComputedDOMStyle)
tmp->ClearComputedStyle(); // remove observer before clearing mContent
NS_IMPL_CYCLE_COLLECTION_UNLINK(mContent)
tmp->ClearComputedStyle(); // remove observer before clearing mElement
NS_IMPL_CYCLE_COLLECTION_UNLINK(mElement)
NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsComputedDOMStyle)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mContent)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mElement)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_TRACE_WRAPPERCACHE(nsComputedDOMStyle)
@ -412,15 +414,17 @@ nsComputedDOMStyle::SetCssText(const nsAString& aCssText,
uint32_t
nsComputedDOMStyle::Length()
{
uint32_t length = GetComputedStyleMap()->Length();
// Make sure we have up to date style so that we can include custom
// properties.
UpdateCurrentStyleSources(false);
if (mComputedStyle) {
length += Servo_GetCustomPropertiesCount(mComputedStyle);
if (!mComputedStyle) {
return 0;
}
uint32_t length =
GetComputedStyleMap()->Length() +
Servo_GetCustomPropertiesCount(mComputedStyle);
ClearCurrentStyleSources();
return length;
@ -452,7 +456,7 @@ nsComputedDOMStyle::GetPropertyValue(const nsAString& aPropertyName,
const bool layoutFlushIsNeeded = entry && entry->IsLayoutFlushNeeded();
UpdateCurrentStyleSources(layoutFlushIsNeeded);
if (!mComputedStyle) {
return NS_ERROR_NOT_AVAILABLE;
return NS_OK;
}
auto cleanup = mozilla::MakeScopeExit([&] {
@ -759,7 +763,6 @@ nsComputedDOMStyle::GetCSSImageURLs(const nsAString& aPropertyName,
UpdateCurrentStyleSources(false);
if (!mComputedStyle) {
aRv.Throw(NS_ERROR_NOT_AVAILABLE);
return;
}
@ -800,7 +803,7 @@ nsComputedDOMStyle::ClearComputedStyle()
{
if (mResolvedComputedStyle) {
mResolvedComputedStyle = false;
mContent->RemoveMutationObserver(this);
mElement->RemoveMutationObserver(this);
}
mComputedStyle = nullptr;
}
@ -811,7 +814,7 @@ nsComputedDOMStyle::SetResolvedComputedStyle(RefPtr<ComputedStyle>&& aContext,
{
if (!mResolvedComputedStyle) {
mResolvedComputedStyle = true;
mContent->AddMutationObserver(this);
mElement->AddMutationObserver(this);
}
mComputedStyle = aContext;
mComputedStyleGeneration = aGeneration;
@ -829,7 +832,7 @@ nsComputedDOMStyle::SetFrameComputedStyle(mozilla::ComputedStyle* aStyle,
bool
nsComputedDOMStyle::NeedsToFlush(nsIDocument* aDocument) const
{
// If mContent is not in the same document, we could do some checks to know if
// If mElement is not in the same document, we could do some checks to know if
// there are some pending restyles can be ignored across documents (since we
// will use the caller document's style), but it can be complicated and should
// be an edge case, so we just don't bother to do the optimization in this
@ -837,10 +840,10 @@ nsComputedDOMStyle::NeedsToFlush(nsIDocument* aDocument) const
//
// FIXME(emilio): This is likely to want GetComposedDoc() instead of
// OwnerDoc().
if (aDocument != mContent->OwnerDoc()) {
if (aDocument != mElement->OwnerDoc()) {
return true;
}
if (DocumentNeedsRestyle(aDocument, mContent->AsElement(), mPseudo)) {
if (DocumentNeedsRestyle(aDocument, mElement, mPseudo)) {
return true;
}
// If parent document is there, also needs to check if there is some change
@ -875,7 +878,7 @@ nsComputedDOMStyle::UpdateCurrentStyleSources(bool aNeedsLayoutFlush)
if (needsToFlush) {
// Flush _before_ getting the presshell, since that could create a new
// presshell. Also note that we want to flush the style on the document
// we're computing style in, not on the document mContent is in -- the two
// we're computing style in, not on the document mElement is in -- the two
// may be different.
document->FlushPendingNotifications(
aNeedsLayoutFlush ? FlushType::Layout : FlushType::Style);
@ -886,7 +889,7 @@ nsComputedDOMStyle::UpdateCurrentStyleSources(bool aNeedsLayoutFlush)
#endif
nsCOMPtr<nsIPresShell> presShellForContent =
nsContentUtils::GetPresShellForContent(mContent);
nsContentUtils::GetPresShellForContent(mElement);
if (presShellForContent && presShellForContent->GetDocument() != document) {
presShellForContent->GetDocument()->FlushPendingNotifications(FlushType::Style);
if (presShellForContent->IsDestroying()) {
@ -913,13 +916,13 @@ nsComputedDOMStyle::UpdateCurrentStyleSources(bool aNeedsLayoutFlush)
mPresShell->GetPresContext()->GetUndisplayedRestyleGeneration();
if (mComputedStyle) {
// We can't rely on the undisplayed restyle generation if mContent is
// We can't rely on the undisplayed restyle generation if mElement is
// out-of-document, since that generation is not incremented for DOM changes
// on out-of-document elements.
//
// So we always need to update the style to ensure it it up-to-date.
if (mComputedStyleGeneration == currentGeneration
&& mContent->IsInComposedDoc()) {
if (mComputedStyleGeneration == currentGeneration &&
mElement->IsInComposedDoc()) {
// Our cached style is still valid.
return;
}
@ -927,21 +930,21 @@ nsComputedDOMStyle::UpdateCurrentStyleSources(bool aNeedsLayoutFlush)
mComputedStyle = nullptr;
}
// XXX the !mContent->IsHTMLElement(nsGkAtoms::area)
// XXX the !mElement->IsHTMLElement(nsGkAtoms::area)
// check is needed due to bug 135040 (to avoid using
// mPrimaryFrame). Remove it once that's fixed.
if (mStyleType == eAll && !mContent->IsHTMLElement(nsGkAtoms::area)) {
if (mStyleType == eAll && !mElement->IsHTMLElement(nsGkAtoms::area)) {
mOuterFrame = nullptr;
if (!mPseudo) {
mOuterFrame = mContent->GetPrimaryFrame();
mOuterFrame = mElement->GetPrimaryFrame();
} else if (mPseudo == nsCSSPseudoElements::before ||
mPseudo == nsCSSPseudoElements::after) {
nsAtom* property = mPseudo == nsCSSPseudoElements::before
? nsGkAtoms::beforePseudoProperty
: nsGkAtoms::afterPseudoProperty;
auto* pseudo = static_cast<Element*>(mContent->GetProperty(property));
auto* pseudo = static_cast<Element*>(mElement->GetProperty(property));
mOuterFrame = pseudo ? pseudo->GetPrimaryFrame() : nullptr;
}
@ -967,7 +970,7 @@ nsComputedDOMStyle::UpdateCurrentStyleSources(bool aNeedsLayoutFlush)
// Need to resolve a style.
RefPtr<ComputedStyle> resolvedComputedStyle =
DoGetComputedStyleNoFlush(
mContent->AsElement(),
mElement,
mPseudo,
presShellForContent ? presShellForContent.get() : mPresShell,
mStyleType);
@ -5695,7 +5698,7 @@ nsComputedDOMStyle::GetLineHeightCoord(nscoord& aCoord)
// lie about font size inflation since we lie about font size (since
// the inflation only applies to text)
aCoord = ReflowInput::CalcLineHeight(mContent,
aCoord = ReflowInput::CalcLineHeight(mElement,
mComputedStyle,
presContext,
blockHeight, 1.0f);
@ -7174,7 +7177,7 @@ MarkComputedStyleMapDirty(const char* aPref, void* aData)
void
nsComputedDOMStyle::ParentChainChanged(nsIContent* aContent)
{
NS_ASSERTION(mContent == aContent, "didn't we register mContent?");
NS_ASSERTION(mElement == aContent, "didn't we register mElement?");
NS_ASSERTION(mResolvedComputedStyle,
"should have only registered an observer when "
"mResolvedComputedStyle is true");

Просмотреть файл

@ -80,12 +80,12 @@ public:
nsComputedDOMStyle(mozilla::dom::Element* aElement,
const nsAString& aPseudoElt,
nsIPresShell* aPresShell,
nsIDocument* aDocument,
StyleType aStyleType);
virtual nsINode *GetParentObject() override
nsINode* GetParentObject() override
{
return mContent;
return mElement;
}
static already_AddRefed<mozilla::ComputedStyle>
@ -718,9 +718,9 @@ private:
// We don't really have a good immutable representation of "presentation".
// Given the way GetComputedStyle is currently used, we should just grab the
// 0th presshell, if any, from the document.
// presshell, if any, from the document.
nsWeakPtr mDocumentWeak;
nsCOMPtr<nsIContent> mContent;
RefPtr<mozilla::dom::Element> mElement;
/**
* Strong reference to the ComputedStyle we access data from. This can be
@ -786,7 +786,7 @@ private:
already_AddRefed<nsComputedDOMStyle>
NS_NewComputedDOMStyle(mozilla::dom::Element* aElement,
const nsAString& aPseudoElt,
nsIPresShell* aPresShell,
nsIDocument* aDocument,
nsComputedDOMStyle::StyleType aStyleType =
nsComputedDOMStyle::eAll);

Просмотреть файл

@ -33,13 +33,27 @@ INSTANTIATE(int, int, prim1, 2 * sizeof(int));
INSTANTIATE(int, long, prim2, 2 * sizeof(long));
struct EmptyClass { explicit EmptyClass(int) {} };
struct NonEmpty { char mC; explicit NonEmpty(int) {} };
struct NonEmpty
{
char mC;
explicit NonEmpty(int)
: mC('\0')
{
}
};
INSTANTIATE(int, EmptyClass, both1, sizeof(int));
INSTANTIATE(int, NonEmpty, both2, 2 * sizeof(int));
INSTANTIATE(EmptyClass, NonEmpty, both3, 1);
struct A { char dummy; explicit A(int) {} };
struct A
{
char dummy;
explicit A(int)
: dummy('\0')
{
}
};
struct B : A { explicit B(int aI) : A(aI) {} };
INSTANTIATE(A, A, class1, 2);

Просмотреть файл

@ -11,6 +11,7 @@
#include "CTPolicyEnforcer.h"
#include "CTVerifyResult.h"
#include "OCSPCache.h"
#include "RootCertificateTelemetryUtils.h"
#include "ScopedNSSTypes.h"
#include "mozilla/Telemetry.h"
#include "mozilla/TimeStamp.h"
@ -78,11 +79,16 @@ enum class NetscapeStepUpPolicy : uint32_t;
class PinningTelemetryInfo
{
public:
PinningTelemetryInfo() { Reset(); }
PinningTelemetryInfo()
: certPinningResultBucket(0)
, rootBucket(ROOT_CERTIFICATE_UNKNOWN)
{
Reset();
}
// Should we accumulate pinning telemetry for the result?
bool accumulateResult;
Telemetry::HistogramID certPinningResultHistogram;
Maybe<Telemetry::HistogramID> certPinningResultHistogram;
int32_t certPinningResultBucket;
// Should we accumulate telemetry for the root?
bool accumulateForRoot;
@ -94,7 +100,12 @@ public:
class CertificateTransparencyInfo
{
public:
CertificateTransparencyInfo() { Reset(); }
CertificateTransparencyInfo()
: enabled(false)
, policyCompliance(mozilla::ct::CTPolicyCompliance::Unknown)
{
Reset();
}
// Was CT enabled?
bool enabled;

Просмотреть файл

@ -305,7 +305,7 @@ CheckPinsForHostname(const RefPtr<nsNSSCertList>& certList, const char* hostname
enforceTestModeResult ? 1 : 0;
}
pinningTelemetryInfo->accumulateResult = true;
pinningTelemetryInfo->certPinningResultHistogram = histogram;
pinningTelemetryInfo->certPinningResultHistogram = Some(histogram);
}
// We only collect per-CA pinning statistics upon failures.

Просмотреть файл

@ -1431,7 +1431,8 @@ AuthCertificate(CertVerifier& certVerifier,
}
if (pinningTelemetryInfo.accumulateResult) {
Telemetry::Accumulate(pinningTelemetryInfo.certPinningResultHistogram,
MOZ_ASSERT(pinningTelemetryInfo.certPinningResultHistogram.isSome());
Telemetry::Accumulate(pinningTelemetryInfo.certPinningResultHistogram.value(),
pinningTelemetryInfo.certPinningResultBucket);
}

Просмотреть файл

@ -68,6 +68,7 @@ EXPORTS += [
'nsRandomGenerator.h',
'nsSecurityHeaderParser.h',
'NSSErrorsService.h',
'RootCertificateTelemetryUtils.h',
'ScopedNSSTypes.h',
'SharedCertVerifier.h',
]

Просмотреть файл

@ -61,6 +61,7 @@ public:
, stapledOCSPResponse(aStapledOCSPResponse)
, subCACount(aSubCACount)
, deferredSubjectError(aDeferredSubjectError)
, subjectSignaturePublicKeyAlg(der::PublicKeyAlgorithm::Uninitialized)
, result(Result::FATAL_ERROR_LIBRARY_FAILURE)
, resultWasSet(false)
, buildForwardCallBudget(aBuildForwardCallBudget)

Просмотреть файл

@ -117,7 +117,11 @@ CheckSignatureAlgorithm(TrustDomain& trustDomain,
// for any curve that we support, the chances of us encountering a curve
// during path building is too low to be worth bothering with.
break;
case der::PublicKeyAlgorithm::Uninitialized:
{
assert(false);
return Result::FATAL_ERROR_LIBRARY_FAILURE;
}
MOZILLA_PKIX_UNREACHABLE_DEFAULT_ENUM
}

Просмотреть файл

@ -457,7 +457,7 @@ CertificateSerialNumber(Reader& input, /*out*/ Input& value)
// x.509 and OCSP both use this same version numbering scheme, though OCSP
// only supports v1.
enum class Version { v1 = 0, v2 = 1, v3 = 2, v4 = 3 };
enum class Version { v1 = 0, v2 = 1, v3 = 2, v4 = 3, Uninitialized = 255 };
// X.509 Certificate and OCSP ResponseData both use
// "[0] EXPLICIT Version DEFAULT v1". Although an explicit encoding of v1 is
@ -522,6 +522,7 @@ enum class PublicKeyAlgorithm
{
RSA_PKCS1,
ECDSA,
Uninitialized
};
Result SignatureAlgorithmIdentifierValue(

Просмотреть файл

@ -42,11 +42,13 @@ class BackCert final
{
public:
// certDER and childCert must be valid for the lifetime of BackCert.
BackCert(Input aCertDER, EndEntityOrCA aEndEntityOrCA,
BackCert(Input aCertDER,
EndEntityOrCA aEndEntityOrCA,
const BackCert* aChildCert)
: der(aCertDER)
, endEntityOrCA(aEndEntityOrCA)
, childCert(aChildCert)
, version(der::Version::Uninitialized)
{
}

Просмотреть файл

@ -79,6 +79,9 @@ VerifySignedDigest(TrustDomain& trustDomain,
case der::PublicKeyAlgorithm::RSA_PKCS1:
return trustDomain.VerifyRSAPKCS1SignedDigest(signedDigest,
signerSubjectPublicKeyInfo);
case der::PublicKeyAlgorithm::Uninitialized:
assert(false);
return Result::FATAL_ERROR_LIBRARY_FAILURE;
MOZILLA_PKIX_UNREACHABLE_DEFAULT_ENUM
}
}

Просмотреть файл

@ -564,51 +564,71 @@ impl PropertyDeclarationBlock {
true
}
/// Returns the first declaration that would be removed by removing
/// `property`.
#[inline]
pub fn first_declaration_to_remove(
&self,
property: &PropertyId,
) -> Option<usize> {
if let Some(id) = property.longhand_id() {
if !self.longhands.contains(id) {
return None;
}
}
self.declarations.iter().position(|declaration| {
declaration.id().is_or_is_longhand_of(property)
})
}
/// Removes a given declaration at a given index.
#[inline]
fn remove_declaration_at(&mut self, i: usize) {
{
let id = self.declarations[i].id();
if let PropertyDeclarationId::Longhand(id) = id {
self.longhands.remove(id);
}
self.declarations_importance.remove(i);
}
self.declarations.remove(i);
}
/// <https://drafts.csswg.org/cssom/#dom-cssstyledeclaration-removeproperty>
///
/// Returns whether any declaration was actually removed.
pub fn remove_property<C>(
/// `first_declaration` needs to be the result of
/// `first_declaration_to_remove`.
#[inline]
pub fn remove_property(
&mut self,
property: &PropertyId,
mut before_change_callback: C,
) -> bool
where
C: FnMut(&Self),
{
let longhand_id = property.longhand_id();
if let Some(id) = longhand_id {
if !self.longhands.contains(id) {
return false
}
}
let mut removed_at_least_one = false;
let mut i = 0;
first_declaration: usize,
) {
debug_assert_eq!(
Some(first_declaration),
self.first_declaration_to_remove(property)
);
debug_assert!(self.declarations[first_declaration].id().is_or_is_longhand_of(property));
self.remove_declaration_at(first_declaration);
let shorthand = match property.as_shorthand() {
Ok(s) => s,
Err(_longhand_or_custom) => return,
};
let mut i = first_declaration;
let mut len = self.len();
while i < len {
{
let id = self.declarations[i].id();
if !id.is_or_is_longhand_of(property) {
i += 1;
continue;
}
if !removed_at_least_one {
before_change_callback(&*self);
}
removed_at_least_one = true;
if let PropertyDeclarationId::Longhand(id) = id {
self.longhands.remove(id);
}
self.declarations_importance.remove(i);
if !self.declarations[i].id().is_longhand_of(shorthand) {
i += 1;
continue;
}
self.declarations.remove(i);
self.remove_declaration_at(i);
len -= 1;
}
if longhand_id.is_some() {
debug_assert!(removed_at_least_one);
}
removed_at_least_one
}
/// Take a declaration block known to contain a single property and serialize it.
@ -727,9 +747,7 @@ impl PropertyDeclarationBlock {
builder.build()
}
}
impl PropertyDeclarationBlock {
/// Like the method on ToCss, but without the type parameter to avoid
/// accidentally monomorphizing this large function multiple times for
/// different writers.

Просмотреть файл

@ -167,14 +167,14 @@ use super::error_reporter::ErrorReporter;
use super::stylesheet_loader::{AsyncStylesheetParser, StylesheetLoader};
trait ClosureHelper {
fn invoke(&self, decls: &PropertyDeclarationBlock);
fn invoke(&self);
}
impl ClosureHelper for DeclarationBlockMutationClosure {
#[inline]
fn invoke(&self, decls: &PropertyDeclarationBlock) {
fn invoke(&self) {
if let Some(function) = self.function.as_ref() {
unsafe { function(decls, self.data) };
unsafe { function(self.data) };
}
}
}
@ -1603,7 +1603,9 @@ pub extern "C" fn Servo_StyleSheet_GetSourceURL(
}
fn read_locked_arc<T, R, F>(raw: &<Locked<T> as HasFFI>::FFIType, func: F) -> R
where Locked<T>: HasArcFFI, F: FnOnce(&T) -> R
where
Locked<T>: HasArcFFI,
F: FnOnce(&T) -> R,
{
let global_style_data = &*GLOBAL_STYLE_DATA;
let guard = global_style_data.shared_lock.read();
@ -3411,15 +3413,6 @@ pub unsafe extern "C" fn Servo_DeclarationBlock_GetCssText(
})
}
#[no_mangle]
pub unsafe extern "C" fn Servo_UnlockedDeclarationBlock_GetCssText(
declarations: *const structs::RawServoUnlockedDeclarationBlock,
result: *mut nsAString,
) {
(*declarations).to_css(&mut *result).unwrap()
}
#[no_mangle]
pub extern "C" fn Servo_DeclarationBlock_SerializeOneValue(
declarations: RawServoDeclarationBlockBorrowed,
@ -3567,9 +3560,10 @@ fn set_property(
return false;
}
before_change_closure.invoke();
let importance = if is_important { Importance::Important } else { Importance::Normal };
write_locked_arc(declarations, |decls: &mut PropertyDeclarationBlock| {
before_change_closure.invoke(&*decls);
decls.extend(
source_declarations.drain(),
importance,
@ -3647,11 +3641,22 @@ fn remove_property(
property_id: PropertyId,
before_change_closure: DeclarationBlockMutationClosure,
) -> bool {
let first_declaration =
read_locked_arc(declarations, |decls: &PropertyDeclarationBlock| {
decls.first_declaration_to_remove(&property_id)
});
let first_declaration = match first_declaration {
Some(i) => i,
None => return false,
};
before_change_closure.invoke();
write_locked_arc(declarations, |decls: &mut PropertyDeclarationBlock| {
decls.remove_property(&property_id, |decls| {
before_change_closure.invoke(decls)
})
})
decls.remove_property(&property_id, first_declaration)
});
true
}
#[no_mangle]

Просмотреть файл

@ -44,3 +44,15 @@ bench-sixspeed:
export JSSHELL=$USE_ARTIFACT_PATH/build/jsshell/js &&
cd $GECKO_PATH &&
./mach jsshell-bench --binary $JSSHELL --perfherder six-speed
bench-asmjsapps:
description: asm.js Apps shell benchmark suite
treeherder:
symbol: js-bench(asm.js-apps)
run:
command: >
cd $USE_ARTIFACT_PATH/build &&
unzip -q -d jsshell target.jsshell.zip &&
export JSSHELL=$USE_ARTIFACT_PATH/build/jsshell/js &&
cd $GECKO_PATH &&
./mach jsshell-bench --binary $JSSHELL --perfherder asmjs-apps

Просмотреть файл

@ -199,9 +199,66 @@ class SixSpeed(Benchmark):
self.suite['value'] = bench_total
class AsmJSApps(Benchmark):
name = 'asmjsapps'
path = os.path.join('third_party', 'webkit', 'PerformanceTests', 'asmjs-apps')
units = 'ms'
@property
def command(self):
if not self.args:
self.args = []
full_args = ['bash', 'harness.sh', self.shell + " " + " ".join(self.args)]
return full_args
def reset(self):
super(AsmJSApps, self).reset()
# Scores are of the form:
# {<bench_name>: {<score_name>: [<values>]}}
self.scores = defaultdict(lambda: defaultdict(list))
def process_results(self, output):
total = 0.0
tests = []
for line in output.splitlines():
m = re.search("(.+) - (\d+(\.\d+)?)", line)
if not m:
continue
name = m.group(1)
score = m.group(2)
total += float(score)
tests.append({ 'name': name, 'time': score })
tests.append({ 'name': '__total__', 'time': total })
return tests
def process_line(self, output):
m = re.search("(.+) - (\d+(\.\d+)?)", output)
if not m:
return
subtest = m.group(1)
score = m.group(2)
if subtest not in self.scores[self.name]:
self.scores[self.name][subtest] = []
self.scores[self.name][subtest].append(int(score))
def collect_results(self):
bench_total = 0
# NOTE: for this benchmark we run the test once, so we have a single value array
for bench, scores in self.scores.items():
for score, values in scores.items():
test_name = "{}-{}".format(self.name, score)
total = sum(values) / len(values)
self.suite['subtests'].append({'name': test_name, 'value': total})
bench_total += int(sum(values))
self.suite['value'] = bench_total
all_benchmarks = {
'ares6': Ares6,
'six-speed': SixSpeed,
'asmjs-apps': AsmJSApps,
}

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше