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

MozReview-Commit-ID: Gc5JIILUrPi
This commit is contained in:
Sebastian Hengst 2017-10-20 00:05:39 +02:00
Родитель 378936755e 47b2d43b88
Коммит 20d769ea9c
115 изменённых файлов: 33576 добавлений и 34482 удалений

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

@ -9,6 +9,8 @@
#include "mozilla/a11y/HandlerProvider.h"
#include "Accessible2_3.h"
#include "AccessibleTable.h"
#include "AccessibleTable2.h"
#include "HandlerData.h"
#include "HandlerData_i.c"
#include "mozilla/Assertions.h"
@ -214,6 +216,18 @@ HandlerProvider::MarshalAs(REFIID aIid)
return aIid;
}
REFIID
HandlerProvider::GetEffectiveOutParamIid(REFIID aCallIid,
ULONG aCallMethod)
{
if (aCallIid == IID_IAccessibleTable || aCallIid == IID_IAccessibleTable2) {
return IID_IAccessible2_3;
}
MOZ_ASSERT(false);
return IID_IUnknown;
}
HRESULT
HandlerProvider::NewInstance(REFIID aIid,
mscom::InterceptorTargetPtr<IUnknown> aTarget,

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

@ -7,7 +7,7 @@
#ifndef mozilla_a11y_HandlerProvider_h
#define mozilla_a11y_HandlerProvider_h
#include "handler/AccessibleHandler.h"
#include "mozilla/a11y/AccessibleHandler.h"
#include "mozilla/AlreadyAddRefed.h"
#include "mozilla/Atomics.h"
#include "mozilla/mscom/IHandlerProvider.h"
@ -44,6 +44,8 @@ public:
STDMETHODIMP GetHandlerPayloadSize(NotNull<DWORD*> aOutPayloadSize) override;
STDMETHODIMP WriteHandlerPayload(NotNull<IStream*> aStream) override;
STDMETHODIMP_(REFIID) MarshalAs(REFIID aIid) override;
STDMETHODIMP_(REFIID) GetEffectiveOutParamIid(REFIID aCallIid,
ULONG aCallMethod) override;
STDMETHODIMP NewInstance(REFIID aIid,
mscom::InterceptorTargetPtr<IUnknown> aTarget,
NotNull<mscom::IHandlerProvider**> aOutNewPayload) override;

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

@ -297,15 +297,28 @@ Sanitizer.prototype = {
Services.obs.notifyObservers(null, "extension:purge-localStorage");
// ServiceWorkers
let promises = [];
let serviceWorkers = serviceWorkerManager.getAllRegistrations();
for (let i = 0; i < serviceWorkers.length; i++) {
let sw = serviceWorkers.queryElementAt(i, Ci.nsIServiceWorkerRegistrationInfo);
let host = sw.principal.URI.host;
serviceWorkerManager.removeAndPropagate(host);
promises.push(new Promise(resolve => {
let unregisterCallback = {
unregisterSucceeded: () => { resolve(true); },
// We don't care about failures.
unregisterFailed: () => { resolve(true); },
QueryInterface: XPCOMUtils.generateQI(
[Ci.nsIServiceWorkerUnregisterCallback])
};
serviceWorkerManager.propagateUnregister(sw.principal, unregisterCallback, sw.scope);
}));
}
await Promise.all(promises);
// QuotaManager
let promises = [];
promises = [];
await new Promise(resolve => {
quotaManagerService.getUsage(request => {
if (request.resultCode != Cr.NS_OK) {

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

@ -1,6 +1,8 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
Cu.import("resource://gre/modules/PromiseUtils.jsm");
/**
* With e10s, plugins must run in their own process. This means we have
* three processes at a minimum when we're running a plugin:
@ -79,10 +81,12 @@ function preparePlugin(browser, pluginFallbackState) {
});
}
add_task(async function setup() {
// Bypass click-to-play
setTestPluginEnabledState(Ci.nsIPluginTag.STATE_ENABLED);
// Deferred promise object used by the test to wait for the crash handler
let crashDeferred = null;
// Clear out any minidumps we create from plugins - we really don't care
// about them.
let crashObserver = (subject, topic, data) => {
@ -108,6 +112,7 @@ add_task(async function setup() {
pluginDumpFile.remove(false);
extraFile.remove(false);
crashDeferred.resolve();
});
};
@ -118,12 +123,14 @@ add_task(async function setup() {
Services.prefs.clearUserPref("plugins.testmode");
Services.obs.removeObserver(crashObserver, "plugin-crashed");
});
});
/**
* In this case, the chrome process hears about the crash first.
*/
add_task(async function testChromeHearsPluginCrashFirst() {
// Setup the crash observer promise
crashDeferred = PromiseUtils.defer();
// Open a remote window so that we can run this test even if e10s is not
// enabled by default.
let win = await BrowserTestUtils.openNewBrowserWindow({remote: true});
@ -183,12 +190,16 @@ add_task(async function testChromeHearsPluginCrashFirst() {
"Should have been showing crash report UI");
});
await BrowserTestUtils.closeWindow(win);
await crashDeferred.promise;
});
/**
* In this case, the content process hears about the crash first.
*/
add_task(async function testContentHearsCrashFirst() {
// Setup the crash observer promise
crashDeferred = PromiseUtils.defer();
// Open a remote window so that we can run this test even if e10s is not
// enabled by default.
let win = await BrowserTestUtils.openNewBrowserWindow({remote: true});
@ -253,4 +264,5 @@ add_task(async function testContentHearsCrashFirst() {
});
await BrowserTestUtils.closeWindow(win);
await crashDeferred.promise;
});

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

@ -34,7 +34,9 @@ add_task(async function test_clear_email() {
prefs.setBoolPref("emailMe", true);
let tab = gBrowser.getTabForBrowser(browser);
await BrowserTestUtils.crashBrowser(browser);
await BrowserTestUtils.crashBrowser(browser,
/* shouldShowTabCrashPage */ true,
/* shouldClearMinidumps */ false);
let doc = browser.contentDocument;
// Since about:tabcrashed will run in the parent process, we can safely

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

@ -1,7 +1,7 @@
This is the debugger.html project output.
See https://github.com/devtools-html/debugger.html
Taken from upstream commit: 455e7e3f2de29113e37de8c03052de110f5fb106
Taken from upstream commit: aa6b25cc7dc645b8c1d76af58b99012e40b80848
Packages:
- babel-plugin-transform-es2015-modules-commonjs @6.26.0

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

@ -2,6 +2,141 @@
* 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/. */
menu {
display: inline;
padding: 0;
}
menu > menuitem::after {
content: "\25BA";
float: right;
padding-left: 5px;
}
menu > menupopup {
display: none;
}
menu > menuitem:hover + menupopup,
menu > menupopup:hover {
display: block;
}
menupopup {
position: fixed;
z-index: 10000;
background: white;
border: 1px solid #cccccc;
padding: 5px 0;
background: #f2f2f2;
border-radius: 5px;
color: #585858;
box-shadow: 0 0 4px 0 rgba(190, 190, 190, 0.8);
min-width: 130px;
}
menuitem {
display: block;
padding: 0 20px;
line-height: 20px;
font-weight: 500;
font-size: 13px;
-moz-user-select: none;
user-select: none;
}
menuitem:hover {
background: #3780fb;
color: white;
cursor: pointer;
}
menuitem[disabled=true] {
color: #cccccc;
}
menuitem[disabled=true]:hover {
background-color: transparent;
cursor: default;
}
menuitem[type=checkbox]::before {
content: "";
width: 10px;
display: inline-block;
}
menuitem[type=checkbox][checked=true]::before {
content: "\2713";
left: -8px;
position: relative;
}
menuseparator {
border-bottom: 1px solid #cacdd3;
width: 100%;
height: 5px;
display: block;
margin-bottom: 5px;
}
#contextmenu-mask.show {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 999;
}
/* 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/. */
:root.theme-light,
:root .theme-light {
--theme-search-overlays-semitransparent: rgba(221, 225, 228, 0.66);
}
* {
box-sizing: border-box;
}
html,
body {
height: 100%;
margin: 0;
padding: 0;
width: 100%;
}
#mount {
display: flex;
height: 100%;
}
::-webkit-scrollbar {
width: 8px;
height: 8px;
background: transparent;
}
::-webkit-scrollbar-track {
border-radius: 8px;
background: transparent;
}
::-webkit-scrollbar-thumb {
border-radius: 8px;
background: rgba(113, 113, 113, 0.5);
}
:root.theme-dark .CodeMirror-scrollbar-filler {
background: transparent;
}
/* 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/. */
.landing-page {
flex: 1;
display: flex;
@ -275,144 +410,10 @@
padding-left: 3px;
font-weight: normal;
}
/* 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/. */
menu {
display: inline;
padding: 0;
}
menu > menuitem::after {
content: "\25BA";
float: right;
padding-left: 5px;
}
menu > menupopup {
display: none;
}
menu > menuitem:hover + menupopup,
menu > menupopup:hover {
display: block;
}
menupopup {
position: fixed;
z-index: 10000;
background: white;
border: 1px solid #cccccc;
padding: 5px 0;
background: #f2f2f2;
border-radius: 5px;
color: #585858;
box-shadow: 0 0 4px 0 rgba(190, 190, 190, 0.8);
min-width: 130px;
}
menuitem {
display: block;
padding: 0 20px;
line-height: 20px;
font-weight: 500;
font-size: 13px;
-moz-user-select: none;
user-select: none;
}
menuitem:hover {
background: #3780fb;
color: white;
cursor: pointer;
}
menuitem[disabled=true] {
color: #cccccc;
}
menuitem[disabled=true]:hover {
background-color: transparent;
cursor: default;
}
menuitem[type=checkbox]::before {
content: "";
width: 10px;
display: inline-block;
}
menuitem[type=checkbox][checked=true]::before {
content: "\2713";
left: -8px;
position: relative;
}
menuseparator {
border-bottom: 1px solid #cacdd3;
width: 100%;
height: 5px;
display: block;
margin-bottom: 5px;
}
#contextmenu-mask.show {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 999;
}
/* 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/. */
:root.theme-light,
:root .theme-light {
--theme-search-overlays-semitransparent: rgba(221, 225, 228, 0.66);
}
* {
box-sizing: border-box;
}
html,
body {
height: 100%;
margin: 0;
padding: 0;
width: 100%;
}
#mount {
display: flex;
height: 100%;
}
::-webkit-scrollbar {
width: 8px;
height: 8px;
background: transparent;
}
::-webkit-scrollbar-track {
border-radius: 8px;
background: transparent;
}
::-webkit-scrollbar-thumb {
border-radius: 8px;
background: rgba(113, 113, 113, 0.5);
}
:root.theme-dark .CodeMirror-scrollbar-filler {
background: transparent;
}
.modal-wrapper {
position: fixed;
display: flex;
flex-direction: column;
align-items: center;
width: 100%;
height: 100%;
@ -423,13 +424,12 @@ body {
}
.modal {
top: 0;
margin: auto;
width: 500px;
width: 80%;
height: auto;
overflow-y: scroll;
background-color: var(--theme-toolbar-background);
transform: translateY(-250px);
transition: transform 150ms cubic-bezier(0.07, 0.95, 0, 1);
box-shadow: 0 0 10px 2px var(--popup-shadow-color);
box-shadow: 1px 1px 3px 1px var(--popup-shadow-color);
}
.modal.entering,
@ -439,13 +439,24 @@ body {
.modal.entered,
.modal.exiting {
transform: translateY(0px);
transform: translateY(5px);
}
@media (max-width: 520px) {
/* This rule is active when the screen is not short and narrow */
@media (min-width: 580px) and (min-height: 340px) {
.modal {
width: 80%;
left: 10%;
width: 50%;
}
}
@media (min-height: 340px) {
.modal {
height: auto;
max-height: 80vh;
}
.modal.entered,
.modal.exiting {
transform: translateY(30px);
}
}
.shortcuts-content {
@ -490,10 +501,6 @@ body {
width: calc(100% - 1px); /* 1px fixes the hidden right border */
}
.shortcuts-modal {
width: 45%;
}
.shortcuts-list li {
font-size: 12px;
color: var(--theme-body-color);
@ -1696,10 +1703,10 @@ html .toggle-button-end.vertical svg {
transition: opacity 200ms;
border: none;
background: transparent;
padding: 6px 0.7em;
padding: 6px;
}
.source-footer > .commands > .action i {
.source-footer > .commands > .action img {
height: 100%;
display: flex;
flex-direction: column;
@ -1718,9 +1725,18 @@ html .toggle-button-end.vertical svg {
fill: var(--theme-selection-color);
}
.source-footer > .commands > .action svg {
.source-footer > .commands > .action > img.prettyPrint {
mask: url("chrome://devtools/skin/images/debugger/prettyPrint.svg") no-repeat;
height: 16px;
width: 16px;
background: var(--theme-body-color);
}
.source-footer > .commands > .action > img.blackBox {
mask: url("chrome://devtools/skin/images/debugger/blackBox.svg") no-repeat;
height: 16px;
width: 16px;
background: var(--theme-body-color);
}
.source-footer .commands .coverage {
@ -1733,8 +1749,8 @@ html .toggle-button-end.vertical svg {
border-radius: 2px;
}
.source-footer .black-box.blackboxed svg {
fill: var(--theme-highlight-blue);
.source-footer > .commands > .blackboxed > img.blackBox {
background: var(--theme-highlight-blue);
}
.source-footer .blackbox-summary {
@ -2188,12 +2204,19 @@ html[dir="rtl"] .arrow svg,
box-shadow: 1px 2px 3px var(--popup-shadow-color);
}
.popover .preview-popup .header {
.popover .preview-popup .header-container {
width: 100%;
line-height: 20px;
border-bottom: 1px solid #cccccc;
display: flex;
flex-direction: column;
margin-bottom: 5px;
}
.popover .preview-popup .header-container h3 {
margin: 0;
margin-bottom: 5px;
font-weight: normal;
font-size: 14px;
}
.popover .preview-popup .header .link {
@ -2492,8 +2515,9 @@ html[dir="rtl"] .editor-mount {
}
.CodeMirror-linenumber {
font-size: 11px;
line-height: 14px;
font-size: 12px;
line-height: 15px;
font-family: monospace;
}
.folding-enabled .CodeMirror-linenumber {
@ -3149,6 +3173,18 @@ html .command-bar > button:disabled {
.command-bar > button {
padding: 6px 5px;
}
.command-bar.bottom {
justify-content: flex-end;
}
.command-bar.bottom > button {
color: var(--theme-comment);
width: 26px;
}
.command-bar.bottom > button:hover {
color: var(--theme-body-color);
}
.object-node.default-property {
opacity: 0.6;
}
@ -3373,13 +3409,13 @@ html .welcomebox .toggle-button-end.collapsed {
fill: var(--theme-body-color);
}
.source-tab .prettyPrint {
line-height: 0;
}
.source-tab .prettyPrint svg {
.source-tab img.prettyPrint {
mask: url("chrome://devtools/skin/images/debugger/prettyPrint.svg") no-repeat;
mask-size: 100%;
padding-top: 12px;
height: 12px;
width: 12px;
background: var(--theme-highlight-blue);
}
.source-tab .prettyPrint path {
@ -3388,13 +3424,16 @@ html .welcomebox .toggle-button-end.collapsed {
.source-tab .blackBox,
.source-tab .prettyPrint {
line-height: 0;
align-self: center;
}
.source-tab .blackBox svg {
.source-tab img.blackBox {
mask: url("chrome://devtools/skin/images/debugger/blackBox.svg") no-repeat;
mask-size: 100%;
padding-top: 12px;
height: 12px;
width: 12px;
background: var(--theme-highlight-blue);
}
.source-tab .blackBox path {

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

Разница между файлами не показана из-за своего большого размера Загрузить разницу

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

@ -78,12 +78,201 @@ return /******/ (function(modules) { // webpackBootstrap
/***/ 1282:
/***/ (function(module, exports, __webpack_require__) {
module.exports = __webpack_require__(1283);
module.exports = __webpack_require__(1630);
/***/ }),
/***/ 1283:
/***/ 1363:
/***/ (function(module, exports, __webpack_require__) {
/* 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/. */
const networkRequest = __webpack_require__(1367);
const workerUtils = __webpack_require__(1368);
module.exports = {
networkRequest,
workerUtils
};
/***/ }),
/***/ 1367:
/***/ (function(module, exports) {
/* 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/. */
function networkRequest(url, opts) {
return fetch(url, {
cache: opts.loadFromCache ? "default" : "no-cache"
}).then(res => {
if (res.status >= 200 && res.status < 300) {
return res.text().then(text => ({ content: text }));
}
return Promise.reject(`request failed with status ${res.status}`);
});
}
module.exports = networkRequest;
/***/ }),
/***/ 1368:
/***/ (function(module, exports) {
function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; }
function WorkerDispatcher() {
this.msgId = 1;
this.worker = null;
} /* 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/. */
const mark = typeof window == "object" && window.performance && window.performance.mark ? window.performance.mark.bind(window.performance) : () => {};
const measure = typeof window == "object" && window.performance && window.performance.measure ? window.performance.measure.bind(window.performance) : () => {};
WorkerDispatcher.prototype = {
start(url) {
this.worker = new Worker(url);
this.worker.onerror = () => {
console.error(`Error in worker ${url}`);
};
},
stop() {
if (!this.worker) {
return;
}
this.worker.terminate();
this.worker = null;
},
task(method) {
return (...args) => {
return new Promise((resolve, reject) => {
const id = this.msgId++;
mark(`${method}_start`);
this.worker.postMessage({ id, method, args });
const listener = ({ data: result }) => {
if (result.id !== id) {
return;
}
if (!this.worker) {
reject("Oops, The worker has shutdown!");
return;
}
this.worker.removeEventListener("message", listener);
mark(`${method}_end`);
measure(`${method}`, `${method}_start`, `${method}_end`);
if (result.error) {
reject(result.error);
} else {
resolve(result.response);
}
};
this.worker.addEventListener("message", listener);
});
};
}
};
function workerHandler(publicInterface) {
return function (msg) {
const { id, method, args } = msg.data;
try {
const response = publicInterface[method].apply(undefined, args);
if (response instanceof Promise) {
response.then(val => self.postMessage({ id, response: val }),
// Error can't be sent via postMessage, so be sure to
// convert to string.
err => self.postMessage({ id, error: err.toString() }));
} else {
self.postMessage({ id, response });
}
} catch (error) {
// Error can't be sent via postMessage, so be sure to convert to
// string.
self.postMessage({ id, error: error.toString() });
}
};
}
function streamingWorkerHandler(publicInterface, { timeout = 100 } = {}, worker = self) {
let streamingWorker = (() => {
var _ref = _asyncToGenerator(function* (id, tasks) {
let isWorking = true;
const intervalId = setTimeout(function () {
isWorking = false;
}, timeout);
const results = [];
while (tasks.length !== 0 && isWorking) {
const { callback, context, args } = tasks.shift();
const result = yield callback.call(context, args);
results.push(result);
}
worker.postMessage({ id, status: "pending", data: results });
clearInterval(intervalId);
if (tasks.length !== 0) {
yield streamingWorker(id, tasks);
}
});
return function streamingWorker(_x, _x2) {
return _ref.apply(this, arguments);
};
})();
return (() => {
var _ref2 = _asyncToGenerator(function* (msg) {
const { id, method, args } = msg.data;
const workerMethod = publicInterface[method];
if (!workerMethod) {
console.error(`Could not find ${method} defined in worker.`);
}
worker.postMessage({ id, status: "start" });
try {
const tasks = workerMethod(args);
yield streamingWorker(id, tasks);
worker.postMessage({ id, status: "done" });
} catch (error) {
worker.postMessage({ id, status: "error", error });
}
});
return function (_x3) {
return _ref2.apply(this, arguments);
};
})();
}
module.exports = {
WorkerDispatcher,
workerHandler,
streamingWorkerHandler
};
/***/ }),
/***/ 1630:
/***/ (function(module, exports, __webpack_require__) {
"use strict";
@ -93,19 +282,14 @@ var _prettyFast = __webpack_require__(802);
var _prettyFast2 = _interopRequireDefault(_prettyFast);
var _devtoolsUtils = __webpack_require__(900);
var _devtoolsUtils = __webpack_require__(1363);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
var workerHandler = _devtoolsUtils.workerUtils.workerHandler;
const { workerHandler } = _devtoolsUtils.workerUtils;
function prettyPrint(_ref) {
var url = _ref.url,
indent = _ref.indent,
source = _ref.source;
var prettified = (0, _prettyFast2.default)(source, {
function prettyPrint({ url, indent, source }) {
const prettified = (0, _prettyFast2.default)(source, {
url: url,
indent: " ".repeat(indent)
});
@ -118,7 +302,7 @@ function prettyPrint(_ref) {
function invertMappings(mappings) {
return mappings._array.map(m => {
var mapping = {
const mapping = {
generated: {
line: m.originalLine,
column: m.originalColumn
@ -7411,184 +7595,6 @@ SourceNode.prototype.toStringWithSourceMap = function SourceNode_toStringWithSou
exports.SourceNode = SourceNode;
/***/ }),
/***/ 900:
/***/ (function(module, exports, __webpack_require__) {
/* 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/. */
const networkRequest = __webpack_require__(901);
const workerUtils = __webpack_require__(902);
module.exports = {
networkRequest,
workerUtils
};
/***/ }),
/***/ 901:
/***/ (function(module, exports) {
/* 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/. */
function networkRequest(url, opts) {
return fetch(url, {
cache: opts.loadFromCache ? "default" : "no-cache"
}).then(res => {
if (res.status >= 200 && res.status < 300) {
return res.text().then(text => ({ content: text }));
}
return Promise.reject(`request failed with status ${res.status}`);
});
}
module.exports = networkRequest;
/***/ }),
/***/ 902:
/***/ (function(module, exports) {
function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; }
function WorkerDispatcher() {
this.msgId = 1;
this.worker = null;
} /* 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/. */
WorkerDispatcher.prototype = {
start(url) {
this.worker = new Worker(url);
this.worker.onerror = () => {
console.error(`Error in worker ${url}`);
};
},
stop() {
if (!this.worker) {
return;
}
this.worker.terminate();
this.worker = null;
},
task(method) {
return (...args) => {
return new Promise((resolve, reject) => {
const id = this.msgId++;
this.worker.postMessage({ id, method, args });
const listener = ({ data: result }) => {
if (result.id !== id) {
return;
}
if (!this.worker) {
reject("Oops, The worker has shutdown!");
return;
}
this.worker.removeEventListener("message", listener);
if (result.error) {
reject(result.error);
} else {
resolve(result.response);
}
};
this.worker.addEventListener("message", listener);
});
};
}
};
function workerHandler(publicInterface) {
return function (msg) {
const { id, method, args } = msg.data;
try {
const response = publicInterface[method].apply(undefined, args);
if (response instanceof Promise) {
response.then(val => self.postMessage({ id, response: val }),
// Error can't be sent via postMessage, so be sure to
// convert to string.
err => self.postMessage({ id, error: err.toString() }));
} else {
self.postMessage({ id, response });
}
} catch (error) {
// Error can't be sent via postMessage, so be sure to convert to
// string.
self.postMessage({ id, error: error.toString() });
}
};
}
function streamingWorkerHandler(publicInterface, { timeout = 100 } = {}, worker = self) {
let streamingWorker = (() => {
var _ref = _asyncToGenerator(function* (id, tasks) {
let isWorking = true;
const intervalId = setTimeout(function () {
isWorking = false;
}, timeout);
const results = [];
while (tasks.length !== 0 && isWorking) {
const { callback, context, args } = tasks.shift();
const result = yield callback.call(context, args);
results.push(result);
}
worker.postMessage({ id, status: "pending", data: results });
clearInterval(intervalId);
if (tasks.length !== 0) {
yield streamingWorker(id, tasks);
}
});
return function streamingWorker(_x, _x2) {
return _ref.apply(this, arguments);
};
})();
return (() => {
var _ref2 = _asyncToGenerator(function* (msg) {
const { id, method, args } = msg.data;
const workerMethod = publicInterface[method];
if (!workerMethod) {
console.error(`Could not find ${method} defined in worker.`);
}
worker.postMessage({ id, status: "start" });
try {
const tasks = workerMethod(args);
yield streamingWorker(id, tasks);
worker.postMessage({ id, status: "done" });
} catch (error) {
worker.postMessage({ id, status: "error", error });
}
});
return function (_x3) {
return _ref2.apply(this, arguments);
};
})();
}
module.exports = {
WorkerDispatcher,
workerHandler,
streamingWorkerHandler
};
/***/ })
/******/ });

Разница между файлами не показана из-за своего большого размера Загрузить разницу

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

@ -109,5 +109,5 @@ skip-if = true # Bug 1393121, 1393299
[browser_dbg-tabs.js]
[browser_dbg-toggling-tools.js]
[browser_dbg-wasm-sourcemaps.js]
skip-if = true
skip-if = asan
[browser_dbg-reload.js]

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

@ -39,21 +39,21 @@ add_task(async function() {
const dbg = await initDebugger("doc-scripts.html");
await selectSource(dbg, "simple2");
dump('Adding a conditional Breakpoint\n')
dump("Adding a conditional Breakpoint\n");
await setConditionalBreakpoint(dbg, 5, "1");
await waitForDispatch(dbg, "ADD_BREAKPOINT");
let bp = findBreakpoint(dbg, "simple2", 5);
is(bp.condition, "1", "breakpoint is created with the condition");
assertEditorBreakpoint(dbg, 5, true);
dump('Editing a conditional breakpoint\n')
dump("Editing a conditional breakpoint\n");
await setConditionalBreakpoint(dbg, 5, "2");
await waitForDispatch(dbg, "SET_BREAKPOINT_CONDITION");
bp = findBreakpoint(dbg, "simple2", 5);
is(bp.condition, "12", "breakpoint is created with the condition");
assertEditorBreakpoint(dbg, 5, true);
dump("Removing a conditional breakpoint\n")
dump("Removing a conditional breakpoint\n");
clickElement(dbg, "gutter", 5);
await waitForDispatch(dbg, "REMOVE_BREAKPOINT");
bp = findBreakpoint(dbg, "simple2", 5);

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

@ -9,7 +9,9 @@
* Tests that the debugger is succesfully loaded in the Browser Content Toolbox.
*/
const {gDevToolsBrowser} = require("devtools/client/framework/devtools-browser");
const {
gDevToolsBrowser
} = require("devtools/client/framework/devtools-browser");
function toggleBreakpoint(dbg, index) {
const bp = findElement(dbg, "breakpointItem", index);

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

@ -0,0 +1,81 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
/**
* This if the debugger's layout is correctly modified when the toolbox's
* host changes.
*/
"use strict";
var gDefaultHostType = Services.prefs.getCharPref("devtools.toolbox.host");
add_task(async function() {
// test is too slow on some platforms due to the number of test cases
requestLongerTimeout(2);
const dbg = await initDebugger("doc-iframes.html");
const layouts = [
["horizontal", "bottom"],
["vertical", "side"],
["horizontal", "window:big"],
["vertical", "window:small"]
];
for (let layout of layouts) {
const [orientation, host] = layout;
await testLayout(dbg, orientation, host);
}
ok(true, "Orientations are correct");
});
async function testLayout(dbg, orientation, host) {
const { panel, toolbox } = dbg;
info(`Switching to ${host} ${orientation}.`);
await switchHost(dbg, host);
await resizeToolboxWindow(dbg, host);
return waitForState(
dbg,
state => dbg.selectors.getOrientation(state) == orientation
);
}
function getHost(host) {
if (host.indexOf("window") == 0) {
return "window";
}
return host;
}
async function switchHost(dbg, hostType) {
const { toolbox } = dbg;
await toolbox.switchHost(getHost(hostType));
}
function resizeToolboxWindow(dbg, host) {
const { panel, toolbox } = dbg;
let sizeOption = host.split(":")[1];
let win = toolbox.win.parent;
let breakpoint = 700;
if (sizeOption == "big" && win.outerWidth <= breakpoint) {
return resizeWindow(dbg, breakpoint + 300);
} else if (sizeOption == "small" && win.outerWidth >= breakpoint) {
return resizeWindow(dbg, breakpoint - 300);
}
}
function resizeWindow(dbg, width) {
const { panel, toolbox } = dbg;
let win = toolbox.win.parent;
const currentWidth = win.screen.width;
win.resizeTo(width, window.screen.availHeight);
}
registerCleanupFunction(function() {
Services.prefs.setCharPref("devtools.toolbox.host", gDefaultHostType);
gDefaultHostType = null;
});

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

@ -7,6 +7,10 @@
add_task(async function() {
const dbg = await initDebugger("doc-wasm-sourcemaps.html");
// NOTE: wait for page load -- attempt to fight the intermittent failure:
// "A promise chain failed to handle a rejection: Debugger.Frame is not live"
await waitForSource(dbg, "doc-wasm-sourcemaps");
await reload(dbg);
await waitForPaused(dbg);
assertPausedLocation(dbg);

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

@ -362,11 +362,11 @@ function createDebuggerContext(toolbox) {
store: store,
client: client,
toolbox: toolbox,
win: win
win: win,
panel: panel
};
}
/**
* Clear all the debugger related preferences.
*/
@ -511,7 +511,7 @@ function stepOut(dbg) {
function resume(dbg) {
info("Resuming");
dbg.actions.resume();
return waitForState(dbg, (state) => !dbg.selectors.isPaused(state));
return waitForState(dbg, state => !dbg.selectors.isPaused(state));
}
function deleteExpression(dbg, input) {

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

@ -299,3 +299,5 @@ devtools.jar:
# Debugger
skin/images/debugger/arrow.svg (themes/images/debugger/arrow.svg)
skin/images/debugger/blackBox.svg (themes/images/debugger/blackBox.svg)
skin/images/debugger/prettyPrint.svg (themes/images/debugger/prettyPrint.svg)

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

@ -24,6 +24,11 @@ copySource.accesskey=y
copySourceUri2=Copy source URI
copySourceUri2.accesskey=u
# LOCALIZATION NOTE (setDirectoryRoot): This is the text that appears in the
# context menu to set a directory as root directory
setDirectoryRoot.label=Set directory root
setDirectoryRoot.accesskey=r
# LOCALIZATION NOTE (copyFunction): This is the text that appears in the
# context menu to copy the function the user selected
copyFunction.label=Copy function
@ -367,6 +372,7 @@ editor.addBreakpoint=Add breakpoint
# LOCALIZATION NOTE (editor.disableBreakpoint): Editor gutter context menu item
# for disabling a breakpoint on a line.
editor.disableBreakpoint=Disable breakpoint
editor.disableBreakpoint.accesskey=D
# LOCALIZATION NOTE (editor.enableBreakpoint): Editor gutter context menu item
# for enabling a breakpoint on a line.
@ -381,8 +387,9 @@ editor.removeBreakpoint=Remove breakpoint
editor.editBreakpoint=Edit breakpoint
# LOCALIZATION NOTE (editor.addConditionalBreakpoint): Editor gutter context
# menu item for adding a breakpoint condition on a line.
editor.addConditionalBreakpoint=Add conditional breakpoint
# menu item for adding/editing a breakpoint condition on a line.
editor.addConditionalBreakpoint=Add/Edit conditional breakpoint
editor.addConditionalBreakpoint.accesskey=c
# LOCALIZATION NOTE (editor.conditionalPanel.placeholder): Placeholder text for
# input element inside ConditionalPanel component
@ -395,6 +402,7 @@ editor.conditionalPanel.close=Cancel edit breakpoint and close
# LOCALIZATION NOTE (editor.jumpToMappedLocation1): Context menu item
# for navigating to a source mapped location
editor.jumpToMappedLocation1=Jump to %S location
editor.jumpToMappedLocation1.accesskey=m
# LOCALIZATION NOTE (framework.disableGrouping): This is the text that appears in the
# context menu to disable framework grouping.
@ -415,6 +423,7 @@ original=original
# LOCALIZATION NOTE (expressions.placeholder): Placeholder text for expression
# input element
expressions.placeholder=Add watch expression
expressions.placeholder.accesskey=e
# LOCALIZATION NOTE (sourceTabs.closeTab): Editor source tab context menu item
# for closing the selected tab below the mouse.
@ -468,10 +477,6 @@ sourceFooter.codeCoverage=Code coverage
# for close tab button in source tabs.
sourceTabs.closeTabButtonTooltip=Close tab
# LOCALIZATION NOTE (sourceTabs.newTabButtonTooltip): The tooltip that is displayed for
# new tab button in source tabs.
sourceTabs.newTabButtonTooltip=Search for sources (%S)
# LOCALIZATION NOTE (scopes.header): Scopes right sidebar pane header.
scopes.header=Scopes
@ -754,6 +759,7 @@ anonymous=(anonymous)
# LOCALIZATION NOTE (shortcuts.toggleBreakpoint): text describing
# keyboard shortcut action for toggling breakpoint
shortcuts.toggleBreakpoint=Toggle Breakpoint
shortcuts.toggleBreakpoint.accesskey=B
# LOCALIZATION NOTE (shortcuts.toggleCondPanel): text describing
# keyboard shortcut action for toggling conditional panel keyboard

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

@ -37,5 +37,10 @@ pref("devtools.debugger.file-search-case-sensitive", false);
pref("devtools.debugger.file-search-whole-word", false);
pref("devtools.debugger.file-search-regex-match", false);
pref("devtools.debugger.features.async-stepping", true);
pref("devtools.debugger.features.project-text-search", true);
pref("devtools.debugger.features.wasm", true);
pref("devtools.debugger.features.shortcuts", true);
pref("devtools.debugger.project-directory-root", "");
pref("devtools.debugger.features.root", false);
pref("devtools.debugger.features.column-breakpoints", false);

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

@ -0,0 +1,9 @@
<!-- 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 width="16" height="16" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
<g fill-rule="evenodd">
<circle cx="8" cy="8.5" r="1.5"/>
<path d="M15.498 8.28l-.001-.03v-.002-.004l-.002-.018-.004-.031c0-.002 0-.002 0 0l-.004-.035.006.082c-.037-.296-.133-.501-.28-.661-.4-.522-.915-1.042-1.562-1.604-1.36-1.182-2.74-1.975-4.178-2.309a6.544 6.544 0 0 0-2.755-.042c-.78.153-1.565.462-2.369.91C3.252 5.147 2.207 6 1.252 7.035c-.216.233-.36.398-.499.577-.338.437-.338 1 0 1.437.428.552.941 1.072 1.59 1.635 1.359 1.181 2.739 1.975 4.177 2.308.907.21 1.829.223 2.756.043.78-.153 1.564-.462 2.369-.91 1.097-.612 2.141-1.464 3.097-2.499.217-.235.36-.398.498-.578.12-.128.216-.334.248-.554 0 .01 0 .01-.008.04l.013-.079-.001.011.003-.031.001-.017v.005l.001-.02v.008l.002-.03.001-.05-.001-.044v-.004-.004zm-.954.045v.007l.001.004V8.33v.012l-.001.01v-.005-.005l.002-.015-.001.008c-.002.014-.002.014 0 0l-.007.084c.003-.057-.004-.041-.014-.031-.143.182-.27.327-.468.543-.89.963-1.856 1.752-2.86 2.311-.724.404-1.419.677-2.095.81a5.63 5.63 0 0 1-2.374-.036c-1.273-.295-2.523-1.014-3.774-2.101-.604-.525-1.075-1.001-1.457-1.496-.054-.07-.054-.107 0-.177.117-.152.244-.298.442-.512.89-.963 1.856-1.752 2.86-2.311.724-.404 1.419-.678 2.095-.81a5.631 5.631 0 0 1 2.374.036c1.272.295 2.523 1.014 3.774 2.101.603.524 1.074 1 1.457 1.496.035.041.043.057.046.076 0 .01 0 .01.008.043l-.009-.047.003.02-.002-.013v-.008.016c0-.004 0-.004 0 0v-.004z"/>
</g>
</svg>

После

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

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

@ -0,0 +1,6 @@
<!-- 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 width="16" height="16" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
<path d="M4.525 13.21h-.472c-.574 0-.987-.154-1.24-.463-.253-.31-.38-.882-.38-1.719v-.573c0-.746-.097-1.265-.292-1.557-.196-.293-.51-.44-.945-.44v-.974c.435 0 .75-.146.945-.44.195-.292.293-.811.293-1.556v-.58c0-.833.126-1.404.379-1.712.253-.31.666-.464 1.24-.464h.472v.783h-.179c-.37 0-.628.08-.774.24-.145.159-.218.54-.218 1.141v.383c0 .824-.096 1.432-.287 1.823-.191.39-.516.679-.974.866.458.191.783.482.974.873.191.39.287.998.287 1.823v.382c0 .602.073.982.218 1.142.146.16.404.239.774.239h.18v.783zm9.502-4.752c-.43 0-.744.147-.942.44-.197.292-.296.811-.296 1.557v.573c0 .837-.125 1.41-.376 1.719-.251.309-.664.463-1.237.463h-.478v-.783h.185c.37 0 .628-.08.774-.24.145-.159.218-.539.218-1.14v-.383c0-.825.096-1.433.287-1.823.191-.39.516-.682.974-.873-.458-.187-.783-.476-.974-.866-.191-.391-.287-.999-.287-1.823v-.383c0-.602-.073-.982-.218-1.142-.146-.159-.404-.239-.774-.239h-.185v-.783h.478c.573 0 .986.155 1.237.464.25.308.376.88.376 1.712v.58c0 .673.088 1.174.263 1.503.176.329.5.493.975.493v.974z" fill-rule="evenodd"/>
</svg>

После

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

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

@ -196,35 +196,36 @@ DOMParser::ParseFromStream(nsIInputStream* aStream,
}
NS_IMETHODIMP
DOMParser::ParseFromStream(nsIInputStream *stream,
const char *charset,
int32_t contentLength,
const char *contentType,
DOMParser::ParseFromStream(nsIInputStream* aStream,
const char* aCharset,
int32_t aContentLength,
const char* aContentType,
nsIDOMDocument** aResult)
{
NS_ENSURE_ARG(stream);
NS_ENSURE_ARG(contentType);
NS_ENSURE_ARG(aStream);
NS_ENSURE_ARG(aContentType);
NS_ENSURE_ARG_POINTER(aResult);
*aResult = nullptr;
bool svg = nsCRT::strcmp(contentType, "image/svg+xml") == 0;
bool svg = nsCRT::strcmp(aContentType, "image/svg+xml") == 0;
// For now, we can only create XML documents.
//XXXsmaug Should we create an HTMLDocument (in XHTML mode)
// for "application/xhtml+xml"?
if ((nsCRT::strcmp(contentType, "text/xml") != 0) &&
(nsCRT::strcmp(contentType, "application/xml") != 0) &&
(nsCRT::strcmp(contentType, "application/xhtml+xml") != 0) &&
if ((nsCRT::strcmp(aContentType, "text/xml") != 0) &&
(nsCRT::strcmp(aContentType, "application/xml") != 0) &&
(nsCRT::strcmp(aContentType, "application/xhtml+xml") != 0) &&
!svg)
return NS_ERROR_NOT_IMPLEMENTED;
nsresult rv;
// Put the nsCOMPtr out here so we hold a ref to the stream as needed
nsCOMPtr<nsIInputStream> bufferedStream;
nsCOMPtr<nsIInputStream> stream = aStream;
if (!NS_InputStreamIsBuffered(stream)) {
rv = NS_NewBufferedInputStream(getter_AddRefs(bufferedStream), stream,
4096);
nsCOMPtr<nsIInputStream> bufferedStream;
rv = NS_NewBufferedInputStream(getter_AddRefs(bufferedStream),
stream.forget(), 4096);
NS_ENSURE_SUCCESS(rv, rv);
stream = bufferedStream;
@ -243,11 +244,11 @@ DOMParser::ParseFromStream(nsIInputStream *stream,
mPrincipal,
nsILoadInfo::SEC_FORCE_INHERIT_PRINCIPAL,
nsIContentPolicy::TYPE_OTHER,
nsDependentCString(contentType));
nsDependentCString(aContentType));
NS_ENSURE_STATE(parserChannel);
if (charset) {
parserChannel->SetContentCharset(nsDependentCString(charset));
if (aCharset) {
parserChannel->SetContentCharset(nsDependentCString(aCharset));
}
// Tell the document to start loading
@ -284,7 +285,7 @@ DOMParser::ParseFromStream(nsIInputStream *stream,
if (NS_SUCCEEDED(rv) && NS_SUCCEEDED(status)) {
rv = listener->OnDataAvailable(parserChannel, nullptr, stream, 0,
contentLength);
aContentLength);
if (NS_FAILED(rv))
parserChannel->Cancel(rv);
parserChannel->GetStatus(&status);

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

@ -252,7 +252,8 @@ nsSyncLoader::PushSyncStream(nsIStreamListener* aListener)
NS_ENSURE_SUCCESS(rv, rv);
mLoading = true;
rv = nsSyncLoadService::PushSyncStreamToListener(in, aListener, mChannel);
rv = nsSyncLoadService::PushSyncStreamToListener(in.forget(), aListener,
mChannel);
mLoading = false;
return rv;
@ -338,14 +339,16 @@ nsSyncLoadService::LoadDocument(nsIURI *aURI,
/* static */
nsresult
nsSyncLoadService::PushSyncStreamToListener(nsIInputStream* aIn,
nsSyncLoadService::PushSyncStreamToListener(already_AddRefed<nsIInputStream> aIn,
nsIStreamListener* aListener,
nsIChannel* aChannel)
{
nsCOMPtr<nsIInputStream> in = Move(aIn);
// Set up buffering stream
nsresult rv;
nsCOMPtr<nsIInputStream> bufferedStream;
if (!NS_InputStreamIsBuffered(aIn)) {
if (!NS_InputStreamIsBuffered(in)) {
int64_t chunkSize;
rv = aChannel->GetContentLength(&chunkSize);
if (NS_FAILED(rv) || chunkSize < 1) {
@ -353,11 +356,11 @@ nsSyncLoadService::PushSyncStreamToListener(nsIInputStream* aIn,
}
chunkSize = std::min(int64_t(UINT16_MAX), chunkSize);
rv = NS_NewBufferedInputStream(getter_AddRefs(bufferedStream), aIn,
chunkSize);
rv = NS_NewBufferedInputStream(getter_AddRefs(bufferedStream),
in.forget(), chunkSize);
NS_ENSURE_SUCCESS(rv, rv);
aIn = bufferedStream;
in = bufferedStream;
}
// Load
@ -366,7 +369,7 @@ nsSyncLoadService::PushSyncStreamToListener(nsIInputStream* aIn,
uint64_t sourceOffset = 0;
while (1) {
uint64_t readCount = 0;
rv = aIn->Available(&readCount);
rv = in->Available(&readCount);
if (NS_FAILED(rv) || !readCount) {
if (rv == NS_BASE_STREAM_CLOSED) {
// End of file, but not an error
@ -378,7 +381,7 @@ nsSyncLoadService::PushSyncStreamToListener(nsIInputStream* aIn,
if (readCount > UINT32_MAX)
readCount = UINT32_MAX;
rv = aListener->OnDataAvailable(aChannel, nullptr, aIn,
rv = aListener->OnDataAvailable(aChannel, nullptr, in,
(uint32_t)std::min(sourceOffset, (uint64_t)UINT32_MAX),
(uint32_t)readCount);
if (NS_FAILED(rv)) {

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

@ -51,13 +51,13 @@ public:
/**
* Read input stream aIn in chunks and deliver synchronously to aListener.
*
* @param aIn The stream to be read.
* @param aIn The stream to be read. The ownership of this stream is taken.
* @param aListener The listener that will receive
* OnStartRequest/OnDataAvailable/OnStopRequest
* notifications.
* @param aChannel The channel that aIn was opened from.
*/
static nsresult PushSyncStreamToListener(nsIInputStream* aIn,
static nsresult PushSyncStreamToListener(already_AddRefed<nsIInputStream> aIn,
nsIStreamListener* aListener,
nsIChannel* aChannel);
};

24
dom/cache/DBSchema.cpp поставляемый
Просмотреть файл

@ -2122,7 +2122,17 @@ ReadResponse(mozIStorageConnection* aConn, EntryId aEntryId,
rv = state->GetIsNull(6, &nullPadding);
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
#ifdef NIGHTLY_BUILD
bool shouldUpdateTo26 = false;
if (nullPadding && aSavedResponseOut->mValue.type() == ResponseType::Opaque) {
// XXXtt: This should be removed in the future (e.g. Nightly 58) by
// bug 1398167.
shouldUpdateTo26 = true;
aSavedResponseOut->mValue.paddingSize() = 0;
} else if (nullPadding) {
#else
if (nullPadding) {
#endif // NIGHTLY_BUILD
MOZ_DIAGNOSTIC_ASSERT(aSavedResponseOut->mValue.type() !=
ResponseType::Opaque);
aSavedResponseOut->mValue.paddingSize() =
@ -2141,6 +2151,20 @@ ReadResponse(mozIStorageConnection* aConn, EntryId aEntryId,
rv = state->GetBlobAsUTF8String(7, aSavedResponseOut->mValue.channelInfo().securityInfo());
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
#ifdef NIGHTLY_BUILD
if (shouldUpdateTo26) {
// XXXtt: This is a quick fix for not updating properly in Nightly 57.
// Note: This should be removed in the future (e.g. Nightly 58) by
// bug 1398167.
rv = aConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
"UPDATE entries SET response_padding_size = 0 "
"WHERE response_type = 4 " // opaque response
"AND response_padding_size IS NULL"
));
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
}
#endif // NIGHTLY_BUILD
rv = aConn->CreateStatement(NS_LITERAL_CSTRING(
"SELECT "
"name, "

3
dom/cache/FileUtils.cpp поставляемый
Просмотреть файл

@ -737,7 +737,8 @@ LockedDirectoryPaddingGet(nsIFile* aBaseDir, int64_t* aPaddingSizeOut)
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
nsCOMPtr<nsIInputStream> bufferedStream;
rv = NS_NewBufferedInputStream(getter_AddRefs(bufferedStream), stream, 512);
rv = NS_NewBufferedInputStream(getter_AddRefs(bufferedStream), stream.forget(),
512);
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
nsCOMPtr<nsIObjectInputStream> objectStream =

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

@ -31,17 +31,8 @@ namespace dom {
* that add and remove fake gamepads, avoiding the platform-specific backends.
*/
NS_IMPL_CYCLE_COLLECTION_CLASS(GamepadServiceTest)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(GamepadServiceTest,
DOMEventTargetHelper)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mWindow)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(GamepadServiceTest,
DOMEventTargetHelper)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mWindow)
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_INHERITED(GamepadServiceTest, DOMEventTargetHelper,
mWindow)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(GamepadServiceTest)
NS_INTERFACE_MAP_ENTRY(nsIIPCBackgroundChildCreateCallback)

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

@ -529,7 +529,7 @@ FSMultipartFormData::AddNameBlobOrNullPair(const nsAString& aName, Blob* aBlob)
// Create buffered stream (for efficiency)
nsCOMPtr<nsIInputStream> bufferedStream;
rv = NS_NewBufferedInputStream(getter_AddRefs(bufferedStream),
fileStream, 8192);
fileStream.forget(), 8192);
NS_ENSURE_SUCCESS(rv, rv);
fileStream = bufferedStream;

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

@ -766,21 +766,11 @@ HTMLContentSink::~HTMLContentSink()
delete mHeadContext;
}
NS_IMPL_CYCLE_COLLECTION_CLASS(HTMLContentSink)
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(HTMLContentSink, nsContentSink)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mHTMLDocument)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mRoot)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mBody)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mHead)
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(HTMLContentSink,
nsContentSink)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mHTMLDocument)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mRoot)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mBody)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mHead)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_INHERITED(HTMLContentSink, nsContentSink,
mHTMLDocument,
mRoot,
mBody,
mHead)
NS_IMPL_ISUPPORTS_CYCLE_COLLECTION_INHERITED(HTMLContentSink,
nsContentSink,

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

@ -186,16 +186,13 @@ interface nsIServiceWorkerManager : nsISupports
// Testing
DOMString getScopeForUrl(in nsIPrincipal aPrincipal, in DOMString aPath);
// Note: This is meant to be used only by about:serviceworkers.
// It returns an array of nsIServiceWorkerRegistrationInfos.
nsIArray getAllRegistrations();
// Note: This is meant to be used only by about:serviceworkers.
// It calls softUpdate() for each child process.
[implicit_jscontext] void propagateSoftUpdate(in jsval aOriginAttributes,
in DOMString aScope);
// Note: This is meant to be used only by about:serviceworkers.
// It calls unregister() in each child process. The callback is used to
// inform when unregister() is completed on the current process.
void propagateUnregister(in nsIPrincipal aPrincipal,

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

@ -29,9 +29,11 @@ public:
{
}
void Reset()
void RetrieveDataFrom(CoalescedInputData& aSource)
{
mCoalescedInputEvent = nullptr;
mCoalescedInputEvent = Move(aSource.mCoalescedInputEvent);
mGuid = aSource.mGuid;
mInputBlockId = aSource.mInputBlockId;
}
bool IsEmpty()
@ -43,9 +45,9 @@ public:
const ScrollableLayerGuid& aGuid,
const uint64_t& aInputBlockId);
const InputEventType* GetCoalescedEvent()
UniquePtr<InputEventType> TakeCoalescedEvent()
{
return mCoalescedInputEvent.get();
return Move(mCoalescedInputEvent);
}
ScrollableLayerGuid GetScrollableLayerGuid()

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

@ -55,8 +55,8 @@ void
CoalescedMouseMoveFlusher::WillRefresh(mozilla::TimeStamp aTime)
{
MOZ_ASSERT(mRefreshDriver);
mTabChild->MaybeDispatchCoalescedMouseMoveEvents();
RemoveObserver();
mTabChild->FlushAllCoalescedMouseData();
mTabChild->ProcessPendingCoalescedMouseDataAndDispatchEvents();
}
void

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

@ -1059,6 +1059,15 @@ TabChild::DestroyWindow()
mCoalescedMouseEventFlusher->RemoveObserver();
mCoalescedMouseEventFlusher = nullptr;
}
// In case we don't have chance to process all entries, clean all data in
// the queue.
while (mToBeDispatchedMouseData.GetSize() > 0) {
UniquePtr<CoalescedMouseData> data(
static_cast<CoalescedMouseData*>(mToBeDispatchedMouseData.PopFront()));
data.reset();
}
nsCOMPtr<nsIBaseWindow> baseWindow = do_QueryInterface(WebNavigation());
if (baseWindow)
baseWindow->Destroy();
@ -1591,28 +1600,62 @@ TabChild::RecvMouseEvent(const nsString& aType,
}
void
TabChild::MaybeDispatchCoalescedMouseMoveEvents()
TabChild::ProcessPendingCoalescedMouseDataAndDispatchEvents()
{
if (!mCoalesceMouseMoveEvents) {
if (!mCoalesceMouseMoveEvents || !mCoalescedMouseEventFlusher) {
// We don't enable mouse coalescing or we are destroying TabChild.
return;
}
// We may reentry the event loop and push more data to
// mToBeDispatchedMouseData while dispatching an event.
// We may have some pending coalesced data while dispatch an event and reentry
// the event loop. In that case we don't have chance to consume the remainding
// pending data until we get new mouse events. Get some helps from
// mCoalescedMouseEventFlusher to trigger it.
mCoalescedMouseEventFlusher->StartObserver();
while (mToBeDispatchedMouseData.GetSize() > 0) {
UniquePtr<CoalescedMouseData> data(
static_cast<CoalescedMouseData*>(mToBeDispatchedMouseData.PopFront()));
UniquePtr<WidgetMouseEvent> event = data->TakeCoalescedEvent();
if (event) {
// Dispatch the pending events. Using HandleRealMouseButtonEvent
// to bypass the coalesce handling in RecvRealMouseMoveEvent. Can't use
// RecvRealMouseButtonEvent because we may also put some mouse events
// other than mousemove.
HandleRealMouseButtonEvent(*event,
data->GetScrollableLayerGuid(),
data->GetInputBlockId());
}
}
// mCoalescedMouseEventFlusher may be destroyed when reentrying the event
// loop.
if (mCoalescedMouseEventFlusher) {
mCoalescedMouseEventFlusher->RemoveObserver();
}
}
void
TabChild::FlushAllCoalescedMouseData()
{
MOZ_ASSERT(mCoalesceMouseMoveEvents);
// Move all entries from mCoalescedMouseData to mToBeDispatchedMouseData.
for (auto iter = mCoalescedMouseData.Iter(); !iter.Done(); iter.Next()) {
CoalescedMouseData* data = iter.UserData();
if (!data || data->IsEmpty()) {
continue;
}
const WidgetMouseEvent* event = data->GetCoalescedEvent();
MOZ_ASSERT(event);
// Dispatch the coalesced mousemove event. Using RecvRealMouseButtonEvent to
// bypass the coalesce handling in RecvRealMouseMoveEvent.
RecvRealMouseButtonEvent(*event,
data->GetScrollableLayerGuid(),
data->GetInputBlockId());
data->Reset();
}
if (mCoalescedMouseEventFlusher) {
mCoalescedMouseEventFlusher->RemoveObserver();
UniquePtr<CoalescedMouseData> dispatchData =
MakeUnique<CoalescedMouseData>();
dispatchData->RetrieveDataFrom(*data);
mToBeDispatchedMouseData.Push(dispatchData.release());
}
mCoalescedMouseData.Clear();
}
mozilla::ipc::IPCResult
@ -1632,10 +1675,23 @@ TabChild::RecvRealMouseMoveEvent(const WidgetMouseEvent& aEvent,
mCoalescedMouseEventFlusher->StartObserver();
return IPC_OK();
}
// Can't coalesce current mousemove event. Dispatch the coalesced mousemove
// event and coalesce the current one.
MaybeDispatchCoalescedMouseMoveEvents();
data->Coalesce(aEvent, aGuid, aInputBlockId);
// Can't coalesce current mousemove event. Put the coalesced mousemove data
// with the same pointer id to mToBeDispatchedMouseData, coalesce the
// current one, and process all pending data in mToBeDispatchedMouseData.
MOZ_ASSERT(data);
UniquePtr<CoalescedMouseData> dispatchData =
MakeUnique<CoalescedMouseData>();
dispatchData->RetrieveDataFrom(*data);
mToBeDispatchedMouseData.Push(dispatchData.release());
// Put new data to replace the old one in the hash table.
CoalescedMouseData* newData = new CoalescedMouseData();
mCoalescedMouseData.Put(aEvent.pointerId, newData);
newData->Coalesce(aEvent, aGuid, aInputBlockId);
// Dispatch all pending mouse events.
ProcessPendingCoalescedMouseDataAndDispatchEvents();
mCoalescedMouseEventFlusher->StartObserver();
} else if (!RecvRealMouseButtonEvent(aEvent, aGuid, aInputBlockId)) {
return IPC_FAIL_NO_REASON(this);
@ -1675,16 +1731,35 @@ TabChild::RecvRealMouseButtonEvent(const WidgetMouseEvent& aEvent,
const ScrollableLayerGuid& aGuid,
const uint64_t& aInputBlockId)
{
if (aEvent.mMessage != eMouseMove) {
// Flush the coalesced mousemove event before dispatching other mouse
// events.
MaybeDispatchCoalescedMouseMoveEvents();
if (aEvent.mMessage == eMouseEnterIntoWidget) {
mCoalescedMouseData.Put(aEvent.pointerId, new CoalescedMouseData());
} else if (aEvent.mMessage == eMouseExitFromWidget) {
mCoalescedMouseData.Remove(aEvent.pointerId);
if (mCoalesceMouseMoveEvents && mCoalescedMouseEventFlusher &&
aEvent.mMessage != eMouseMove) {
// When receiving a mouse event other than mousemove, we have to dispatch
// all coalesced events before it. However, we can't dispatch all pending
// coalesced events directly because we may reentry the event loop while
// dispatching. To make sure we won't dispatch disorder events, we move all
// coalesced mousemove events and current event to a deque to dispatch them.
// When reentrying the event loop and dispatching more events, we put new
// events in the end of the nsQueue and dispatch events from the beginning.
FlushAllCoalescedMouseData();
UniquePtr<CoalescedMouseData> dispatchData =
MakeUnique<CoalescedMouseData>();
dispatchData->Coalesce(aEvent, aGuid, aInputBlockId);
mToBeDispatchedMouseData.Push(dispatchData.release());
ProcessPendingCoalescedMouseDataAndDispatchEvents();
return IPC_OK();
}
HandleRealMouseButtonEvent(aEvent, aGuid, aInputBlockId);
return IPC_OK();
}
void
TabChild::HandleRealMouseButtonEvent(const WidgetMouseEvent& aEvent,
const ScrollableLayerGuid& aGuid,
const uint64_t& aInputBlockId)
{
// Mouse events like eMouseEnterIntoWidget, that are created in the parent
// process EventStateManager code, have an input block id which they get from
// the InputAPZContext in the parent process stack. However, they did not
@ -1714,7 +1789,6 @@ TabChild::RecvRealMouseButtonEvent(const WidgetMouseEvent& aEvent,
if (aInputBlockId && aEvent.mFlags.mHandledByAPZ) {
mAPZEventState->ProcessMouseEvent(aEvent, aGuid, aInputBlockId);
}
return IPC_OK();
}
mozilla::ipc::IPCResult
@ -1779,13 +1853,12 @@ TabChild::MaybeDispatchCoalescedWheelEvent()
if (mCoalescedWheelData.IsEmpty()) {
return;
}
const WidgetWheelEvent* wheelEvent =
mCoalescedWheelData.GetCoalescedEvent();
UniquePtr<WidgetWheelEvent> wheelEvent =
mCoalescedWheelData.TakeCoalescedEvent();
MOZ_ASSERT(wheelEvent);
DispatchWheelEvent(*wheelEvent,
mCoalescedWheelData.GetScrollableLayerGuid(),
mCoalescedWheelData.GetInputBlockId());
mCoalescedWheelData.Reset();
}
void

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

@ -41,6 +41,7 @@
#include "AudioChannelService.h"
#include "PuppetWidget.h"
#include "mozilla/layers/GeckoContentController.h"
#include "nsDeque.h"
#include "nsISHistoryListener.h"
#include "nsIPartialSHistoryListener.h"
@ -761,8 +762,17 @@ public:
return mWidgetNativeData;
}
// Prepare to dispatch all coalesced mousemove events. We'll move all data
// in mCoalescedMouseData to a nsDeque; then we start processing them. We
// can't fetch the coalesced event one by one and dispatch it because we may
// reentry the event loop and access to the same hashtable. It's called when
// dispatching some mouse events other than mousemove.
void FlushAllCoalescedMouseData();
void ProcessPendingCoalescedMouseDataAndDispatchEvents();
void MaybeDispatchCoalescedMouseMoveEvents();
void HandleRealMouseButtonEvent(const WidgetMouseEvent& aEvent,
const ScrollableLayerGuid& aGuid,
const uint64_t& aInputBlockId);
static bool HasActiveTabs()
{
@ -948,7 +958,12 @@ private:
// takes time, some repeated events can be skipped to not flood child process.
mozilla::TimeStamp mLastWheelProcessedTimeFromParent;
mozilla::TimeDuration mLastWheelProcessingDuration;
// Hash table to track coalesced mousemove events for different pointers.
nsClassHashtable<nsUint32HashKey, CoalescedMouseData> mCoalescedMouseData;
nsDeque mToBeDispatchedMouseData;
CoalescedWheelData mCoalescedWheelData;
RefPtr<CoalescedMouseMoveFlusher> mCoalescedMouseEventFlusher;

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

@ -2,7 +2,6 @@
skip-if = os == 'android'
support-files =
process_error.xul
process_error_contentscript.js
[test_process_error.xul]
skip-if = !crashreporter

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

@ -7,6 +7,7 @@
<browser id="thebrowser" type="content" remote="true" />
<script type="application/javascript"><![CDATA[
Components.utils.import("resource://gre/modules/Services.jsm");
Components.utils.import("resource://testing-common/BrowserTestUtils.jsm");
const ok = window.opener.wrappedJSObject.ok;
const is = window.opener.wrappedJSObject.is;
@ -18,24 +19,19 @@
ok(subject instanceof Components.interfaces.nsIPropertyBag2,
'Subject implements nsIPropertyBag2.');
var waitCrash = Promise.resolve();
var dumpID;
if ('nsICrashReporter' in Components.interfaces) {
dumpID = subject.getPropertyAsAString('dumpID');
ok(dumpID, "dumpID is present and not an empty string");
waitCrash = Services.crashmanager.ensureCrashIsPresent(dumpID);
}
Services.obs.removeObserver(crashObserver, 'ipc:content-shutdown');
waitCrash.then(done);
done();
}
Services.obs.addObserver(crashObserver, 'ipc:content-shutdown');
document.getElementById('thebrowser')
.QueryInterface(Components.interfaces.nsIFrameLoaderOwner)
.frameLoader.messageManager
.loadFrameScript('chrome://mochitests/content/chrome/dom/ipc/tests/process_error_contentscript.js', true);
BrowserTestUtils.crashBrowser(document.getElementById('thebrowser'));
]]></script>
</window>

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

@ -1,7 +0,0 @@
Components.utils.import("resource://gre/modules/ctypes.jsm");
privateNoteIntentionalCrash();
var zero = new ctypes.intptr_t(8);
var badptr = ctypes.cast(zero, ctypes.PointerType(ctypes.int32_t));
var crash = badptr.contents;

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

@ -42,14 +42,10 @@ var testObserver = {
let additionalDumps = extraData.additional_minidumps.split(',');
ok(additionalDumps.indexOf('browser') >= 0, "browser in additional_minidumps");
let additionalDumpFiles = [];
for (let name of additionalDumps) {
let file = profD.clone();
file.append(pluginId + "-" + name + ".dmp");
ok(file.exists(), "additional dump '"+name+"' exists");
if (file.exists()) {
additionalDumpFiles.push(file);
}
}
// check cpu usage field
@ -103,7 +99,5 @@ function onPluginCrashed(aEvent) {
getService(Ci.nsIObserverService);
os.removeObserver(testObserver, "plugin-crashed");
Services.crashmanager.ensureCrashIsPresent(aEvent.pluginDumpID).then(() => {
SimpleTest.finish();
});
}

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

@ -19,8 +19,6 @@
</body>
<script class="testbody" type="application/javascript">
<![CDATA[
Components.utils.import("resource://gre/modules/Services.jsm");
SimpleTest.waitForExplicitFinish();
SimpleTest.expectChildProcessCrash();

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

@ -15,7 +15,7 @@
</body>
<script class="testbody" type="application/javascript">
<![CDATA[
Components.utils.import("resource://gre/modules/Services.jsm");
Components.utils.import("resource://gre/modules/PromiseUtils.jsm");
SimpleTest.waitForExplicitFinish();
SimpleTest.expectChildProcessCrash();
@ -23,6 +23,8 @@ SimpleTest.expectChildProcessCrash();
var success = false;
var observerFired = false;
var observerDeferred = PromiseUtils.defer();
var eventListenerDeferred = PromiseUtils.defer();
var testObserver = {
observe: function(subject, topic, data) {
@ -46,6 +48,8 @@ var testObserver = {
let extraFile = profD.clone();
extraFile.append(id + ".extra");
ok(extraFile.exists(), "extra file exists");
observerDeferred.resolve();
},
QueryInterface: function(iid) {
@ -84,9 +88,7 @@ function onPluginCrashed(aEvent) {
getService(Components.interfaces.nsIObserverService);
os.removeObserver(testObserver, "plugin-crashed");
Services.crashmanager.ensureCrashIsPresent(aEvent.pluginDumpID).then(() => {
SimpleTest.finish();
});
eventListenerDeferred.resolve();
}
function runTests() {
@ -101,6 +103,13 @@ function runTests() {
pluginElement.crash();
} catch (e) {
}
Promise.all([
observerDeferred.promise,
eventListenerDeferred.promise
]).then(() => {
SimpleTest.finish();
});
}
]]>
</script>

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

@ -19,8 +19,6 @@
</body>
<script class="testbody" type="application/javascript">
<![CDATA[
Components.utils.import("resource://gre/modules/Services.jsm");
SimpleTest.waitForExplicitFinish();
SimpleTest.expectChildProcessCrash();

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

@ -2454,7 +2454,8 @@ GetBinaryInputStream(nsIFile* aDirectory,
}
nsCOMPtr<nsIInputStream> bufferedStream;
rv = NS_NewBufferedInputStream(getter_AddRefs(bufferedStream), stream, 512);
rv = NS_NewBufferedInputStream(getter_AddRefs(bufferedStream),
stream.forget(), 512);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
@ -5235,46 +5236,11 @@ QuotaManager::EnsureOriginIsInitializedInternal(
*aCreated = false;
return NS_OK;
}
} else if (!mTemporaryStorageInitialized) {
rv = InitializeRepository(aPersistenceType);
if (NS_WARN_IF(NS_FAILED(rv))) {
// We have to cleanup partially initialized quota.
RemoveQuota();
return rv;
}
rv = InitializeRepository(ComplementaryPersistenceType(aPersistenceType));
if (NS_WARN_IF(NS_FAILED(rv))) {
// We have to cleanup partially initialized quota.
RemoveQuota();
return rv;
}
if (gFixedLimitKB >= 0) {
mTemporaryStorageLimit = static_cast<uint64_t>(gFixedLimitKB) * 1024;
}
else {
nsCOMPtr<nsIFile> storageDir =
do_CreateInstance(NS_LOCAL_FILE_CONTRACTID, &rv);
} else {
rv = EnsureTemporaryStorageIsInitialized();
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
rv = storageDir->InitWithPath(GetStoragePath());
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
rv = GetTemporaryStorageLimit(storageDir, mTemporaryStorageUsage,
&mTemporaryStorageLimit);
NS_ENSURE_SUCCESS(rv, rv);
}
mTemporaryStorageInitialized = true;
CheckTemporaryStorageLimits();
}
bool created;
@ -5337,6 +5303,60 @@ QuotaManager::EnsureOriginIsInitializedInternal(
return NS_OK;
}
nsresult
QuotaManager::EnsureTemporaryStorageIsInitialized()
{
AssertIsOnIOThread();
MOZ_ASSERT(mStorageInitialized);
if (mTemporaryStorageInitialized) {
return NS_OK;
}
nsresult rv = InitializeRepository(PERSISTENCE_TYPE_DEFAULT);
if (NS_WARN_IF(NS_FAILED(rv))) {
// We have to cleanup partially initialized quota.
RemoveQuota();
return rv;
}
rv = InitializeRepository(PERSISTENCE_TYPE_TEMPORARY);
if (NS_WARN_IF(NS_FAILED(rv))) {
// We have to cleanup partially initialized quota.
RemoveQuota();
return rv;
}
if (gFixedLimitKB >= 0) {
mTemporaryStorageLimit = static_cast<uint64_t>(gFixedLimitKB) * 1024;
} else {
nsCOMPtr<nsIFile> storageDir =
do_CreateInstance(NS_LOCAL_FILE_CONTRACTID, &rv);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
rv = storageDir->InitWithPath(GetStoragePath());
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
rv = GetTemporaryStorageLimit(storageDir, mTemporaryStorageUsage,
&mTemporaryStorageLimit);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
}
mTemporaryStorageInitialized = true;
CheckTemporaryStorageLimits();
return rv;
}
void
QuotaManager::OriginClearCompleted(PersistenceType aPersistenceType,
const nsACString& aOrigin)
@ -7147,14 +7167,16 @@ GetOriginUsageOp::DoDirectoryWork(QuotaManager* aQuotaManager)
nsresult rv;
if (mGetGroupUsage) {
nsCOMPtr<nsIFile> directory;
// Ensure temporary storage is initialized first. It will initialize all
// origins for temporary storage including origins belonging to our group by
// traversing the repositories. EnsureStorageIsInitialized is needed before
// EnsureTemporaryStorageIsInitialized.
rv = aQuotaManager->EnsureStorageIsInitialized();
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
// Ensure origin is initialized first. It will initialize all origins for
// temporary storage including origins belonging to our group.
rv = aQuotaManager->EnsureOriginIsInitialized(PERSISTENCE_TYPE_TEMPORARY,
mSuffix, mGroup,
mOriginScope.GetOrigin(),
getter_AddRefs(directory));
rv = aQuotaManager->EnsureTemporaryStorageIsInitialized();
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}

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

@ -298,6 +298,9 @@ public:
nsIFile** aDirectory,
bool* aCreated);
nsresult
EnsureTemporaryStorageIsInitialized();
void
OriginClearCompleted(PersistenceType aPersistenceType,
const nsACString& aOrigin);

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

@ -1491,7 +1491,8 @@ nsresult nsWebBrowserPersist::SaveChannelInternal(
getter_AddRefs(fileInputStream));
NS_ENSURE_SUCCESS(rv, rv);
rv = NS_NewBufferedInputStream(getter_AddRefs(bufferedInputStream),
fileInputStream, BUFFERED_OUTPUT_SIZE);
fileInputStream.forget(),
BUFFERED_OUTPUT_SIZE);
NS_ENSURE_SUCCESS(rv, rv);
nsAutoCString contentType;
aChannel->GetContentType(contentType);

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

@ -215,7 +215,7 @@ FileReaderSync::ReadAsText(Blob& aBlob,
}
nsCOMPtr<nsIInputStream> syncStream;
aRv = ConvertAsyncToSyncStream(blobSize - sniffBuf.Length(), stream,
aRv = ConvertAsyncToSyncStream(blobSize - sniffBuf.Length(), stream.forget(),
getter_AddRefs(syncStream));
if (NS_WARN_IF(aRv.Failed())) {
return;
@ -269,7 +269,8 @@ FileReaderSync::ReadAsDataURL(Blob& aBlob, nsAString& aResult,
}
nsCOMPtr<nsIInputStream> syncStream;
aRv = ConvertAsyncToSyncStream(blobSize, stream, getter_AddRefs(syncStream));
aRv = ConvertAsyncToSyncStream(blobSize, stream.forget(),
getter_AddRefs(syncStream));
if (NS_WARN_IF(aRv.Failed())) {
return;
}
@ -475,13 +476,15 @@ FileReaderSync::SyncRead(nsIInputStream* aStream, char* aBuffer,
nsresult
FileReaderSync::ConvertAsyncToSyncStream(uint64_t aStreamSize,
nsIInputStream* aAsyncStream,
already_AddRefed<nsIInputStream> aAsyncStream,
nsIInputStream** aSyncStream)
{
nsCOMPtr<nsIInputStream> asyncInputStream = Move(aAsyncStream);
// If the stream is not async, we just need it to be bufferable.
nsCOMPtr<nsIAsyncInputStream> asyncStream = do_QueryInterface(aAsyncStream);
nsCOMPtr<nsIAsyncInputStream> asyncStream = do_QueryInterface(asyncInputStream);
if (!asyncStream) {
return NS_NewBufferedInputStream(aSyncStream, aAsyncStream, 4096);
return NS_NewBufferedInputStream(aSyncStream, asyncInputStream.forget(), 4096);
}
nsAutoCString buffer;
@ -491,7 +494,7 @@ FileReaderSync::ConvertAsyncToSyncStream(uint64_t aStreamSize,
uint32_t read;
nsresult rv =
SyncRead(aAsyncStream, buffer.BeginWriting(), aStreamSize, &read);
SyncRead(asyncInputStream, buffer.BeginWriting(), aStreamSize, &read);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}

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

@ -33,7 +33,7 @@ private:
nsAString &aResult);
nsresult ConvertAsyncToSyncStream(uint64_t aStreamSize,
nsIInputStream* aAsyncStream,
already_AddRefed<nsIInputStream> aAsyncStream,
nsIInputStream** aSyncStream);
nsresult SyncRead(nsIInputStream* aStream, char* aBuffer,

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

@ -1116,7 +1116,8 @@ nsXBLService::FetchBindingDocument(nsIContent* aBoundElement, nsIDocument* aBoun
rv = channel->Open2(getter_AddRefs(in));
NS_ENSURE_SUCCESS(rv, rv);
rv = nsSyncLoadService::PushSyncStreamToListener(in, listener, channel);
rv = nsSyncLoadService::PushSyncStreamToListener(in.forget(), listener,
channel);
NS_ENSURE_SUCCESS(rv, rv);
doc.swap(*aResult);

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

@ -2561,11 +2561,12 @@ XMLHttpRequestMainThread::MaybeLowerChannelPriority()
}
nsresult
XMLHttpRequestMainThread::InitiateFetch(nsIInputStream* aUploadStream,
XMLHttpRequestMainThread::InitiateFetch(already_AddRefed<nsIInputStream> aUploadStream,
int64_t aUploadLength,
nsACString& aUploadContentType)
{
nsresult rv;
nsCOMPtr<nsIInputStream> uploadStream = Move(aUploadStream);
// nsIRequest::LOAD_BACKGROUND prevents throbber from becoming active, which
// in turn keeps STOP button from becoming active. If the consumer passed in
@ -2615,16 +2616,16 @@ XMLHttpRequestMainThread::InitiateFetch(nsIInputStream* aUploadStream,
}
}
if (aUploadStream) {
if (uploadStream) {
// If necessary, wrap the stream in a buffered stream so as to guarantee
// support for our upload when calling ExplicitSetUploadStream.
if (!NS_InputStreamIsBuffered(uploadStream)) {
nsCOMPtr<nsIInputStream> bufferedStream;
if (!NS_InputStreamIsBuffered(aUploadStream)) {
rv = NS_NewBufferedInputStream(getter_AddRefs(bufferedStream),
aUploadStream, 4096);
uploadStream.forget(), 4096);
NS_ENSURE_SUCCESS(rv, rv);
aUploadStream = bufferedStream;
uploadStream = bufferedStream;
}
// We want to use a newer version of the upload channel that won't
@ -2633,7 +2634,7 @@ XMLHttpRequestMainThread::InitiateFetch(nsIInputStream* aUploadStream,
// This assertion will fire if buggy extensions are installed
NS_ASSERTION(uploadChannel2, "http must support nsIUploadChannel2");
if (uploadChannel2) {
uploadChannel2->ExplicitSetUploadStream(aUploadStream,
uploadChannel2->ExplicitSetUploadStream(uploadStream,
aUploadContentType,
mUploadTotal, mRequestMethod,
false);
@ -2645,7 +2646,7 @@ XMLHttpRequestMainThread::InitiateFetch(nsIInputStream* aUploadStream,
}
nsCOMPtr<nsIUploadChannel> uploadChannel =
do_QueryInterface(httpChannel);
uploadChannel->SetUploadStream(aUploadStream, aUploadContentType,
uploadChannel->SetUploadStream(uploadStream, aUploadContentType,
mUploadTotal);
// Reset the method to its original value
rv = httpChannel->SetRequestMethod(mRequestMethod);
@ -3053,7 +3054,7 @@ XMLHttpRequestMainThread::SendInternal(const BodyExtractorBase* aBody)
}
}
rv = InitiateFetch(uploadStream, mUploadTotal, uploadContentType);
rv = InitiateFetch(uploadStream.forget(), mUploadTotal, uploadContentType);
NS_ENSURE_SUCCESS(rv, rv);
// Start our timeout

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

@ -261,7 +261,7 @@ public:
// request
nsresult CreateChannel();
nsresult InitiateFetch(nsIInputStream* aUploadStream,
nsresult InitiateFetch(already_AddRefed<nsIInputStream> aUploadStream,
int64_t aUploadLength,
nsACString& aUploadContentType);

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

@ -1,4 +1,4 @@
52368
52371
0/nm
0th/pt
1/n1
@ -16621,6 +16621,7 @@ billycan/S
bimbo/MS
bimetallic/SM
bimetallism/M
bimodal
bimonthly/SM
bin/SM
binary/SM
@ -36405,6 +36406,8 @@ nondepreciating
nondescript
nondestructive
nondetachable
nondeterminism
nondeterministic
nondisciplinary
nondisclosure/M
nondiscrimination/M

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

@ -333,7 +333,8 @@ CreateBufferedStream(const uint8_t *aBuffer, uint32_t aBufLen,
nsCOMPtr<nsIInputStream> aBufferedStream;
if (!NS_InputStreamIsBuffered(stream)) {
rv = NS_NewBufferedInputStream(getter_AddRefs(aBufferedStream), stream, 4096);
rv = NS_NewBufferedInputStream(getter_AddRefs(aBufferedStream),
stream.forget(), 4096);
NS_ENSURE_SUCCESS(rv, rv);
stream = aBufferedStream;
}

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

@ -100,20 +100,20 @@ private:
};
/* static */ already_AddRefed<ImageOps::ImageBuffer>
ImageOps::CreateImageBuffer(nsIInputStream* aInputStream)
ImageOps::CreateImageBuffer(already_AddRefed<nsIInputStream> aInputStream)
{
MOZ_ASSERT(aInputStream);
nsCOMPtr<nsIInputStream> inputStream = Move(aInputStream);
MOZ_ASSERT(inputStream);
nsresult rv;
// Prepare the input stream.
nsCOMPtr<nsIInputStream> inputStream = aInputStream;
if (!NS_InputStreamIsBuffered(aInputStream)) {
if (!NS_InputStreamIsBuffered(inputStream)) {
nsCOMPtr<nsIInputStream> bufStream;
rv = NS_NewBufferedInputStream(getter_AddRefs(bufStream),
aInputStream, 1024);
if (NS_SUCCEEDED(rv)) {
inputStream = bufStream;
inputStream.forget(), 1024);
if (NS_WARN_IF(NS_FAILED(rv))) {
return nullptr;
}
}
@ -145,11 +145,12 @@ ImageOps::CreateImageBuffer(nsIInputStream* aInputStream)
}
/* static */ nsresult
ImageOps::DecodeMetadata(nsIInputStream* aInputStream,
ImageOps::DecodeMetadata(already_AddRefed<nsIInputStream> aInputStream,
const nsACString& aMimeType,
ImageMetadata& aMetadata)
{
RefPtr<ImageBuffer> buffer = CreateImageBuffer(aInputStream);
nsCOMPtr<nsIInputStream> inputStream = Move(aInputStream);
RefPtr<ImageBuffer> buffer = CreateImageBuffer(inputStream.forget());
return DecodeMetadata(buffer, aMimeType, aMetadata);
}
@ -193,12 +194,13 @@ ImageOps::DecodeMetadata(ImageBuffer* aBuffer,
}
/* static */ already_AddRefed<gfx::SourceSurface>
ImageOps::DecodeToSurface(nsIInputStream* aInputStream,
ImageOps::DecodeToSurface(already_AddRefed<nsIInputStream> aInputStream,
const nsACString& aMimeType,
uint32_t aFlags,
const Maybe<IntSize>& aSize /* = Nothing() */)
{
RefPtr<ImageBuffer> buffer = CreateImageBuffer(aInputStream);
nsCOMPtr<nsIInputStream> inputStream = Move(aInputStream);
RefPtr<ImageBuffer> buffer = CreateImageBuffer(inputStream.forget());
return DecodeToSurface(buffer, aMimeType, aFlags, aSize);
}

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

@ -93,23 +93,25 @@ public:
* an ImageBuffer representing the given input stream is more efficient if one
* has multiple Decode* calls to make on that stream.
*
* @param aInputStream An input stream containing an encoded image.
* @param aInputStream An input stream containing an encoded image. The
* ownership is taken.
* @return An image buffer derived from the input stream.
*/
static already_AddRefed<ImageBuffer>
CreateImageBuffer(nsIInputStream* aInputStream);
CreateImageBuffer(already_AddRefed<nsIInputStream> aInputStream);
/**
* Decodes an image's metadata from an nsIInputStream into the given
* structure. This function may be called off-main-thread.
*
* @param aInputStream An input stream containing an encoded image.
* @param aInputStream An input stream containing an encoded image. Ownership
* is taken.
* @param aMimeType The MIME type of the image.
* @param aMetadata Where the image metadata is stored upon success.
* @return The status of the operation.
*/
static nsresult
DecodeMetadata(nsIInputStream* aInputStream,
DecodeMetadata(already_AddRefed<nsIInputStream> aInputStream,
const nsACString& aMimeType,
ImageMetadata& aMetadata);
@ -127,14 +129,15 @@ public:
* main-thread-only). That means that this function may be called
* off-main-thread.
*
* @param aInputStream An input stream containing an encoded image.
* @param aInputStream An input stream containing an encoded image. The
* ownership is taken.
* @param aMimeType The MIME type of the image.
* @param aFlags Flags of the imgIContainer::FLAG_DECODE_* variety.
* @return A SourceSurface containing the first frame of the image at its
* intrinsic size, or nullptr if the image cannot be decoded.
*/
static already_AddRefed<gfx::SourceSurface>
DecodeToSurface(nsIInputStream* aInputStream,
DecodeToSurface(already_AddRefed<nsIInputStream> aInputStream,
const nsACString& aMimeType,
uint32_t aFlags,
const Maybe<gfx::IntSize>& aSize = Nothing());

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

@ -61,7 +61,8 @@ imgTools::DecodeImage(nsIInputStream* aInStr,
nsCOMPtr<nsIInputStream> inStream = aInStr;
if (!NS_InputStreamIsBuffered(aInStr)) {
nsCOMPtr<nsIInputStream> bufStream;
rv = NS_NewBufferedInputStream(getter_AddRefs(bufStream), aInStr, 1024);
rv = NS_NewBufferedInputStream(getter_AddRefs(bufStream),
inStream.forget(), 1024);
if (NS_SUCCEEDED(rv)) {
inStream = bufStream;
}

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

@ -52,7 +52,7 @@ public:
void Go()
{
mSurface =
ImageOps::DecodeToSurface(mInputStream,
ImageOps::DecodeToSurface(mInputStream.forget(),
nsDependentCString(mimeType.c_str()),
imgIContainer::DECODE_FLAGS_DEFAULT);
if (!mSurface)

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

@ -125,7 +125,7 @@ LoadFile(const char* aRelativePath)
if (!NS_InputStreamIsBuffered(inputStream)) {
nsCOMPtr<nsIInputStream> bufStream;
rv = NS_NewBufferedInputStream(getter_AddRefs(bufStream),
inputStream, 1024);
inputStream.forget(), 1024);
ASSERT_TRUE_OR_RETURN(NS_SUCCEEDED(rv), nullptr);
inputStream = bufStream;
}

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

@ -57,7 +57,7 @@ public:
outputSize);
} else {
mSurface =
ImageOps::DecodeToSurface(mInputStream,
ImageOps::DecodeToSurface(mInputStream.forget(),
nsDependentCString(mTestCase.mMimeType),
imgIContainer::DECODE_FLAGS_DEFAULT,
outputSize);
@ -144,7 +144,7 @@ TEST_F(ImageDecodeToSurface, Corrupt)
ASSERT_TRUE(inputStream != nullptr);
RefPtr<SourceSurface> surface =
ImageOps::DecodeToSurface(inputStream,
ImageOps::DecodeToSurface(inputStream.forget(),
nsDependentCString(testCase.mMimeType),
imgIContainer::DECODE_FLAGS_DEFAULT);
EXPECT_TRUE(surface == nullptr);
@ -158,7 +158,7 @@ TEST_F(ImageDecodeToSurface, ICOMultipleSizes)
ASSERT_TRUE(inputStream != nullptr);
RefPtr<ImageOps::ImageBuffer> buffer =
ImageOps::CreateImageBuffer(inputStream);
ImageOps::CreateImageBuffer(inputStream.forget());
ASSERT_TRUE(buffer != nullptr);
ImageMetadata metadata;

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

@ -26,6 +26,8 @@ struct HandlerProvider
struct IHandlerProvider : public IUnknown
, public HandlerProvider
{
virtual STDMETHODIMP_(REFIID) GetEffectiveOutParamIid(REFIID aCallIid,
ULONG aCallMethod) = 0;
virtual STDMETHODIMP NewInstance(REFIID aIid,
InterceptorTargetPtr<IUnknown> aTarget,
NotNull<IHandlerProvider**> aOutNewPayload) = 0;

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

@ -14,6 +14,7 @@
#include "mozilla/mscom/Utils.h"
#include "mozilla/Assertions.h"
#include "mozilla/DebugOnly.h"
#include "mozilla/ThreadLocal.h"
#include "nsThreadUtils.h"
#include "nsProxyRelease.h"
@ -154,6 +155,52 @@ private:
HRESULT mResult;
};
class MOZ_RAII SavedCallFrame final
{
public:
explicit SavedCallFrame(mozilla::NotNull<ICallFrame*> aFrame)
: mCallFrame(aFrame)
{
static const bool sIsInit = tlsFrame.init();
MOZ_ASSERT(sIsInit);
MOZ_ASSERT(!tlsFrame.get());
tlsFrame.set(this);
}
~SavedCallFrame()
{
MOZ_ASSERT(tlsFrame.get());
tlsFrame.set(nullptr);
}
HRESULT GetIidAndMethod(mozilla::NotNull<IID*> aIid,
mozilla::NotNull<ULONG*> aMethod) const
{
return mCallFrame->GetIIDAndMethod(aIid, aMethod);
}
static const SavedCallFrame& Get()
{
SavedCallFrame* saved = tlsFrame.get();
MOZ_ASSERT(saved);
return *saved;
}
SavedCallFrame(const SavedCallFrame&) = delete;
SavedCallFrame(SavedCallFrame&&) = delete;
SavedCallFrame& operator=(const SavedCallFrame&) = delete;
SavedCallFrame& operator=(SavedCallFrame&&) = delete;
private:
ICallFrame* mCallFrame;
private:
static MOZ_THREAD_LOCAL(SavedCallFrame*) tlsFrame;
};
MOZ_THREAD_LOCAL(SavedCallFrame*) SavedCallFrame::tlsFrame;
} // anonymous namespace
namespace mozilla {
@ -338,6 +385,8 @@ MainThreadHandoff::OnCall(ICallFrame* aFrame)
return hr;
}
} else {
SavedCallFrame savedFrame(WrapNotNull(aFrame));
// (7) Scan the outputs looking for any outparam interfaces that need wrapping.
// NB: WalkFrame does not correctly handle array outparams. It processes the
// first element of an array but not the remaining elements (if any).
@ -566,9 +615,26 @@ MainThreadHandoff::OnWalkInterface(REFIID aIid, PVOID* aInterface,
}
}
IID effectiveIid = aIid;
RefPtr<IHandlerProvider> payload;
if (mHandlerProvider) {
hr = mHandlerProvider->NewInstance(aIid,
if (aIid == IID_IUnknown) {
const SavedCallFrame& curFrame = SavedCallFrame::Get();
IID callIid;
ULONG callMethod;
hr = curFrame.GetIidAndMethod(WrapNotNull(&callIid),
WrapNotNull(&callMethod));
if (FAILED(hr)) {
return hr;
}
effectiveIid = mHandlerProvider->GetEffectiveOutParamIid(callIid,
callMethod);
}
hr = mHandlerProvider->NewInstance(effectiveIid,
ToInterceptorTargetPtr(origInterface),
WrapNotNull((IHandlerProvider**)getter_AddRefs(payload)));
MOZ_ASSERT(SUCCEEDED(hr));
@ -585,7 +651,8 @@ MainThreadHandoff::OnWalkInterface(REFIID aIid, PVOID* aInterface,
return hr;
}
REFIID interceptorIid = payload ? payload->MarshalAs(aIid) : aIid;
REFIID interceptorIid = payload ? payload->MarshalAs(effectiveIid) :
effectiveIid;
RefPtr<IUnknown> wrapped;
hr = Interceptor::Create(Move(origInterface), handoff, interceptorIid,

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

@ -2504,7 +2504,7 @@ BytecodeEmitter::emitCall(JSOp op, uint16_t argc, ParseNode* pn)
{
if (pn && !updateSourceCoordNotes(pn->pn_pos.begin))
return false;
return emit3(op, ARGC_HI(argc), ARGC_LO(argc));
return emit3(op, ARGC_LO(argc), ARGC_HI(argc));
}
bool
@ -2687,7 +2687,7 @@ bool
BytecodeEmitter::emitUint16Operand(JSOp op, uint32_t operand)
{
MOZ_ASSERT(operand <= UINT16_MAX);
if (!emit3(op, UINT16_HI(operand), UINT16_LO(operand)))
if (!emit3(op, UINT16_LO(operand), UINT16_HI(operand)))
return false;
checkTypeSet(op);
return true;
@ -10214,10 +10214,7 @@ BytecodeEmitter::replaceNewInitWithNewObject(JSObject* obj, ptrdiff_t offset)
MOZ_ASSERT(code[0] == JSOP_NEWINIT);
code[0] = JSOP_NEWOBJECT;
code[1] = jsbytecode(index >> 24);
code[2] = jsbytecode(index >> 16);
code[3] = jsbytecode(index >> 8);
code[4] = jsbytecode(index);
SET_UINT32(code, index);
return true;
}

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

@ -40,6 +40,7 @@ class AutoRunParallelTask;
class AutoTraceSession;
class MarkingValidator;
struct MovingTracer;
class SweepGroupsIter;
class WeakCacheSweepIterator;
enum IncrementalProgress
@ -1073,27 +1074,24 @@ class GCRuntime
void groupZonesForSweeping(JS::gcreason::Reason reason, AutoLockForExclusiveAccess& lock);
MOZ_MUST_USE bool findInterZoneEdges();
void getNextSweepGroup();
void endMarkingSweepGroup();
void beginSweepingSweepGroup();
IncrementalProgress endMarkingSweepGroup(FreeOp* fop, SliceBudget& budget);
IncrementalProgress beginSweepingSweepGroup(FreeOp* fop, SliceBudget& budget);
#ifdef JS_GC_ZEAL
IncrementalProgress maybeYieldForSweepingZeal(FreeOp* fop, SliceBudget& budget);
#endif
bool shouldReleaseObservedTypes();
void sweepDebuggerOnMainThread(FreeOp* fop);
void sweepJitDataOnMainThread(FreeOp* fop);
void endSweepingSweepGroup();
IncrementalProgress performSweepActions(SliceBudget& sliceBudget,
AutoLockForExclusiveAccess& lock);
static IncrementalProgress sweepTypeInformation(GCRuntime* gc, FreeOp* fop, SliceBudget& budget,
Zone* zone);
static IncrementalProgress mergeSweptObjectArenas(GCRuntime* gc, FreeOp* fop, SliceBudget& budget,
Zone* zone);
static IncrementalProgress sweepAtomsTable(GCRuntime* gc, FreeOp* fop, SliceBudget& budget);
IncrementalProgress endSweepingSweepGroup(FreeOp* fop, SliceBudget& budget);
IncrementalProgress performSweepActions(SliceBudget& sliceBudget, AutoLockForExclusiveAccess& lock);
IncrementalProgress sweepTypeInformation(FreeOp* fop, SliceBudget& budget, Zone* zone);
IncrementalProgress mergeSweptObjectArenas(FreeOp* fop, SliceBudget& budget, Zone* zone);
void startSweepingAtomsTable();
IncrementalProgress sweepAtomsTable(SliceBudget& budget);
static IncrementalProgress sweepWeakCaches(GCRuntime* gc, FreeOp* fop, SliceBudget& budget);
IncrementalProgress sweepWeakCaches(SliceBudget& budget);
static IncrementalProgress finalizeAllocKind(GCRuntime* gc, FreeOp* fop, SliceBudget& budget,
Zone* zone, AllocKind kind);
static IncrementalProgress sweepShapeTree(GCRuntime* gc, FreeOp* fop, SliceBudget& budget,
Zone* zone);
IncrementalProgress sweepAtomsTable(FreeOp* fop, SliceBudget& budget);
IncrementalProgress sweepWeakCaches(FreeOp* fop, SliceBudget& budget);
IncrementalProgress finalizeAllocKind(FreeOp* fop, SliceBudget& budget, Zone* zone,
AllocKind kind);
IncrementalProgress sweepShapeTree(FreeOp* fop, SliceBudget& budget, Zone* zone);
void endSweepPhase(bool lastGC, AutoLockForExclusiveAccess& lock);
bool allCCVisibleZonesWereCollected() const;
void sweepZones(FreeOp* fop, ZoneGroup* group, bool lastGC);
@ -1285,9 +1283,20 @@ class GCRuntime
*/
ActiveThreadOrGCTaskData<State> incrementalState;
/* The incremental state at the start of this slice. */
ActiveThreadData<State> initialState;
#ifdef JS_GC_ZEAL
/* Whether to pay attention the zeal settings in this incremental slice. */
ActiveThreadData<bool> useZeal;
#endif
/* Indicates that the last incremental slice exhausted the mark stack. */
ActiveThreadData<bool> lastMarkSlice;
/* Whether it's currently safe to yield to the mutator in an incremental GC. */
ActiveThreadData<bool> safeToYield;
/* Whether any sweeping will take place in the separate GC helper thread. */
ActiveThreadData<bool> sweepOnBackgroundThread;
@ -1319,6 +1328,7 @@ class GCRuntime
ActiveThreadOrGCTaskData<JS::detail::WeakCacheBase*> sweepCache;
ActiveThreadData<bool> abortSweepAfterCurrentGroup;
friend class SweepGroupsIter;
friend class WeakCacheSweepIterator;
/*

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

@ -2494,7 +2494,7 @@ GCMarker::enterWeakMarkingMode()
if (weakMapAction() == ExpandWeakMaps) {
tag_ = TracerKindTag::WeakMarking;
for (GCSweepGroupIter zone(runtime()); !zone.done(); zone.next()) {
for (SweepGroupZonesIter zone(runtime()); !zone.done(); zone.next()) {
for (WeakMapBase* m : zone->gcWeakMapList()) {
if (m->marked)
(void) m->markIteratively(this);

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

@ -3568,6 +3568,19 @@ Simulator::branchDelayInstructionDecode(SimInstruction* instr)
instructionDecode(instr);
}
static void
FakeInterruptHandler()
{
JSContext* cx = TlsContext.get();
uint8_t* pc = cx->simulator()->get_pc_as<uint8_t*>();
const wasm::CodeSegment* cs = nullptr;
if (!wasm::InInterruptibleCode(cx, pc, &cs))
return;
cx->simulator()->trigger_wasm_interrupt();
}
template<bool enableStopSimAt>
void
Simulator::execute()
@ -3581,6 +3594,8 @@ Simulator::execute()
MipsDebugger dbg(this);
dbg.debug();
} else {
if (MOZ_UNLIKELY(JitOptions.simulatorAlwaysInterrupt))
FakeInterruptHandler();
SimInstruction* instr = reinterpret_cast<SimInstruction*>(program_counter);
instructionDecode(instr);
icount_++;

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

@ -3733,6 +3733,19 @@ Simulator::disable_single_stepping()
single_step_callback_arg_ = nullptr;
}
static void
FakeInterruptHandler()
{
JSContext* cx = TlsContext.get();
uint8_t* pc = cx->simulator()->get_pc_as<uint8_t*>();
const wasm::CodeSegment* cs = nullptr;
if (!wasm::InInterruptibleCode(cx, pc, &cs))
return;
cx->simulator()->trigger_wasm_interrupt();
}
template<bool enableStopSimAt>
void
Simulator::execute()
@ -3751,6 +3764,8 @@ Simulator::execute()
} else {
if (single_stepping_)
single_step_callback_(single_step_callback_arg_, this, (void*)program_counter);
if (MOZ_UNLIKELY(JitOptions.simulatorAlwaysInterrupt))
FakeInterruptHandler();
SimInstruction* instr = reinterpret_cast<SimInstruction *>(program_counter);
instructionDecode(instr);
icount_++;

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

@ -465,6 +465,7 @@ class AutoLeaveZeal
JS::GCForReason(cx_, GC_SHRINK, JS::gcreason::DEBUG_GC);
}
~AutoLeaveZeal() {
JS_SetGCZeal(cx_, 0, 0);
for (size_t i = 0; i < sizeof(zealBits_) * 8; i++) {
if (zealBits_ & (1 << i))
JS_SetGCZeal(cx_, i, frequency_);

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

@ -914,7 +914,12 @@ GCRuntime::GCRuntime(JSRuntime* rt) :
number(0),
isFull(false),
incrementalState(gc::State::NotActive),
initialState(gc::State::NotActive),
#ifdef JS_GC_ZEAL
useZeal(false),
#endif
lastMarkSlice(false),
safeToYield(true),
sweepOnBackgroundThread(false),
blocksToFreeAfterSweeping((size_t) JSContext::TEMP_LIFO_ALLOC_PRIMARY_CHUNK_SIZE),
sweepGroupIndex(0),
@ -4389,7 +4394,7 @@ GCRuntime::markWeakReferences(gcstats::PhaseKind phase)
void
GCRuntime::markWeakReferencesInCurrentGroup(gcstats::PhaseKind phase)
{
markWeakReferences<GCSweepGroupIter>(phase);
markWeakReferences<SweepGroupZonesIter>(phase);
}
template <class ZoneIterT, class CompartmentIterT>
@ -4412,7 +4417,7 @@ GCRuntime::markGrayReferences(gcstats::PhaseKind phase)
void
GCRuntime::markGrayReferencesInCurrentGroup(gcstats::PhaseKind phase)
{
markGrayReferences<GCSweepGroupIter, GCCompartmentGroupIter>(phase);
markGrayReferences<SweepGroupZonesIter, SweepGroupCompartmentsIter>(phase);
}
void
@ -4907,14 +4912,14 @@ GCRuntime::getNextSweepGroup()
if (abortSweepAfterCurrentGroup) {
MOZ_ASSERT(!isIncremental);
for (GCSweepGroupIter zone(rt); !zone.done(); zone.next()) {
for (SweepGroupZonesIter zone(rt); !zone.done(); zone.next()) {
MOZ_ASSERT(!zone->gcNextGraphComponent);
zone->setNeedsIncrementalBarrier(false);
zone->changeGCState(Zone::Mark, Zone::NoGC);
zone->gcGrayRoots().clearAndFree();
}
for (GCCompartmentGroupIter comp(rt); !comp.done(); comp.next())
for (SweepGroupCompartmentsIter comp(rt); !comp.done(); comp.next())
ResetGrayList(comp);
abortSweepAfterCurrentGroup = false;
@ -5049,7 +5054,7 @@ MarkIncomingCrossCompartmentPointers(JSRuntime* rt, MarkColor color)
bool unlinkList = color == MarkColor::Gray;
for (GCCompartmentGroupIter c(rt); !c.done(); c.next()) {
for (SweepGroupCompartmentsIter c(rt); !c.done(); c.next()) {
MOZ_ASSERT_IF(color == MarkColor::Gray, c->zone()->isGCMarkingGray());
MOZ_ASSERT_IF(color == MarkColor::Black, c->zone()->isGCMarkingBlack());
MOZ_ASSERT_IF(c->gcIncomingGrayPointers, IsGrayListObject(c->gcIncomingGrayPointers));
@ -5162,8 +5167,8 @@ js::NotifyGCPostSwap(JSObject* a, JSObject* b, unsigned removedFlags)
DelayCrossCompartmentGrayMarking(a);
}
void
GCRuntime::endMarkingSweepGroup()
IncrementalProgress
GCRuntime::endMarkingSweepGroup(FreeOp* fop, SliceBudget& budget)
{
gcstats::AutoPhase ap(stats(), gcstats::PhaseKind::SWEEP_MARK);
@ -5181,7 +5186,7 @@ GCRuntime::endMarkingSweepGroup()
* these will be marked through, as they are not marked with
* MarkCrossCompartmentXXX.
*/
for (GCSweepGroupIter zone(rt); !zone.done(); zone.next())
for (SweepGroupZonesIter zone(rt); !zone.done(); zone.next())
zone->changeGCState(Zone::Mark, Zone::MarkGray);
marker.setMarkColorGray();
@ -5193,10 +5198,15 @@ GCRuntime::endMarkingSweepGroup()
markWeakReferencesInCurrentGroup(gcstats::PhaseKind::SWEEP_MARK_GRAY_WEAK);
/* Restore marking state. */
for (GCSweepGroupIter zone(rt); !zone.done(); zone.next())
for (SweepGroupZonesIter zone(rt); !zone.done(); zone.next())
zone->changeGCState(Zone::MarkGray, Zone::Mark);
MOZ_ASSERT(marker.isDrained());
marker.setMarkColorBlack();
/* We must not yield after this point before we start sweeping the group. */
safeToYield = false;
return Finished;
}
// Causes the given WeakCache to be swept when run.
@ -5245,28 +5255,28 @@ UpdateAtomsBitmap(JSRuntime* runtime)
static void
SweepCCWrappers(JSRuntime* runtime)
{
for (GCCompartmentGroupIter c(runtime); !c.done(); c.next())
for (SweepGroupCompartmentsIter c(runtime); !c.done(); c.next())
c->sweepCrossCompartmentWrappers();
}
static void
SweepObjectGroups(JSRuntime* runtime)
{
for (GCCompartmentGroupIter c(runtime); !c.done(); c.next())
for (SweepGroupCompartmentsIter c(runtime); !c.done(); c.next())
c->objectGroups.sweep(runtime->defaultFreeOp());
}
static void
SweepRegExps(JSRuntime* runtime)
{
for (GCCompartmentGroupIter c(runtime); !c.done(); c.next())
for (SweepGroupCompartmentsIter c(runtime); !c.done(); c.next())
c->sweepRegExps();
}
static void
SweepMisc(JSRuntime* runtime)
{
for (GCCompartmentGroupIter c(runtime); !c.done(); c.next()) {
for (SweepGroupCompartmentsIter c(runtime); !c.done(); c.next()) {
c->sweepGlobalObject();
c->sweepTemplateObjects();
c->sweepSavedStacks();
@ -5303,7 +5313,7 @@ SweepCompressionTasks(JSRuntime* runtime)
static void
SweepWeakMaps(JSRuntime* runtime)
{
for (GCSweepGroupIter zone(runtime); !zone.done(); zone.next()) {
for (SweepGroupZonesIter zone(runtime); !zone.done(); zone.next()) {
/* Clear all weakrefs that point to unmarked things. */
for (auto edge : zone->gcWeakRefs()) {
/* Edges may be present multiple times, so may already be nulled. */
@ -5325,7 +5335,7 @@ static void
SweepUniqueIds(JSRuntime* runtime)
{
FreeOp fop(nullptr);
for (GCSweepGroupIter zone(runtime); !zone.done(); zone.next())
for (SweepGroupZonesIter zone(runtime); !zone.done(); zone.next())
zone->sweepUniqueIds(&fop);
}
@ -5363,7 +5373,7 @@ GCRuntime::sweepDebuggerOnMainThread(FreeOp* fop)
// table.
{
gcstats::AutoPhase ap2(stats(), gcstats::PhaseKind::SWEEP_MISC);
for (GCCompartmentGroupIter c(rt); !c.done(); c.next())
for (SweepGroupCompartmentsIter c(rt); !c.done(); c.next())
c->sweepDebugEnvironments();
}
@ -5371,7 +5381,7 @@ GCRuntime::sweepDebuggerOnMainThread(FreeOp* fop)
// although note that it can cause JIT code to be patched.
{
gcstats::AutoPhase ap(stats(), gcstats::PhaseKind::SWEEP_BREAKPOINT);
for (GCSweepGroupIter zone(rt); !zone.done(); zone.next())
for (SweepGroupZonesIter zone(rt); !zone.done(); zone.next())
zone->sweepBreakpoints(fop);
}
}
@ -5385,10 +5395,10 @@ GCRuntime::sweepJitDataOnMainThread(FreeOp* fop)
// Cancel any active or pending off thread compilations.
js::CancelOffThreadIonCompile(rt, JS::Zone::Sweep);
for (GCCompartmentGroupIter c(rt); !c.done(); c.next())
for (SweepGroupCompartmentsIter c(rt); !c.done(); c.next())
c->sweepJitCompartment(fop);
for (GCSweepGroupIter zone(rt); !zone.done(); zone.next()) {
for (SweepGroupZonesIter zone(rt); !zone.done(); zone.next()) {
if (jit::JitZone* jitZone = zone->jitZone())
jitZone->sweep(fop);
}
@ -5403,14 +5413,14 @@ GCRuntime::sweepJitDataOnMainThread(FreeOp* fop)
{
gcstats::AutoPhase apdc(stats(), gcstats::PhaseKind::SWEEP_DISCARD_CODE);
for (GCSweepGroupIter zone(rt); !zone.done(); zone.next())
for (SweepGroupZonesIter zone(rt); !zone.done(); zone.next())
zone->discardJitCode(fop);
}
{
gcstats::AutoPhase ap1(stats(), gcstats::PhaseKind::SWEEP_TYPES);
gcstats::AutoPhase ap2(stats(), gcstats::PhaseKind::SWEEP_TYPES_BEGIN);
for (GCSweepGroupIter zone(rt); !zone.done(); zone.next())
for (SweepGroupZonesIter zone(rt); !zone.done(); zone.next())
zone->beginSweepTypes(fop, releaseObservedTypes && !zone->isPreservingCode());
}
}
@ -5429,7 +5439,7 @@ template <typename Functor>
static inline bool
IterateWeakCaches(JSRuntime* rt, Functor f)
{
for (GCSweepGroupIter zone(rt); !zone.done(); zone.next()) {
for (SweepGroupZonesIter zone(rt); !zone.done(); zone.next()) {
for (JS::detail::WeakCacheBase* cache : zone->weakCaches()) {
if (!f(cache, ZoneWeakCache))
return false;
@ -5484,8 +5494,8 @@ SweepWeakCachesOnMainThread(JSRuntime* rt)
});
}
void
GCRuntime::beginSweepingSweepGroup()
IncrementalProgress
GCRuntime::beginSweepingSweepGroup(FreeOp* fop, SliceBudget& budget)
{
/*
* Begin sweeping the group of zones in currentSweepGroup, performing
@ -5497,7 +5507,7 @@ GCRuntime::beginSweepingSweepGroup()
AutoSCC scc(stats(), sweepGroupIndex);
bool sweepingAtoms = false;
for (GCSweepGroupIter zone(rt); !zone.done(); zone.next()) {
for (SweepGroupZonesIter zone(rt); !zone.done(); zone.next()) {
/* Set the GC state to sweeping. */
zone->changeGCState(Zone::Mark, Zone::Sweep);
@ -5514,26 +5524,24 @@ GCRuntime::beginSweepingSweepGroup()
validateIncrementalMarking();
FreeOp fop(rt);
{
AutoPhase ap(stats(), PhaseKind::FINALIZE_START);
callFinalizeCallbacks(&fop, JSFINALIZE_GROUP_PREPARE);
callFinalizeCallbacks(fop, JSFINALIZE_GROUP_PREPARE);
{
AutoPhase ap2(stats(), PhaseKind::WEAK_ZONES_CALLBACK);
callWeakPointerZonesCallbacks();
}
{
AutoPhase ap2(stats(), PhaseKind::WEAK_COMPARTMENT_CALLBACK);
for (GCSweepGroupIter zone(rt); !zone.done(); zone.next()) {
for (SweepGroupZonesIter zone(rt); !zone.done(); zone.next()) {
for (CompartmentsInZoneIter comp(zone); !comp.done(); comp.next())
callWeakPointerCompartmentCallbacks(comp);
}
}
callFinalizeCallbacks(&fop, JSFINALIZE_GROUP_START);
callFinalizeCallbacks(fop, JSFINALIZE_GROUP_START);
}
sweepDebuggerOnMainThread(&fop);
sweepDebuggerOnMainThread(fop);
{
AutoLockHelperThreadState lock;
@ -5561,7 +5569,7 @@ GCRuntime::beginSweepingSweepGroup()
{
AutoUnlockHelperThreadState unlock(lock);
sweepJitDataOnMainThread(&fop);
sweepJitDataOnMainThread(fop);
}
for (auto& task : sweepCacheTasks)
@ -5574,25 +5582,45 @@ GCRuntime::beginSweepingSweepGroup()
// Queue all GC things in all zones for sweeping, either on the foreground
// or on the background thread.
for (GCSweepGroupIter zone(rt); !zone.done(); zone.next()) {
for (SweepGroupZonesIter zone(rt); !zone.done(); zone.next()) {
zone->arenas.queueForForegroundSweep(&fop, ForegroundObjectFinalizePhase);
zone->arenas.queueForForegroundSweep(&fop, ForegroundNonObjectFinalizePhase);
zone->arenas.queueForForegroundSweep(fop, ForegroundObjectFinalizePhase);
zone->arenas.queueForForegroundSweep(fop, ForegroundNonObjectFinalizePhase);
for (unsigned i = 0; i < ArrayLength(BackgroundFinalizePhases); ++i)
zone->arenas.queueForBackgroundSweep(&fop, BackgroundFinalizePhases[i]);
zone->arenas.queueForBackgroundSweep(fop, BackgroundFinalizePhases[i]);
zone->arenas.queueForegroundThingsForSweep(&fop);
zone->arenas.queueForegroundThingsForSweep(fop);
}
sweepCache = nullptr;
sweepActions->assertFinished();
safeToYield = true;
return Finished;
}
void
GCRuntime::endSweepingSweepGroup()
#ifdef JS_GC_ZEAL
IncrementalProgress
GCRuntime::maybeYieldForSweepingZeal(FreeOp* fop, SliceBudget& budget)
{
sweepActions->assertFinished();
/*
* Check whether we need to yield for GC zeal. We always yield when running
* in incremental multi-slice zeal mode so RunDebugGC can reset the slice
* budget.
*/
if (isIncremental && useZeal && initialState != State::Sweep &&
(hasZealMode(ZealMode::IncrementalMultipleSlices) ||
hasZealMode(ZealMode::IncrementalSweepThenFinish)))
{
return NotFinished;
}
return Finished;
}
#endif
IncrementalProgress
GCRuntime::endSweepingSweepGroup(FreeOp* fop, SliceBudget& budget)
{
{
gcstats::AutoPhase ap(stats(), gcstats::PhaseKind::FINALIZE_END);
FreeOp fop(rt);
@ -5600,7 +5628,7 @@ GCRuntime::endSweepingSweepGroup()
}
/* Update the GC state for zones we have swept. */
for (GCSweepGroupIter zone(rt); !zone.done(); zone.next()) {
for (SweepGroupZonesIter zone(rt); !zone.done(); zone.next()) {
AutoLockGC lock(rt);
zone->changeGCState(Zone::Sweep, Zone::Finished);
zone->threshold.updateAfterGC(zone->usage.gcBytes(), invocationKind, tunables,
@ -5609,7 +5637,7 @@ GCRuntime::endSweepingSweepGroup()
/* Start background thread to sweep zones if required. */
ZoneList zones;
for (GCSweepGroupIter zone(rt); !zone.done(); zone.next())
for (SweepGroupZonesIter zone(rt); !zone.done(); zone.next())
zones.append(zone);
if (sweepOnBackgroundThread)
queueZonesForBackgroundSweep(zones);
@ -5621,6 +5649,8 @@ GCRuntime::endSweepingSweepGroup()
arenasAllocatedDuringSweep = arena->getNextAllocDuringSweep();
arena->unsetAllocDuringSweep();
}
return Finished;
}
void
@ -5653,8 +5683,12 @@ GCRuntime::beginSweepPhase(JS::gcreason::Reason reason, AutoLockForExclusiveAcce
DropStringWrappers(rt);
groupZonesForSweeping(reason, lock);
endMarkingSweepGroup();
beginSweepingSweepGroup();
sweepActions->assertFinished();
// We must not yield after this point until we start sweeping the first sweep
// group.
safeToYield = false;
}
bool
@ -5737,8 +5771,8 @@ SweepArenaList(Arena** arenasToSweep, SliceBudget& sliceBudget, Args... args)
return true;
}
/* static */ IncrementalProgress
GCRuntime::sweepTypeInformation(GCRuntime* gc, FreeOp* fop, SliceBudget& budget, Zone* zone)
IncrementalProgress
GCRuntime::sweepTypeInformation(FreeOp* fop, SliceBudget& budget, Zone* zone)
{
// Sweep dead type information stored in scripts and object groups, but
// don't finalize them yet. We have to sweep dead information from both live
@ -5748,8 +5782,8 @@ GCRuntime::sweepTypeInformation(GCRuntime* gc, FreeOp* fop, SliceBudget& budget,
// the sweep group finishes we won't be able to determine which things in
// the zone are live.
gcstats::AutoPhase ap1(gc->stats(), gcstats::PhaseKind::SWEEP_COMPARTMENTS);
gcstats::AutoPhase ap2(gc->stats(), gcstats::PhaseKind::SWEEP_TYPES);
gcstats::AutoPhase ap1(stats(), gcstats::PhaseKind::SWEEP_COMPARTMENTS);
gcstats::AutoPhase ap2(stats(), gcstats::PhaseKind::SWEEP_TYPES);
ArenaLists& al = zone->arenas;
@ -5763,15 +5797,16 @@ GCRuntime::sweepTypeInformation(GCRuntime* gc, FreeOp* fop, SliceBudget& budget,
// Finish sweeping type information in the zone.
{
gcstats::AutoPhase ap(gc->stats(), gcstats::PhaseKind::SWEEP_TYPES_END);
zone->types.endSweep(gc->rt);
gcstats::AutoPhase ap(stats(), gcstats::PhaseKind::SWEEP_TYPES_END);
zone->types.endSweep(rt);
}
return Finished;
}
/* static */ IncrementalProgress
GCRuntime::mergeSweptObjectArenas(GCRuntime* gc, FreeOp* fop, SliceBudget& budget, Zone* zone)
IncrementalProgress
GCRuntime::mergeSweptObjectArenas(FreeOp* fop, SliceBudget& budget,
Zone* zone)
{
// Foreground finalized objects have already been finalized, and now their
// arenas can be reclaimed by freeing empty ones and making non-empty ones
@ -5802,18 +5837,12 @@ GCRuntime::startSweepingAtomsTable()
maybeAtoms.emplace(*atomsTable);
}
/* static */ IncrementalProgress
GCRuntime::sweepAtomsTable(GCRuntime* gc, FreeOp* fop, SliceBudget& budget)
IncrementalProgress
GCRuntime::sweepAtomsTable(FreeOp* fop, SliceBudget& budget)
{
if (!gc->atomsZone->isGCSweeping())
if (!atomsZone->isGCSweeping())
return Finished;
return gc->sweepAtomsTable(budget);
}
IncrementalProgress
GCRuntime::sweepAtomsTable(SliceBudget& budget)
{
gcstats::AutoPhase ap(stats(), gcstats::PhaseKind::SWEEP_ATOMS_TABLE);
auto& maybeAtoms = maybeAtomsToSweep.ref();
@ -5943,12 +5972,6 @@ class IncrementalSweepWeakCacheTask : public GCParallelTask
}
};
/* static */ IncrementalProgress
GCRuntime::sweepWeakCaches(GCRuntime* gc, FreeOp* fop, SliceBudget& budget)
{
return gc->sweepWeakCaches(budget);
}
static const size_t MaxWeakCacheSweepTasks = 8;
static size_t
@ -5959,7 +5982,7 @@ WeakCacheSweepTaskCount()
}
IncrementalProgress
GCRuntime::sweepWeakCaches(SliceBudget& budget)
GCRuntime::sweepWeakCaches(FreeOp* fop, SliceBudget& budget)
{
WeakCacheSweepIterator work(this);
@ -5978,13 +6001,12 @@ GCRuntime::sweepWeakCaches(SliceBudget& budget)
return work.empty(lock) ? Finished : NotFinished;
}
/* static */ IncrementalProgress
GCRuntime::finalizeAllocKind(GCRuntime* gc, FreeOp* fop, SliceBudget& budget, Zone* zone,
AllocKind kind)
IncrementalProgress
GCRuntime::finalizeAllocKind(FreeOp* fop, SliceBudget& budget, Zone* zone, AllocKind kind)
{
// Set the number of things per arena for this AllocKind.
size_t thingsPerArena = Arena::thingsPerArena(kind);
auto& sweepList = gc->incrementalSweepList.ref();
auto& sweepList = incrementalSweepList.ref();
sweepList.setThingsPerArena(thingsPerArena);
if (!zone->arenas.foregroundFinalize(fop, kind, budget, sweepList))
@ -5996,12 +6018,12 @@ GCRuntime::finalizeAllocKind(GCRuntime* gc, FreeOp* fop, SliceBudget& budget, Zo
return Finished;
}
/* static */ IncrementalProgress
GCRuntime::sweepShapeTree(GCRuntime* gc, FreeOp* fop, SliceBudget& budget, Zone* zone)
IncrementalProgress
GCRuntime::sweepShapeTree(FreeOp* fop, SliceBudget& budget, Zone* zone)
{
// Remove dead shapes from the shape tree, but don't finalize them yet.
gcstats::AutoPhase ap(gc->stats(), gcstats::PhaseKind::SWEEP_SHAPE);
gcstats::AutoPhase ap(stats(), gcstats::PhaseKind::SWEEP_SHAPE);
ArenaLists& al = zone->arenas;
@ -6084,20 +6106,46 @@ struct IncrementalIter
}
};
namespace sweepaction {
// Implementation of the SweepAction interface that calls a function.
template <typename... Args>
class SweepActionFunc final : public SweepAction<Args...>
// Iterate through the sweep groups created by GCRuntime::groupZonesForSweeping().
class js::gc::SweepGroupsIter
{
using Func = IncrementalProgress (*)(Args...);
Func func;
GCRuntime* gc;
public:
explicit SweepActionFunc(Func f) : func(f) {}
IncrementalProgress run(Args... args) override {
return func(args...);
explicit SweepGroupsIter(JSRuntime* rt)
: gc(&rt->gc)
{
MOZ_ASSERT(gc->currentSweepGroup);
}
bool done() const {
return !gc->currentSweepGroup;
}
Zone* get() const {
return gc->currentSweepGroup;
}
void next() {
MOZ_ASSERT(!done());
gc->getNextSweepGroup();
}
};
namespace sweepaction {
// Implementation of the SweepAction interface that calls a method on GCRuntime.
template <typename... Args>
class SweepActionCall final : public SweepAction<GCRuntime*, Args...>
{
using Method = IncrementalProgress (GCRuntime::*)(Args...);
Method method;
public:
explicit SweepActionCall(Method m) : method(m) {}
IncrementalProgress run(GCRuntime* gc, Args... args) override {
return (gc->*method)(args...);
}
void assertFinished() const override { }
};
@ -6168,6 +6216,36 @@ class SweepActionForEach final : public SweepAction<Args...>
}
};
template <typename Iter, typename Init, typename... Args>
class SweepActionRepeatFor final : public SweepAction<Args...>
{
protected:
using Action = SweepAction<Args...>;
using IncrIter = IncrementalIter<Iter>;
Init iterInit;
UniquePtr<Action> action;
typename IncrIter::State iterState;
public:
SweepActionRepeatFor(const Init& init, UniquePtr<Action> action)
: iterInit(init), action(Move(action))
{}
IncrementalProgress run(Args... args) override {
for (IncrIter iter(iterState, iterInit); !iter.done(); iter.next()) {
if (action->run(args...) == NotFinished)
return NotFinished;
}
return Finished;
}
void assertFinished() const override {
MOZ_ASSERT(iterState.isNothing());
action->assertFinished();
}
};
// Helper class to remove the last template parameter from the instantiation of
// a variadic template. For example:
//
@ -6206,9 +6284,9 @@ class RemoveLastTemplateParameter<Target<Args...>>
};
template <typename... Args>
static UniquePtr<SweepAction<Args...>>
Func(IncrementalProgress (*func)(Args...)) {
return MakeUnique<SweepActionFunc<Args...>>(func);
static UniquePtr<SweepAction<GCRuntime*, Args...>>
Call(IncrementalProgress (GCRuntime::*method)(Args...)) {
return MakeUnique<SweepActionCall<Args...>>(method);
}
template <typename... Args, typename... Rest>
@ -6223,6 +6301,17 @@ Sequence(UniquePtr<SweepAction<Args...>> first, Rest... rest)
return UniquePtr<SweepAction<Args...>>(Move(seq));
}
template <typename... Args>
static UniquePtr<SweepAction<Args...>>
RepeatForSweepGroup(JSRuntime* rt, UniquePtr<SweepAction<Args...>> action)
{
if (!action)
return nullptr;
using Action = SweepActionRepeatFor<SweepGroupsIter, JSRuntime*, Args...>;
return js::MakeUnique<Action>(rt, Move(action));
}
template <typename... Args>
static UniquePtr<typename RemoveLastTemplateParameter<SweepAction<Args...>>::Type>
ForEachZoneInSweepGroup(JSRuntime* rt, UniquePtr<SweepAction<Args...>> action)
@ -6231,7 +6320,7 @@ ForEachZoneInSweepGroup(JSRuntime* rt, UniquePtr<SweepAction<Args...>> action)
return nullptr;
using Action = typename RemoveLastTemplateParameter<
SweepActionForEach<GCSweepGroupIter, JSRuntime*, Args...>>::Type;
SweepActionForEach<SweepGroupZonesIter, JSRuntime*, Args...>>::Type;
return js::MakeUnique<Action>(rt, Move(action));
}
@ -6253,22 +6342,31 @@ bool
GCRuntime::initSweepActions()
{
using namespace sweepaction;
using sweepaction::Call;
sweepActions.ref() = Sequence(
Func(sweepAtomsTable),
Func(sweepWeakCaches),
sweepActions.ref() =
RepeatForSweepGroup(rt,
Sequence(
Call(&GCRuntime::endMarkingSweepGroup),
Call(&GCRuntime::beginSweepingSweepGroup),
#ifdef JS_GC_ZEAL
Call(&GCRuntime::maybeYieldForSweepingZeal),
#endif
Call(&GCRuntime::sweepAtomsTable),
Call(&GCRuntime::sweepWeakCaches),
ForEachZoneInSweepGroup(rt,
ForEachAllocKind(ForegroundObjectFinalizePhase.kinds,
Func(finalizeAllocKind))),
Call(&GCRuntime::finalizeAllocKind))),
ForEachZoneInSweepGroup(rt,
Sequence(
Func(sweepTypeInformation),
Func(mergeSweptObjectArenas))),
Call(&GCRuntime::sweepTypeInformation),
Call(&GCRuntime::mergeSweptObjectArenas))),
ForEachZoneInSweepGroup(rt,
ForEachAllocKind(ForegroundNonObjectFinalizePhase.kinds,
Func(finalizeAllocKind))),
Call(&GCRuntime::finalizeAllocKind))),
ForEachZoneInSweepGroup(rt,
Func(sweepShapeTree)));
Call(&GCRuntime::sweepShapeTree)),
Call(&GCRuntime::endSweepingSweepGroup)));
return sweepActions != nullptr;
}
@ -6281,21 +6379,17 @@ GCRuntime::performSweepActions(SliceBudget& budget, AutoLockForExclusiveAccess&
gcstats::AutoPhase ap(stats(), gcstats::PhaseKind::SWEEP);
FreeOp fop(rt);
// Drain the mark stack, except in the first sweep slice where we must not
// yield to the mutator until we've starting sweeping a sweep group.
MOZ_ASSERT(initialState <= State::Sweep);
if (initialState != State::Sweep) {
MOZ_ASSERT(marker.isDrained());
} else {
if (drainMarkStack(budget, gcstats::PhaseKind::SWEEP_MARK) == NotFinished)
return NotFinished;
for (;;) {
if (sweepActions->run(this, &fop, budget) == NotFinished)
return NotFinished;
endSweepingSweepGroup();
getNextSweepGroup();
if (!currentSweepGroup)
return Finished;
endMarkingSweepGroup();
beginSweepingSweepGroup();
}
return sweepActions->run(this, &fop, budget);
}
bool
@ -6331,6 +6425,8 @@ GCRuntime::allCCVisibleZonesWereCollected() const
void
GCRuntime::endSweepPhase(bool destroyingRuntime, AutoLockForExclusiveAccess& lock)
{
sweepActions->assertFinished();
AutoSetThreadIsSweeping threadIsSweeping;
gcstats::AutoPhase ap(stats(), gcstats::PhaseKind::SWEEP);
@ -6766,18 +6862,17 @@ GCRuntime::incrementalCollectSlice(SliceBudget& budget, JS::gcreason::Reason rea
bool destroyingRuntime = (reason == JS::gcreason::DESTROY_RUNTIME);
gc::State initialState = incrementalState;
initialState = incrementalState;
bool useZeal = false;
#ifdef JS_GC_ZEAL
if (reason == JS::gcreason::DEBUG_GC && !budget.isUnlimited()) {
/*
* Do the incremental collection type specified by zeal mode if the
* collection was triggered by runDebugGC() and incremental GC has not
* been cancelled by resetIncrementalGC().
* collection was triggered by runDebugGC() and incremental GC has not been
* cancelled by resetIncrementalGC().
*/
useZeal = true;
}
useZeal = reason == JS::gcreason::DEBUG_GC && !budget.isUnlimited();
#else
bool useZeal = false;
#endif
MOZ_ASSERT_IF(isIncrementalGCInProgress(), isIncremental);
@ -6860,24 +6955,7 @@ GCRuntime::incrementalCollectSlice(SliceBudget& budget, JS::gcreason::Reason rea
incrementalState = State::Sweep;
/*
* This runs to completion, but we don't continue if the budget is
* now exhasted.
*/
beginSweepPhase(reason, lock);
if (budget.isOverBudget())
break;
/*
* Always yield here when running in incremental multi-slice zeal
* mode, so RunDebugGC can reset the slice buget.
*/
if (isIncremental && useZeal &&
(hasZealMode(ZealMode::IncrementalMultipleSlices) ||
hasZealMode(ZealMode::IncrementalSweepThenFinish)))
{
break;
}
MOZ_FALLTHROUGH;
@ -6956,6 +7034,8 @@ GCRuntime::incrementalCollectSlice(SliceBudget& budget, JS::gcreason::Reason rea
incrementalState = State::NotActive;
break;
}
MOZ_ASSERT(safeToYield);
}
gc::AbortReason

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

@ -437,11 +437,11 @@ class GCZonesIter
typedef CompartmentsIterT<GCZonesIter> GCCompartmentsIter;
/* Iterates over all zones in the current sweep group. */
class GCSweepGroupIter {
class SweepGroupZonesIter {
JS::Zone* current;
public:
explicit GCSweepGroupIter(JSRuntime* rt) {
explicit SweepGroupZonesIter(JSRuntime* rt) {
MOZ_ASSERT(CurrentThreadIsPerformingGC());
current = rt->gc.getCurrentSweepGroup();
}
@ -462,7 +462,7 @@ class GCSweepGroupIter {
JS::Zone* operator->() const { return get(); }
};
typedef CompartmentsIterT<GCSweepGroupIter> GCCompartmentGroupIter;
typedef CompartmentsIterT<SweepGroupZonesIter> SweepGroupCompartmentsIter;
inline void
RelocationOverlay::forwardTo(Cell* cell)

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

@ -12,6 +12,7 @@
*/
#include "mozilla/Attributes.h"
#include "mozilla/EndianUtils.h"
#include "jsbytecode.h"
#include "jstypes.h"
@ -136,17 +137,26 @@ UINT16_LO(uint16_t i)
static MOZ_ALWAYS_INLINE uint16_t
GET_UINT16(const jsbytecode* pc)
{
return uint16_t((pc[1] << 8) | pc[2]);
#if MOZ_LITTLE_ENDIAN
uint16_t result;
memcpy(&result, pc + 1, sizeof(result));
return result;
#else
return uint16_t((pc[2] << 8) | pc[1]);
#endif
}
static MOZ_ALWAYS_INLINE void
SET_UINT16(jsbytecode* pc, uint16_t i)
{
pc[1] = UINT16_HI(i);
pc[2] = UINT16_LO(i);
#if MOZ_LITTLE_ENDIAN
memcpy(pc + 1, &i, sizeof(i));
#else
pc[1] = UINT16_LO(i);
pc[2] = UINT16_HI(i);
#endif
}
static const unsigned UINT16_LEN = 2;
static const unsigned UINT16_LIMIT = 1 << 16;
/* Helpers for accessing the offsets of jump opcodes. */
@ -154,69 +164,32 @@ static const unsigned JUMP_OFFSET_LEN = 4;
static const int32_t JUMP_OFFSET_MIN = INT32_MIN;
static const int32_t JUMP_OFFSET_MAX = INT32_MAX;
static MOZ_ALWAYS_INLINE int32_t
GET_JUMP_OFFSET(jsbytecode* pc)
{
return (pc[1] << 24) | (pc[2] << 16) | (pc[3] << 8) | pc[4];
}
static MOZ_ALWAYS_INLINE void
SET_JUMP_OFFSET(jsbytecode* pc, int32_t off)
{
pc[1] = jsbytecode(off >> 24);
pc[2] = jsbytecode(off >> 16);
pc[3] = jsbytecode(off >> 8);
pc[4] = jsbytecode(off);
}
static const unsigned UINT32_INDEX_LEN = 4;
static MOZ_ALWAYS_INLINE uint32_t
GET_UINT32_INDEX(const jsbytecode* pc)
{
return (pc[1] << 24) | (pc[2] << 16) | (pc[3] << 8) | pc[4];
}
static MOZ_ALWAYS_INLINE void
SET_UINT32_INDEX(jsbytecode* pc, uint32_t index)
{
pc[1] = jsbytecode(index >> 24);
pc[2] = jsbytecode(index >> 16);
pc[3] = jsbytecode(index >> 8);
pc[4] = jsbytecode(index);
}
static inline jsbytecode
UINT24_HI(unsigned i)
{
return jsbytecode(i >> 16);
}
static inline jsbytecode
UINT24_MID(unsigned i)
{
return jsbytecode(i >> 8);
}
static inline jsbytecode
UINT24_LO(unsigned i)
{
return jsbytecode(i);
}
static MOZ_ALWAYS_INLINE unsigned
GET_UINT24(const jsbytecode* pc)
{
return unsigned((pc[1] << 16) | (pc[2] << 8) | pc[3]);
#if MOZ_LITTLE_ENDIAN
// Do a single 32-bit load (for opcode and operand), then shift off the
// opcode.
uint32_t result;
memcpy(&result, pc, 4);
return result >> 8;
#else
return unsigned((pc[3] << 16) | (pc[2] << 8) | pc[1]);
#endif
}
static MOZ_ALWAYS_INLINE void
SET_UINT24(jsbytecode* pc, unsigned i)
SET_UINT24(jsbytecode* pc, uint32_t i)
{
MOZ_ASSERT(i < (1 << 24));
pc[1] = UINT24_HI(i);
pc[2] = UINT24_MID(i);
pc[3] = UINT24_LO(i);
#if MOZ_LITTLE_ENDIAN
memcpy(pc + 1, &i, 3);
#else
pc[1] = jsbytecode(i);
pc[2] = jsbytecode(i >> 8);
pc[3] = jsbytecode(i >> 16);
#endif
}
static MOZ_ALWAYS_INLINE int8_t
@ -228,19 +201,29 @@ GET_INT8(const jsbytecode* pc)
static MOZ_ALWAYS_INLINE uint32_t
GET_UINT32(const jsbytecode* pc)
{
return (uint32_t(pc[1]) << 24) |
(uint32_t(pc[2]) << 16) |
(uint32_t(pc[3]) << 8) |
uint32_t(pc[4]);
#if MOZ_LITTLE_ENDIAN
uint32_t result;
memcpy(&result, pc + 1, sizeof(result));
return result;
#else
return (uint32_t(pc[4]) << 24) |
(uint32_t(pc[3]) << 16) |
(uint32_t(pc[2]) << 8) |
uint32_t(pc[1]);
#endif
}
static MOZ_ALWAYS_INLINE void
SET_UINT32(jsbytecode* pc, uint32_t u)
{
pc[1] = jsbytecode(u >> 24);
pc[2] = jsbytecode(u >> 16);
pc[3] = jsbytecode(u >> 8);
pc[4] = jsbytecode(u);
#if MOZ_LITTLE_ENDIAN
memcpy(pc + 1, &u, sizeof(u));
#else
pc[1] = jsbytecode(u);
pc[2] = jsbytecode(u >> 8);
pc[3] = jsbytecode(u >> 16);
pc[4] = jsbytecode(u >> 24);
#endif
}
static MOZ_ALWAYS_INLINE int32_t
@ -255,6 +238,32 @@ SET_INT32(jsbytecode* pc, int32_t i)
SET_UINT32(pc, static_cast<uint32_t>(i));
}
static MOZ_ALWAYS_INLINE int32_t
GET_JUMP_OFFSET(jsbytecode* pc)
{
return GET_INT32(pc);
}
static MOZ_ALWAYS_INLINE void
SET_JUMP_OFFSET(jsbytecode* pc, int32_t off)
{
SET_INT32(pc, off);
}
static const unsigned UINT32_INDEX_LEN = 4;
static MOZ_ALWAYS_INLINE uint32_t
GET_UINT32_INDEX(const jsbytecode* pc)
{
return GET_UINT32(pc);
}
static MOZ_ALWAYS_INLINE void
SET_UINT32_INDEX(jsbytecode* pc, uint32_t index)
{
SET_UINT32(pc, index);
}
/* Index limit is determined by SN_4BYTE_OFFSET_FLAG, see frontend/BytecodeEmitter.h. */
static const unsigned INDEX_LIMIT_LOG2 = 31;
static const uint32_t INDEX_LIMIT = uint32_t(1) << INDEX_LIMIT_LOG2;

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

@ -10,6 +10,7 @@
#include "mozilla/Alignment.h"
#include "mozilla/Maybe.h"
#include "mozilla/Move.h"
#include "mozilla/OperatorNewExtensions.h"
#include "threading/ConditionVariable.h"
#include "threading/Mutex.h"
@ -99,7 +100,7 @@ class ExclusiveData
explicit ExclusiveData(const MutexId& id, U&& u)
: lock_(id)
{
new (value_.addr()) T(mozilla::Forward<U>(u));
new (mozilla::KnownNotNull, value_.addr()) T(mozilla::Forward<U>(u));
}
/**
@ -109,7 +110,7 @@ class ExclusiveData
explicit ExclusiveData(const MutexId& id, Args&&... args)
: lock_(id)
{
new (value_.addr()) T(mozilla::Forward<Args>(args)...);
new (mozilla::KnownNotNull, value_.addr()) T(mozilla::Forward<Args>(args)...);
}
~ExclusiveData() {
@ -122,12 +123,12 @@ class ExclusiveData
lock_(mozilla::Move(rhs.lock))
{
MOZ_ASSERT(&rhs != this, "self-move disallowed!");
new (value_.addr()) T(mozilla::Move(*rhs.value_.addr()));
new (mozilla::KnownNotNull, value_.addr()) T(mozilla::Move(*rhs.value_.addr()));
}
ExclusiveData& operator=(ExclusiveData&& rhs) {
this->~ExclusiveData();
new (this) ExclusiveData(mozilla::Move(rhs));
new (mozilla::KnownNotNull, this) ExclusiveData(mozilla::Move(rhs));
return *this;
}

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

@ -265,7 +265,7 @@ class ElementSpecific
}
// Inhibit unaligned accesses on ARM (bug 1097253, a compiler bug).
#ifdef __arm__
#if defined(__arm__) && defined(__GNUC__) && !defined(__clang__)
# define JS_VOLATILE_ARM volatile
#else
# define JS_VOLATILE_ARM

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

@ -246,6 +246,7 @@ static const unsigned PushedFP = 5;
static const unsigned SetFP = 8;
static const unsigned PoppedFP = 4;
static const unsigned PoppedExitReason = 2;
static const unsigned PoppedTLSReg = 0;
#elif defined(JS_CODEGEN_X86)
static const unsigned PushedRetAddr = 0;
static const unsigned PushedTLS = 1;
@ -254,6 +255,7 @@ static const unsigned PushedFP = 4;
static const unsigned SetFP = 6;
static const unsigned PoppedFP = 2;
static const unsigned PoppedExitReason = 1;
static const unsigned PoppedTLSReg = 0;
#elif defined(JS_CODEGEN_ARM)
static const unsigned BeforePushRetAddr = 0;
static const unsigned PushedRetAddr = 4;
@ -263,6 +265,7 @@ static const unsigned PushedFP = 20;
static const unsigned SetFP = 24;
static const unsigned PoppedFP = 8;
static const unsigned PoppedExitReason = 4;
static const unsigned PoppedTLSReg = 0;
#elif defined(JS_CODEGEN_ARM64)
static const unsigned BeforePushRetAddr = 0;
static const unsigned PushedRetAddr = 0;
@ -272,6 +275,7 @@ static const unsigned PushedFP = 0;
static const unsigned SetFP = 0;
static const unsigned PoppedFP = 0;
static const unsigned PoppedExitReason = 0;
static const unsigned PoppedTLSReg = 0;
#elif defined(JS_CODEGEN_MIPS32) || defined(JS_CODEGEN_MIPS64)
static const unsigned BeforePushRetAddr = 0;
static const unsigned PushedRetAddr = 8;
@ -279,8 +283,9 @@ static const unsigned PushedTLS = 16;
static const unsigned PushedExitReason = 28;
static const unsigned PushedFP = 36;
static const unsigned SetFP = 40;
static const unsigned PoppedFP = 16;
static const unsigned PoppedExitReason = 8;
static const unsigned PoppedFP = 24;
static const unsigned PoppedExitReason = 16;
static const unsigned PoppedTLSReg = 8;
#elif defined(JS_CODEGEN_NONE)
static const unsigned PushedRetAddr = 0;
static const unsigned PushedTLS = 1;
@ -289,6 +294,7 @@ static const unsigned PushedFP = 0;
static const unsigned SetFP = 0;
static const unsigned PoppedFP = 0;
static const unsigned PoppedExitReason = 0;
static const unsigned PoppedTLSReg = 0;
#else
# error "Unknown architecture!"
#endif
@ -448,11 +454,20 @@ GenerateCallableEpilogue(MacroAssembler& masm, unsigned framePushed, ExitReason
DebugOnly<uint32_t> poppedExitReason = masm.currentOffset();
masm.pop(WasmTlsReg);
DebugOnly<uint32_t> poppedTlsReg = masm.currentOffset();
#if defined(JS_CODEGEN_MIPS32) || defined(JS_CODEGEN_MIPS64)
masm.pop(ra);
*ret = masm.currentOffset();
masm.branch(ra);
#else
*ret = masm.currentOffset();
masm.ret();
#endif
MOZ_ASSERT_IF(!masm.oom(), PoppedFP == *ret - poppedFP);
MOZ_ASSERT_IF(!masm.oom(), PoppedExitReason == *ret - poppedExitReason);
MOZ_ASSERT_IF(!masm.oom(), PoppedTLSReg == *ret - poppedTlsReg);
}
void
@ -734,7 +749,21 @@ js::wasm::StartUnwinding(const JitActivation& activation, const RegisterState& r
case CodeRange::BuiltinThunk:
case CodeRange::TrapExit:
case CodeRange::DebugTrap:
#if defined(JS_CODEGEN_ARM) || defined(JS_CODEGEN_ARM64) || defined(JS_CODEGEN_MIPS32) || defined(JS_CODEGEN_MIPS64)
#if defined(JS_CODEGEN_MIPS32) || defined(JS_CODEGEN_MIPS64)
if ((offsetFromEntry >= BeforePushRetAddr && offsetFromEntry < PushedFP) || codeRange->isThunk()) {
// See BUG 1407986.
// On MIPS push is emulated by two instructions: adjusting the sp
// and storing the value to sp.
// Execution might be interrupted in between the two operation so we
// have to relay on register state instead of state saved on stack
// until the wasm::Frame is completely built.
// On entry the return address is in ra (registers.lr) and
// fp holds the caller's fp.
fixedPC = (uint8_t*) registers.lr;
fixedFP = fp;
AssertMatchesCallSite(activation, fixedPC, fixedFP);
} else
#elif defined(JS_CODEGEN_ARM) || defined(JS_CODEGEN_ARM64)
if (offsetFromEntry == BeforePushRetAddr || codeRange->isThunk()) {
// The return address is still in lr and fp holds the caller's fp.
fixedPC = (uint8_t*) registers.lr;
@ -766,24 +795,45 @@ js::wasm::StartUnwinding(const JitActivation& activation, const RegisterState& r
fixedPC = reinterpret_cast<Frame*>(sp)->returnAddress;
fixedFP = fp;
AssertMatchesCallSite(activation, fixedPC, fixedFP);
} else if (offsetInCode == codeRange->ret() - PoppedFP) {
} else if (offsetInCode >= codeRange->ret() - PoppedFP &&
offsetInCode < codeRange->ret() - PoppedExitReason)
{
// The fixedFP field of the Frame has been popped into fp, but the
// exit reason hasn't been popped yet.
fixedPC = sp[2];
fixedFP = fp;
AssertMatchesCallSite(activation, fixedPC, fixedFP);
} else if (offsetInCode == codeRange->ret() - PoppedExitReason) {
} else if (offsetInCode >= codeRange->ret() - PoppedExitReason &&
offsetInCode < codeRange->ret() - PoppedTLSReg)
{
// The fixedFP field of the Frame has been popped into fp, and the
// exit reason has been popped.
fixedPC = sp[1];
fixedFP = fp;
AssertMatchesCallSite(activation, fixedPC, fixedFP);
#if defined(JS_CODEGEN_MIPS32) || defined(JS_CODEGEN_MIPS64)
} else if (offsetInCode >= codeRange->ret() - PoppedTLSReg &&
offsetInCode < codeRange->ret())
{
// The fixedFP field of the Frame has been popped into fp, but the
// exit reason hasn't been popped yet.
fixedPC = sp[0];
fixedFP = fp;
AssertMatchesCallSite(activation, fixedPC, fixedFP);
} else if (offsetInCode == codeRange->ret()) {
// Both the TLS, fixedFP and ra have been popped and fp now
// points to the caller's frame.
fixedPC = (uint8_t*) registers.lr;;
fixedFP = fp;
AssertMatchesCallSite(activation, fixedPC, fixedFP);
#else
} else if (offsetInCode == codeRange->ret()) {
// Both the TLS and fixedFP fields have been popped and fp now
// points to the caller's frame.
fixedPC = sp[0];
fixedFP = fp;
AssertMatchesCallSite(activation, fixedPC, fixedFP);
#endif
} else {
if (codeRange->kind() == CodeRange::ImportJitExit) {
// The jit exit contains a range where the value of FP can't be

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

@ -173,6 +173,7 @@ class AutoSetHandlingSegFault
# define EPC_sig(p) ((p)->uc_mcontext.pc)
# define RFP_sig(p) ((p)->uc_mcontext.gregs[30])
# define RSP_sig(p) ((p)->uc_mcontext.gregs[29])
# define R31_sig(p) ((p)->uc_mcontext.gregs[31])
# endif
#elif defined(__NetBSD__)
# define XMM_sig(p,i) (((struct fxsave64*)(p)->uc_mcontext.__fpregs)->fx_xmm[i])
@ -418,6 +419,7 @@ struct macos_arm_context {
# define PC_sig(p) EPC_sig(p)
# define FP_sig(p) RFP_sig(p)
# define SP_sig(p) RSP_sig(p)
# define LR_sig(p) R31_sig(p)
#endif
static uint8_t**
@ -447,7 +449,7 @@ ContextToSP(CONTEXT* context)
return reinterpret_cast<uint8_t*>(SP_sig(context));
}
# if defined(__arm__) || defined(__aarch64__)
# if defined(__arm__) || defined(__aarch64__) || defined(__mips__)
static uint8_t*
ContextToLR(CONTEXT* context)
{
@ -538,7 +540,7 @@ ToRegisterState(CONTEXT* context)
state.fp = ContextToFP(context);
state.pc = *ContextToPC(context);
state.sp = ContextToSP(context);
# if defined(__arm__) || defined(__aarch64__)
# if defined(__arm__) || defined(__aarch64__) || defined(__mips__)
state.lr = ContextToLR(context);
# endif
return state;

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

@ -1404,7 +1404,7 @@ Loader::LoadSheet(SheetLoadData* aLoadData,
// This will call back into OnStreamComplete
// and thence to ParseSheet. Regardless of whether this fails,
// SheetComplete has been called.
return nsSyncLoadService::PushSyncStreamToListener(stream,
return nsSyncLoadService::PushSyncStreamToListener(stream.forget(),
streamLoader,
channel);
}

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

@ -26,7 +26,7 @@ void CSFLogV(CSFLogLevel priority, const char* sourceFile, int sourceLine, const
vprintf(format, args);
#else
mozilla::LogLevel level = static_cast<mozilla::LogLevel>(priority);
mozilla::LogLevel level = static_cast<mozilla::LogLevel>(static_cast<unsigned int>(priority));
// Skip doing any of this work if we're not logging the indicated level...
if (!MOZ_LOG_TEST(gSignalingLog, level)) {
@ -82,6 +82,6 @@ void CSFLog( CSFLogLevel priority, const char* sourceFile, int sourceLine, const
int CSFLogTestLevel(CSFLogLevel priority)
{
mozilla::LogLevel level = static_cast<mozilla::LogLevel>(priority);
return MOZ_LOG_TEST(gSignalingLog, level);
return MOZ_LOG_TEST(gSignalingLog,
static_cast<mozilla::LogLevel>(static_cast<unsigned int>(priority)));
}

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

@ -510,6 +510,9 @@ public class CustomTabsActivity extends AppCompatActivity
* Callback for Open-in menu item.
*/
private void onOpenInClicked() {
if (TextUtils.isEmpty(mCurrentUrl)) {
return;
}
final Intent intent = new Intent();
intent.setData(Uri.parse(mCurrentUrl));
intent.setAction(Intent.ACTION_VIEW);

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

@ -1216,7 +1216,7 @@ PREF_RegisterCallback(const char* aPrefNode,
NS_PRECONDITION(aPrefNode, "aPrefNode must not be nullptr");
NS_PRECONDITION(aCallback, "aCallback must not be nullptr");
auto node = new CallbackNode();
auto node = (CallbackNode*)moz_xmalloc(sizeof(CallbackNode));
node->mDomain = moz_xstrdup(aPrefNode);
node->mFunc = aCallback;
node->mData = aData;
@ -2975,7 +2975,7 @@ nsPrefBranch::GetChildList(const char* aStartingAt,
numPrefs = prefArray.Length();
if (numPrefs) {
outArray = new char*[numPrefs];
outArray = (char**)moz_xmalloc(numPrefs * sizeof(char*));
for (dwIndex = 0; dwIndex < numPrefs; ++dwIndex) {
// we need to lop off mPrefRoot in case the user is planning to pass this

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

@ -727,8 +727,9 @@ nsInputStreamPump::CreateBufferedStreamIfNeeded()
return NS_OK;
}
nsCOMPtr<nsIAsyncInputStream> stream = mAsyncStream;
nsresult rv = NS_NewBufferedInputStream(getter_AddRefs(mBufferedStream),
mAsyncStream, 4096);
stream.forget(), 4096);
NS_ENSURE_SUCCESS(rv, rv);
return NS_OK;

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

@ -1370,38 +1370,24 @@ NS_BufferOutputStream(nsIOutputStream *aOutputStream,
}
MOZ_MUST_USE nsresult
NS_NewBufferedInputStream(nsIInputStream **result,
nsIInputStream *str,
uint32_t bufferSize)
NS_NewBufferedInputStream(nsIInputStream** aResult,
already_AddRefed<nsIInputStream> aInputStream,
uint32_t aBufferSize)
{
nsCOMPtr<nsIInputStream> inputStream = Move(aInputStream);
nsresult rv;
nsCOMPtr<nsIBufferedInputStream> in =
do_CreateInstance(NS_BUFFEREDINPUTSTREAM_CONTRACTID, &rv);
if (NS_SUCCEEDED(rv)) {
rv = in->Init(str, bufferSize);
rv = in->Init(inputStream, aBufferSize);
if (NS_SUCCEEDED(rv)) {
in.forget(result);
in.forget(aResult);
}
}
return rv;
}
already_AddRefed<nsIInputStream>
NS_BufferInputStream(nsIInputStream *aInputStream,
uint32_t aBufferSize)
{
NS_ASSERTION(aInputStream, "No input stream given!");
nsCOMPtr<nsIInputStream> bis;
nsresult rv = NS_NewBufferedInputStream(getter_AddRefs(bis), aInputStream,
aBufferSize);
if (NS_SUCCEEDED(rv))
return bis.forget();
bis = aInputStream;
return bis.forget();
}
nsresult
NS_NewPostDataStream(nsIInputStream **result,
bool isFile,
@ -1418,7 +1404,8 @@ NS_NewPostDataStream(nsIInputStream **result,
rv = NS_NewLocalFileInputStream(getter_AddRefs(fileStream), file);
if (NS_SUCCEEDED(rv)) {
// wrap the file stream with a buffered input stream
rv = NS_NewBufferedInputStream(result, fileStream, 8192);
rv = NS_NewBufferedInputStream(result, fileStream.forget(),
8192);
}
}
return rv;

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

@ -511,9 +511,9 @@ nsresult NS_NewLocalFileStream(nsIFileStream **result,
int32_t behaviorFlags = 0);
MOZ_MUST_USE nsresult
NS_NewBufferedInputStream(nsIInputStream **result,
nsIInputStream *str,
uint32_t bufferSize);
NS_NewBufferedInputStream(nsIInputStream** aResult,
already_AddRefed<nsIInputStream> aInputStream,
uint32_t aBufferSize);
// note: the resulting stream can be QI'ed to nsISafeOutputStream iff the
// provided stream supports it.
@ -535,9 +535,6 @@ nsresult NS_NewBufferedOutputStream(nsIOutputStream **result,
already_AddRefed<nsIOutputStream>
NS_BufferOutputStream(nsIOutputStream *aOutputStream,
uint32_t aBufferSize);
already_AddRefed<nsIInputStream>
NS_BufferInputStream(nsIInputStream *aInputStream,
uint32_t aBufferSize);
// returns an input stream compatible with nsIUploadChannel::SetUploadStream()
nsresult NS_NewPostDataStream(nsIInputStream **result,

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

@ -929,7 +929,8 @@ HttpBaseChannel::EnsureUploadStreamIsCloneable(nsIRunnable* aCallback)
if (NS_InputStreamIsBuffered(mUploadStream)) {
source = mUploadStream;
} else {
rv = NS_NewBufferedInputStream(getter_AddRefs(source), mUploadStream, 4096);
rv = NS_NewBufferedInputStream(getter_AddRefs(source),
mUploadStream.forget(), 4096);
NS_ENSURE_SUCCESS(rv, rv);
}

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

@ -383,7 +383,8 @@ nsHttpTransaction::Init(uint32_t caps,
// that we write data in the largest chunks possible. this is actually
// necessary to workaround some common server bugs (see bug 137155).
nsCOMPtr<nsIInputStream> stream(do_QueryInterface(multi));
rv = NS_NewBufferedInputStream(getter_AddRefs(mRequestStream), stream,
rv = NS_NewBufferedInputStream(getter_AddRefs(mRequestStream),
stream.forget(),
nsIOService::gDefaultSegmentSize);
if (NS_FAILED(rv)) return rv;
} else {

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

@ -16,12 +16,12 @@
#include "nsEscape.h"
#include "nsIDirIndex.h"
#include "nsURLHelper.h"
#include "nsIPlatformCharset.h"
#include "nsIPrefService.h"
#include "nsIPrefBranch.h"
#include "nsIPrefLocalizedString.h"
#include "nsIStringBundle.h"
#include "nsITextToSubURI.h"
#include "nsNativeCharsetUtils.h"
#include "nsString.h"
#include <algorithm>
#include "nsIChannel.h"
@ -500,13 +500,10 @@ nsIndexedToHTML::DoOnStartRequest(nsIRequest* request, nsISupports *aContext,
// 1. file URL may be encoded in platform charset for backward compatibility
// 2. query part may not be encoded in UTF-8 (see bug 261929)
// so try the platform's default if this is file url
if (NS_FAILED(rv) && isSchemeFile) {
nsCOMPtr<nsIPlatformCharset> platformCharset(do_GetService(NS_PLATFORMCHARSET_CONTRACTID, &rv));
NS_ENSURE_SUCCESS(rv, rv);
if (NS_FAILED(rv) && isSchemeFile && !NS_IsNativeUTF8()) {
auto encoding = mozilla::dom::FallbackEncoding::FromLocale();
nsAutoCString charset;
rv = platformCharset->GetCharset(kPlatformCharsetSel_FileName, charset);
NS_ENSURE_SUCCESS(rv, rv);
encoding->Name(charset);
rv = mTextToSubURI->UnEscapeAndConvert(charset, titleUri, unEscapeSpec);
}
if (NS_FAILED(rv)) return rv;

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

@ -474,24 +474,25 @@ nsSAXXMLReader::ParseFromString(const nsAString &aStr,
}
NS_IMETHODIMP
nsSAXXMLReader::ParseFromStream(nsIInputStream *aStream,
nsSAXXMLReader::ParseFromStream(nsIInputStream *aStreamPtr,
const char *aCharset,
const char *aContentType)
{
// Don't call this in the middle of an async parse
NS_ENSURE_TRUE(!mIsAsyncParse, NS_ERROR_FAILURE);
NS_ENSURE_ARG(aStream);
NS_ENSURE_ARG(aStreamPtr);
NS_ENSURE_ARG(aContentType);
// Put the nsCOMPtr out here so we hold a ref to the stream as needed
nsresult rv;
nsCOMPtr<nsIInputStream> stream = aStreamPtr;
if (!NS_InputStreamIsBuffered(stream)) {
nsCOMPtr<nsIInputStream> bufferedStream;
if (!NS_InputStreamIsBuffered(aStream)) {
rv = NS_NewBufferedInputStream(getter_AddRefs(bufferedStream),
aStream, 4096);
stream.forget(), 4096);
NS_ENSURE_SUCCESS(rv, rv);
aStream = bufferedStream;
stream = bufferedStream;
}
rv = EnsureBaseURI();
@ -504,7 +505,7 @@ nsSAXXMLReader::ParseFromStream(nsIInputStream *aStream,
nsCOMPtr<nsIChannel> parserChannel;
rv = NS_NewInputStreamChannel(getter_AddRefs(parserChannel),
mBaseURI,
aStream,
stream,
nullPrincipal,
nsILoadInfo::SEC_REQUIRE_SAME_ORIGIN_DATA_IS_BLOCKED,
nsIContentPolicy::TYPE_OTHER,
@ -536,7 +537,7 @@ nsSAXXMLReader::ParseFromStream(nsIInputStream *aStream,
uint64_t offset = 0;
while (NS_SUCCEEDED(rv) && NS_SUCCEEDED(status)) {
uint64_t available;
rv = aStream->Available(&available);
rv = stream->Available(&available);
if (rv == NS_BASE_STREAM_CLOSED) {
rv = NS_OK;
available = 0;
@ -552,7 +553,7 @@ nsSAXXMLReader::ParseFromStream(nsIInputStream *aStream,
available = UINT32_MAX;
rv = mListener->OnDataAvailable(parserChannel, nullptr,
aStream,
stream,
offset,
(uint32_t)available);
if (NS_SUCCEEDED(rv))

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

@ -497,7 +497,7 @@ RDFXMLDataSourceImpl::BlockingParse(nsIURI* aURL, nsIStreamListener* aConsumer)
// Wrap the channel's input stream in a buffered stream to ensure that
// ReadSegments is implemented (which OnDataAvailable expects).
nsCOMPtr<nsIInputStream> bufStream;
rv = NS_NewBufferedInputStream(getter_AddRefs(bufStream), in,
rv = NS_NewBufferedInputStream(getter_AddRefs(bufStream), in.forget(),
4096 /* buffer size */);
if (NS_FAILED(rv)) return rv;

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

@ -1001,12 +1001,15 @@ this.BrowserTestUtils = {
* True if it is expected that the tab crashed page will be shown
* for this browser. If so, the Promise will only resolve once the
* tab crash page has loaded.
* @param (bool) shouldClearMinidumps
* True if the minidumps left behind by the crash should be removed.
*
* @returns (Promise)
* @resolves An Object with key-value pairs representing the data from the
* crash report's extra file (if applicable).
*/
async crashBrowser(browser, shouldShowTabCrashPage=true) {
async crashBrowser(browser, shouldShowTabCrashPage=true,
shouldClearMinidumps=true) {
let extra = {};
let KeyValueParser = {};
if (AppConstants.MOZ_CRASHREPORTER) {
@ -1107,8 +1110,10 @@ this.BrowserTestUtils = {
}
}
if (shouldClearMinidumps) {
removeFile(minidumpDirectory, dumpID + '.dmp');
removeFile(minidumpDirectory, dumpID + '.extra');
}
});
}

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

@ -638,8 +638,13 @@ TestRunner.testFinished = function(tests) {
}
SpecialPowers.executeAfterFlushingMessageQueue(function() {
SpecialPowers.waitForCrashes(TestRunner._expectingProcessCrash)
.then(() => {
cleanUpCrashDumpFiles();
SpecialPowers.flushPermissions(function () { SpecialPowers.flushPrefEnv(runNextTest); });
SpecialPowers.flushPermissions(function () {
SpecialPowers.flushPrefEnv(runNextTest);
});
});
});
};

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

@ -330,10 +330,23 @@ function expectedException(actual, expected) {
* 11. Expected to throw an error:
* assert.throws(block, Error_opt, message_opt);
*
* Example:
* ```js
* // The following will verify that an error of type TypeError was thrown:
* Assert.throws(() => testBody(), TypeError);
* // The following will verify that an error was thrown with an error message matching "hello":
* Assert.throws(() => testBody(), /hello/);
* // The following will verify that any error was thrown and will use "hello" in the test report:
* Assert.throws(() => testBody(), "hello");
* ```
*
* @param block
* (function) Function block to evaluate and catch eventual thrown errors
* @param expected (optional)
* (mixed) Test reference to evaluate against the thrown result from `block`
* (mixed) This parameter can be either a RegExp, a function, or a string. The
* function is either the error type's constructor, or it's a method that returns a boolean
* that describes the test outcome. When string value is provided, it will be used as if it
* was provided as the message parameter.
* @param message (optional)
* (string) Short explanation of the expected result
*/
@ -473,4 +486,3 @@ proto.less = function less(lhs, rhs, message) {
proto.lessOrEqual = function lessOrEqual(lhs, rhs, message) {
compareNumbers.call(this, lhs > rhs, lhs, rhs, message, "<=");
};

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

@ -70,6 +70,7 @@ SpecialPowersObserver.prototype._loadFrameScript = function() {
if (!this._isFrameScriptLoaded) {
// Register for any messages our API needs us to handle
this._messageManager.addMessageListener("SPPrefService", this);
this._messageManager.addMessageListener("SPProcessCrashManagerWait", this);
this._messageManager.addMessageListener("SPProcessCrashService", this);
this._messageManager.addMessageListener("SPPingService", this);
this._messageManager.addMessageListener("SpecialPowers.Quit", this);
@ -140,6 +141,7 @@ SpecialPowersObserver.prototype.uninit = function() {
if (this._isFrameScriptLoaded) {
this._messageManager.removeMessageListener("SPPrefService", this);
this._messageManager.removeMessageListener("SPProcessCrashManagerWait", this);
this._messageManager.removeMessageListener("SPProcessCrashService", this);
this._messageManager.removeMessageListener("SPPingService", this);
this._messageManager.removeMessageListener("SpecialPowers.Quit", this);

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

@ -117,6 +117,10 @@ SpecialPowersObserverAPI.prototype = {
}
}
} else { // ipc:content-shutdown
if (!aSubject.hasKey("abnormal")) {
return; // This is a normal shutdown, ignore it
}
addDumpIDToMessage("dumpID");
}
this._sendAsyncMessage("SPProcessCrashService", message);
@ -393,6 +397,17 @@ SpecialPowersObserverAPI.prototype = {
return undefined; // See comment at the beginning of this function.
}
case "SPProcessCrashManagerWait": {
let promises = aMessage.json.crashIds.map((crashId) => {
return Services.crashmanager.ensureCrashIsPresent(crashId);
});
Promise.all(promises).then(() => {
this._sendReply(aMessage, "SPProcessCrashManagerWait", {});
});
return undefined; // See comment at the beginning of this function.
}
case "SPPermissionManager": {
let msg = aMessage.json;
let principal = msg.principal;

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

@ -49,6 +49,7 @@ function SpecialPowers(window) {
"SpecialPowers.RemoveFiles",
"SPPingService",
"SPLoadExtension",
"SPProcessCrashManagerWait",
"SPStartupExtension",
"SPUnloadExtension",
"SPExtensionMessage"];

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

@ -670,6 +670,31 @@ SpecialPowersAPI.prototype = {
return bindDOMWindowUtils(aWindow);
},
waitForCrashes(aExpectingProcessCrash) {
return new Promise((resolve, reject) => {
if (!aExpectingProcessCrash) {
resolve();
}
var crashIds = this._encounteredCrashDumpFiles.filter((filename) => {
return ((filename.length === 40) && filename.endsWith(".dmp"));
}).map((id) => {
return id.slice(0, -4); // Strip the .dmp extension to get the ID
});
let self = this;
function messageListener(msg) {
self._removeMessageListener("SPProcessCrashManagerWait", messageListener);
resolve();
}
this._addMessageListener("SPProcessCrashManagerWait", messageListener);
this._sendAsyncMessage("SPProcessCrashManagerWait", {
crashIds
});
});
},
removeExpectedCrashDumpFiles(aExpectingProcessCrash) {
var success = true;
if (aExpectingProcessCrash) {

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

@ -6,7 +6,7 @@
#include <string>
#include "common/linux/file_id.h"
#include "common/memory.h"
#include "common/memory_allocator.h"
using std::string;

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

@ -1295,7 +1295,7 @@ FetchAndConvertUnsupportedPayloads::ConvertPayload(int64_t aId,
// Decode the input stream to a surface.
RefPtr<gfx::SourceSurface> surface =
image::ImageOps::DecodeToSurface(stream,
image::ImageOps::DecodeToSurface(stream.forget(),
aMimeType,
imgIContainer::DECODE_FLAGS_DEFAULT);
NS_ENSURE_STATE(surface);

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

@ -339,7 +339,9 @@ HashStore::Open()
}
mFileSize = static_cast<uint32_t>(fileSize);
mInputStream = NS_BufferInputStream(origStream, mFileSize);
rv = NS_NewBufferedInputStream(getter_AddRefs(mInputStream),
origStream.forget(), mFileSize);
NS_ENSURE_SUCCESS(rv, rv);
rv = ReadHeader();
NS_ENSURE_SUCCESS(rv, rv);

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

@ -239,7 +239,10 @@ VariableLengthPrefixSet::LoadFromFile(nsIFile* aFile)
MAX_BUFFER_SIZE);
// Convert to buffered stream
nsCOMPtr<nsIInputStream> in = NS_BufferInputStream(localInFile, bufferSize);
nsCOMPtr<nsIInputStream> in;
rv = NS_NewBufferedInputStream(getter_AddRefs(in), localInFile.forget(),
bufferSize);
NS_ENSURE_SUCCESS(rv, rv);
rv = mFixedPrefixSet->LoadPrefixes(in);
NS_ENSURE_SUCCESS(rv, rv);

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

@ -352,7 +352,10 @@ nsUrlClassifierPrefixSet::LoadFromFile(nsIFile* aFile)
MAX_BUFFER_SIZE);
// Convert to buffered stream
nsCOMPtr<nsIInputStream> in = NS_BufferInputStream(localInFile, bufferSize);
nsCOMPtr<nsIInputStream> in;
rv = NS_NewBufferedInputStream(getter_AddRefs(in), localInFile.forget(),
bufferSize);
NS_ENSURE_SUCCESS(rv, rv);
rv = LoadPrefixes(in);
NS_ENSURE_SUCCESS(rv, rv);

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

@ -34,7 +34,7 @@
#include <sys/user.h>
#include "linux/dump_writer_common/raw_context_cpu.h"
#include "common/memory.h"
#include "common/memory_allocator.h"
#include "google_breakpad/common/minidump_format.h"
namespace google_breakpad {

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

@ -34,7 +34,7 @@
#include <sys/user.h>
#include "linux/dump_writer_common/raw_context_cpu.h"
#include "common/memory.h"
#include "common/memory_allocator.h"
#include "google_breakpad/common/minidump_format.h"
namespace google_breakpad {

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

@ -89,7 +89,7 @@
#include "common/basictypes.h"
#include "common/linux/linux_libc_support.h"
#include "common/memory.h"
#include "common/memory_allocator.h"
#include "linux/log/log.h"
#include "linux/microdump_writer/microdump_writer.h"
#include "linux/minidump_writer/linux_dumper.h"

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