diff --git a/browser/modules/test/browser/contentSearch.js b/browser/modules/test/browser/contentSearch.js index be670233765b..569943590382 100644 --- a/browser/modules/test/browser/contentSearch.js +++ b/browser/modules/test/browser/contentSearch.js @@ -30,7 +30,7 @@ addMessageListener(TEST_MSG, msg => { content.dispatchEvent( new content.CustomEvent(CLIENT_EVENT_TYPE, { - detail: msg.data, + detail: Cu.cloneInto(msg.data, content), }) ); diff --git a/devtools/client/aboutdebugging-new/aboutdebugging.css b/devtools/client/aboutdebugging-new/aboutdebugging.css index ab303b95273d..268ad98598ad 100644 --- a/devtools/client/aboutdebugging-new/aboutdebugging.css +++ b/devtools/client/aboutdebugging-new/aboutdebugging.css @@ -4,12 +4,13 @@ @import "chrome://global/skin/in-content/common.css"; @import "resource://devtools/client/aboutdebugging-new/src/components/App.css"; +@import "resource://devtools/client/aboutdebugging-new/src/components/ConnectPage.css"; @import "resource://devtools/client/aboutdebugging-new/src/components/DebugTargetItem.css"; @import "resource://devtools/client/aboutdebugging-new/src/components/DebugTargetList.css"; -@import "resource://devtools/client/aboutdebugging-new/src/components/ConnectPage.css"; @import "resource://devtools/client/aboutdebugging-new/src/components/RuntimeInfo.css"; @import "resource://devtools/client/aboutdebugging-new/src/components/Sidebar.css"; @import "resource://devtools/client/aboutdebugging-new/src/components/SidebarItem.css"; +@import "resource://devtools/client/aboutdebugging-new/src/components/debugtarget/ExtensionDetail.css"; :root { /* Import css variables from common.css */ @@ -22,6 +23,11 @@ html, body { color: var(--text-color); } +dd { + margin: 0; + padding: 0; +} + ul { list-style: none; margin: 0; diff --git a/devtools/client/aboutdebugging-new/src/actions/runtime.js b/devtools/client/aboutdebugging-new/src/actions/runtime.js index 06532868192e..ef322e5ff0b8 100644 --- a/devtools/client/aboutdebugging-new/src/actions/runtime.js +++ b/devtools/client/aboutdebugging-new/src/actions/runtime.js @@ -4,6 +4,8 @@ "use strict"; +const { BrowserToolboxProcess } = + require("resource://devtools/client/framework/ToolboxProcess.jsm"); const { DebuggerClient } = require("devtools/shared/client/debugger-client"); const { DebuggerServer } = require("devtools/server/main"); @@ -15,11 +17,16 @@ const { DISCONNECT_RUNTIME_FAILURE, DISCONNECT_RUNTIME_START, DISCONNECT_RUNTIME_SUCCESS, + REQUEST_EXTENSIONS_FAILURE, + REQUEST_EXTENSIONS_START, + REQUEST_EXTENSIONS_SUCCESS, REQUEST_TABS_FAILURE, REQUEST_TABS_START, REQUEST_TABS_SUCCESS, } = require("../constants"); +let browserToolboxProcess = null; + function connectRuntime() { return async (dispatch, getState) => { dispatch({ type: CONNECT_RUNTIME_START }); @@ -32,6 +39,7 @@ function connectRuntime() { await client.connect(); dispatch({ type: CONNECT_RUNTIME_SUCCESS, client }); + dispatch(requestExtensions()); dispatch(requestTabs()); } catch (e) { dispatch({ type: CONNECT_RUNTIME_FAILURE, error: e.message }); @@ -59,6 +67,18 @@ function disconnectRuntime() { function inspectDebugTarget(type, id) { if (type === DEBUG_TARGETS.TAB) { window.open(`about:devtools-toolbox?type=tab&id=${ id }`); + } else if (type === DEBUG_TARGETS.EXTENSION) { + // Close previous addon debugging toolbox. + if (browserToolboxProcess) { + browserToolboxProcess.close(); + } + + browserToolboxProcess = BrowserToolboxProcess.init({ + addonID: id, + onClose: () => { + browserToolboxProcess = null; + } + }); } else { console.error(`Failed to inspect the debug target of type: ${ type } id: ${ id }`); } @@ -83,9 +103,33 @@ function requestTabs() { }; } +function requestExtensions() { + return async (dispatch, getState) => { + dispatch({ type: REQUEST_EXTENSIONS_START }); + + const client = getState().runtime.client; + + try { + const { addons } = await client.listAddons(); + const extensions = addons.filter(a => a.debuggable); + const installedExtensions = extensions.filter(e => !e.temporarilyInstalled); + const temporaryExtensions = extensions.filter(e => e.temporarilyInstalled); + + dispatch({ + type: REQUEST_EXTENSIONS_SUCCESS, + installedExtensions, + temporaryExtensions, + }); + } catch (e) { + dispatch({ type: REQUEST_EXTENSIONS_FAILURE, error: e.message }); + } + }; +} + module.exports = { connectRuntime, disconnectRuntime, inspectDebugTarget, requestTabs, + requestExtensions, }; diff --git a/devtools/client/aboutdebugging-new/src/components/DebugTargetItem.js b/devtools/client/aboutdebugging-new/src/components/DebugTargetItem.js index 1b7858851c50..af162cf81d7e 100644 --- a/devtools/client/aboutdebugging-new/src/components/DebugTargetItem.js +++ b/devtools/client/aboutdebugging-new/src/components/DebugTargetItem.js @@ -4,11 +4,15 @@ "use strict"; -const { PureComponent } = require("devtools/client/shared/vendor/react"); +const { createFactory, PureComponent } = require("devtools/client/shared/vendor/react"); const dom = require("devtools/client/shared/vendor/react-dom-factories"); const PropTypes = require("devtools/client/shared/vendor/react-prop-types"); +const ExtensionDetail = createFactory(require("./debugtarget/ExtensionDetail")); +const TabDetail = createFactory(require("./debugtarget/TabDetail")); + const Actions = require("../actions/index"); +const { DEBUG_TARGETS } = require("../constants"); /** * This component displays debug target. @@ -17,27 +21,39 @@ class DebugTargetItem extends PureComponent { static get propTypes() { return { dispatch: PropTypes.func.isRequired, - icon: PropTypes.string.isRequired, - id: PropTypes.string.isRequired, - name: PropTypes.string.isRequired, - type: PropTypes.string.isRequired, - url: PropTypes.string.isRequired, + target: PropTypes.object.isRequired, }; } inspect() { - const { dispatch, type, id } = this.props; - dispatch(Actions.inspectDebugTarget(type, id)); + const { dispatch, target } = this.props; + dispatch(Actions.inspectDebugTarget(target.type, target.id)); + } + + renderDetail() { + const { target } = this.props; + + switch (target.type) { + case DEBUG_TARGETS.EXTENSION: + return ExtensionDetail({ target }); + case DEBUG_TARGETS.TAB: + return TabDetail({ target }); + + default: + return null; + } } renderIcon() { return dom.img({ className: "debug-target-item__icon", - src: this.props.icon, + src: this.props.target.icon, }); } renderInfo() { + const { target } = this.props; + return dom.div( { className: "debug-target-item__info", @@ -45,16 +61,11 @@ class DebugTargetItem extends PureComponent { dom.div( { className: "debug-target-item__info__name ellipsis-text", - title: this.props.name, + title: target.name, }, - this.props.name - ), - dom.div( - { - className: "debug-target-item__info__url ellipsis-text", - }, - this.props.url + target.name ), + this.renderDetail(), ); } diff --git a/devtools/client/aboutdebugging-new/src/components/DebugTargetList.js b/devtools/client/aboutdebugging-new/src/components/DebugTargetList.js index 5b7bdd000f82..bda2d3e48c5c 100644 --- a/devtools/client/aboutdebugging-new/src/components/DebugTargetList.js +++ b/devtools/client/aboutdebugging-new/src/components/DebugTargetList.js @@ -17,7 +17,7 @@ class DebugTargetList extends PureComponent { static get propTypes() { return { dispatch: PropTypes.func.isRequired, - targets: PropTypes.arrayOf(PropTypes.Object).isRequired, + targets: PropTypes.arrayOf(PropTypes.object).isRequired, }; } @@ -28,16 +28,7 @@ class DebugTargetList extends PureComponent { { className: "debug-target-list", }, - targets.map(target => - DebugTargetItem({ - dispatch, - icon: target.icon, - id: target.id, - name: target.name, - type: target.type, - url: target.url, - }) - ), + targets.map(target => DebugTargetItem({ dispatch, target })), ); } } diff --git a/devtools/client/aboutdebugging-new/src/components/RuntimePage.js b/devtools/client/aboutdebugging-new/src/components/RuntimePage.js index 498f1ae2fd35..cfb5260dee50 100644 --- a/devtools/client/aboutdebugging-new/src/components/RuntimePage.js +++ b/devtools/client/aboutdebugging-new/src/components/RuntimePage.js @@ -18,12 +18,14 @@ class RuntimePage extends PureComponent { static get propTypes() { return { dispatch: PropTypes.func.isRequired, + installedExtensions: PropTypes.arrayOf(PropTypes.object).isRequired, tabs: PropTypes.arrayOf(PropTypes.object).isRequired, + temporaryExtensions: PropTypes.arrayOf(PropTypes.object).isRequired, }; } render() { - const { dispatch, tabs } = this.props; + const { dispatch, installedExtensions, tabs, temporaryExtensions } = this.props; return dom.article( { @@ -34,6 +36,16 @@ class RuntimePage extends PureComponent { name: Services.appinfo.name, version: Services.appinfo.version, }), + DebugTargetPane({ + dispatch, + name: "Temporary Extensions", + targets: temporaryExtensions, + }), + DebugTargetPane({ + dispatch, + name: "Extensions", + targets: installedExtensions, + }), DebugTargetPane({ dispatch, name: "Tabs", @@ -45,7 +57,9 @@ class RuntimePage extends PureComponent { const mapStateToProps = state => { return { + installedExtensions: state.runtime.installedExtensions, tabs: state.runtime.tabs, + temporaryExtensions: state.runtime.temporaryExtensions, }; }; diff --git a/devtools/client/aboutdebugging-new/src/components/debugtarget/ExtensionDetail.css b/devtools/client/aboutdebugging-new/src/components/debugtarget/ExtensionDetail.css new file mode 100644 index 000000000000..1f5abf43b293 --- /dev/null +++ b/devtools/client/aboutdebugging-new/src/components/debugtarget/ExtensionDetail.css @@ -0,0 +1,25 @@ +/* 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/. */ + +/* + * The current layout of extension detail is + * + * +----------------+--------------------+ + * | detail name dt | detail value dd | + * | (120px) | (auto) | + * +----------------+--------------------+ + * | detail name dt | detail value dd | + * +----------------+--------------------+ + * | detail name dt | detail value dd | + * +----------------+--------------------+ + */ +.extension-detail { + display: grid; + grid-template-columns: 120px auto; + margin-block-start: 4px; +} + +.extension-detail__manifest { + margin-inline-start: 1ch; +} diff --git a/devtools/client/aboutdebugging-new/src/components/debugtarget/ExtensionDetail.js b/devtools/client/aboutdebugging-new/src/components/debugtarget/ExtensionDetail.js new file mode 100644 index 000000000000..1efeaf912658 --- /dev/null +++ b/devtools/client/aboutdebugging-new/src/components/debugtarget/ExtensionDetail.js @@ -0,0 +1,68 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +"use strict"; + +const { PureComponent } = require("devtools/client/shared/vendor/react"); +const dom = require("devtools/client/shared/vendor/react-dom-factories"); +const PropTypes = require("devtools/client/shared/vendor/react-prop-types"); + +/** + * This component displays detail information for extension. + */ +class ExtensionDetail extends PureComponent { + static get propTypes() { + return { + target: PropTypes.object.isRequired, + }; + } + + renderField(name, value, title) { + return [ + dom.dt({}, name), + dom.dd( + { + className: "ellipsis-text", + title: title || value, + }, + value, + ), + ]; + } + + renderUUID() { + const { target } = this.props; + const { manifestURL, uuid } = target; + + const value = [ + uuid, + dom.a( + { + className: "extension-detail__manifest", + href: manifestURL, + target: "_blank", + }, + "Manifest URL", + ) + ]; + + return this.renderField("Internal UUID", value, uuid); + } + + render() { + const { target } = this.props; + const { id, location, uuid } = target; + + return dom.dl( + { + className: "extension-detail", + }, + location ? this.renderField("Location", location) : null, + this.renderField("Extension ID", id), + uuid ? this.renderUUID() : null, + ); + } +} + +module.exports = ExtensionDetail; diff --git a/devtools/client/aboutdebugging-new/src/components/debugtarget/TabDetail.js b/devtools/client/aboutdebugging-new/src/components/debugtarget/TabDetail.js new file mode 100644 index 000000000000..103fe7a80bba --- /dev/null +++ b/devtools/client/aboutdebugging-new/src/components/debugtarget/TabDetail.js @@ -0,0 +1,26 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +"use strict"; + +const { PureComponent } = require("devtools/client/shared/vendor/react"); +const dom = require("devtools/client/shared/vendor/react-dom-factories"); +const PropTypes = require("devtools/client/shared/vendor/react-prop-types"); + +/** + * This component displays detail information for tab. + */ +class TabDetail extends PureComponent { + static get propTypes() { + return { + target: PropTypes.object.isRequired, + }; + } + + render() { + return dom.div({ className: "ellipsis-text" }, this.props.target.url); + } +} + +module.exports = TabDetail; diff --git a/devtools/client/aboutdebugging-new/src/components/debugtarget/moz.build b/devtools/client/aboutdebugging-new/src/components/debugtarget/moz.build new file mode 100644 index 000000000000..606098392717 --- /dev/null +++ b/devtools/client/aboutdebugging-new/src/components/debugtarget/moz.build @@ -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/. + +DevToolsModules( + 'ExtensionDetail.css', + 'ExtensionDetail.js', + 'TabDetail.js', +) diff --git a/devtools/client/aboutdebugging-new/src/components/moz.build b/devtools/client/aboutdebugging-new/src/components/moz.build index f0ddc16d7d00..d43450465aaf 100644 --- a/devtools/client/aboutdebugging-new/src/components/moz.build +++ b/devtools/client/aboutdebugging-new/src/components/moz.build @@ -2,6 +2,10 @@ # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. +DIRS += [ + 'debugtarget', +] + DevToolsModules( 'App.css', 'App.js', diff --git a/devtools/client/aboutdebugging-new/src/constants.js b/devtools/client/aboutdebugging-new/src/constants.js index 29bb87f7974f..a7bf7dca2eae 100644 --- a/devtools/client/aboutdebugging-new/src/constants.js +++ b/devtools/client/aboutdebugging-new/src/constants.js @@ -11,6 +11,9 @@ const actionTypes = { DISCONNECT_RUNTIME_FAILURE: "DISCONNECT_RUNTIME_FAILURE", DISCONNECT_RUNTIME_START: "DISCONNECT_RUNTIME_START", DISCONNECT_RUNTIME_SUCCESS: "DISCONNECT_RUNTIME_SUCCESS", + REQUEST_EXTENSIONS_FAILURE: "REQUEST_EXTENSIONS_FAILURE", + REQUEST_EXTENSIONS_START: "REQUEST_EXTENSIONS_START", + REQUEST_EXTENSIONS_SUCCESS: "REQUEST_EXTENSIONS_SUCCESS", REQUEST_TABS_FAILURE: "REQUEST_TABS_FAILURE", REQUEST_TABS_START: "REQUEST_TABS_START", REQUEST_TABS_SUCCESS: "REQUEST_TABS_SUCCESS", @@ -18,6 +21,7 @@ const actionTypes = { }; const DEBUG_TARGETS = { + EXTENSION: "EXTENSION", TAB: "TAB", }; diff --git a/devtools/client/aboutdebugging-new/src/middleware/debug-target-listener.js b/devtools/client/aboutdebugging-new/src/middleware/debug-target-listener.js index 3874a0b33227..d04bad392504 100644 --- a/devtools/client/aboutdebugging-new/src/middleware/debug-target-listener.js +++ b/devtools/client/aboutdebugging-new/src/middleware/debug-target-listener.js @@ -4,6 +4,8 @@ "use strict"; +const { AddonManager } = require("resource://gre/modules/AddonManager.jsm"); + const { CONNECT_RUNTIME_SUCCESS, DISCONNECT_RUNTIME_START, @@ -11,18 +13,50 @@ const { const Actions = require("../actions/index"); function debugTargetListenerMiddleware(state) { + const onExtensionsUpdated = () => { + state.dispatch(Actions.requestExtensions()); + }; + const onTabsUpdated = () => { state.dispatch(Actions.requestTabs()); }; + const extensionsListener = { + onDisabled() { + onExtensionsUpdated(); + }, + + onEnabled() { + onExtensionsUpdated(); + }, + + onInstalled() { + onExtensionsUpdated(); + }, + + onOperationCancelled() { + onExtensionsUpdated(); + }, + + onUninstalled() { + onExtensionsUpdated(); + }, + + onUninstalling() { + onExtensionsUpdated(); + }, + }; + return next => action => { switch (action.type) { case CONNECT_RUNTIME_SUCCESS: { action.client.addListener("tabListChanged", onTabsUpdated); + AddonManager.addAddonListener(extensionsListener); break; } case DISCONNECT_RUNTIME_START: { state.getState().runtime.client.removeListener("tabListChanged", onTabsUpdated); + AddonManager.removeAddonListener(extensionsListener); break; } } diff --git a/devtools/client/aboutdebugging-new/src/reducers/runtime-state.js b/devtools/client/aboutdebugging-new/src/reducers/runtime-state.js index 0556ccc52e86..18ad79641c8e 100644 --- a/devtools/client/aboutdebugging-new/src/reducers/runtime-state.js +++ b/devtools/client/aboutdebugging-new/src/reducers/runtime-state.js @@ -8,13 +8,16 @@ const { CONNECT_RUNTIME_SUCCESS, DEBUG_TARGETS, DISCONNECT_RUNTIME_SUCCESS, + REQUEST_EXTENSIONS_SUCCESS, REQUEST_TABS_SUCCESS, } = require("../constants"); function RuntimeState() { return { client: null, + installedExtensions: [], tabs: [], + temporaryExtensions: [], }; } @@ -27,6 +30,13 @@ function runtimeReducer(state = RuntimeState(), action) { case DISCONNECT_RUNTIME_SUCCESS: { return RuntimeState(); } + case REQUEST_EXTENSIONS_SUCCESS: { + const { installedExtensions, temporaryExtensions } = action; + return Object.assign({}, state, { + installedExtensions: toExtensionComponentData(installedExtensions), + temporaryExtensions: toExtensionComponentData(temporaryExtensions), + }); + } case REQUEST_TABS_SUCCESS: { const { tabs } = action; return Object.assign({}, state, { tabs: toTabComponentData(tabs) }); @@ -37,6 +47,37 @@ function runtimeReducer(state = RuntimeState(), action) { } } +function getExtensionFilePath(extension) { + // Only show file system paths, and only for temporarily installed add-ons. + if (!extension.temporarilyInstalled || + !extension.url || + !extension.url.startsWith("file://")) { + return null; + } + + // Strip a leading slash from Windows drive letter URIs. + // file:///home/foo ~> /home/foo + // file:///C:/foo ~> C:/foo + const windowsRegex = /^file:\/\/\/([a-zA-Z]:\/.*)/; + + if (windowsRegex.test(extension.url)) { + return windowsRegex.exec(extension.url)[1]; + } + + return extension.url.slice("file://".length); +} + +function toExtensionComponentData(extensions) { + return extensions.map(extension => { + const type = DEBUG_TARGETS.EXTENSION; + const { iconURL, id, manifestURL, name } = extension; + const icon = iconURL || "chrome://mozapps/skin/extensions/extensionGeneric.svg"; + const location = getExtensionFilePath(extension); + const uuid = manifestURL ? /moz-extension:\/\/([^/]*)/.exec(manifestURL)[1] : null; + return { type, id, icon, location, manifestURL, name, uuid }; + }); +} + function toTabComponentData(tabs) { return tabs.map(tab => { const type = DEBUG_TARGETS.TAB; diff --git a/devtools/shared/heapsnapshot/HeapSnapshot.cpp b/devtools/shared/heapsnapshot/HeapSnapshot.cpp index 784820096f64..ee66df07fbbc 100644 --- a/devtools/shared/heapsnapshot/HeapSnapshot.cpp +++ b/devtools/shared/heapsnapshot/HeapSnapshot.cpp @@ -406,9 +406,6 @@ readSizeOfNextMessage(ZeroCopyInputStream& stream, uint32_t* sizep) bool HeapSnapshot::init(JSContext* cx, const uint8_t* buffer, uint32_t size) { - if (!nodes.init() || !frames.init()) - return false; - ArrayInputStream stream(buffer, size); GzipInputStream gzipStream(&stream); uint32_t sizeOfMessage = 0; @@ -439,8 +436,6 @@ HeapSnapshot::init(JSContext* cx, const uint8_t* buffer, uint32_t size) // The set of all node ids we've found edges pointing to. NodeIdSet edgeReferents(cx); - if (NS_WARN_IF(!edgeReferents.init())) - return false; if (NS_WARN_IF(!saveNode(root, edgeReferents))) return false; @@ -478,10 +473,6 @@ HeapSnapshot::TakeCensus(JSContext* cx, JS::HandleObject options, JS::MutableHandleValue rval, ErrorResult& rv) { JS::ubi::Census census(cx); - if (NS_WARN_IF(!census.init())) { - rv.Throw(NS_ERROR_OUT_OF_MEMORY); - return; - } JS::ubi::CountTypePtr rootType; if (NS_WARN_IF(!JS::ubi::ParseCensusOptions(cx, census, options, rootType))) { @@ -501,10 +492,6 @@ HeapSnapshot::TakeCensus(JSContext* cx, JS::HandleObject options, JS::AutoCheckCannotGC nogc; JS::ubi::CensusTraversal traversal(cx, handler, nogc); - if (NS_WARN_IF(!traversal.init())) { - rv.Throw(NS_ERROR_OUT_OF_MEMORY); - return; - } if (NS_WARN_IF(!traversal.addStart(getRoot()))) { rv.Throw(NS_ERROR_OUT_OF_MEMORY); @@ -610,10 +597,6 @@ HeapSnapshot::ComputeShortestPaths(JSContext*cx, uint64_t start, // snapshot. JS::ubi::NodeSet targetsSet; - if (NS_WARN_IF(!targetsSet.init())) { - rv.Throw(NS_ERROR_OUT_OF_MEMORY); - return; - } for (const auto& target : targets) { Maybe targetNode = getNodeById(target); @@ -722,9 +705,6 @@ HeapSnapshot::ComputeShortestPaths(JSContext*cx, uint64_t start, static bool PopulateCompartmentsWithGlobals(CompartmentSet& compartments, AutoObjectVector& globals) { - if (!compartments.init()) - return false; - unsigned length = globals.length(); for (unsigned i = 0; i < length; i++) { if (!compartments.put(GetObjectCompartment(globals[i]))) @@ -768,7 +748,7 @@ EstablishBoundaries(JSContext* cx, CompartmentSet& compartments) { MOZ_ASSERT(!roots.initialized()); - MOZ_ASSERT(!compartments.initialized()); + MOZ_ASSERT(compartments.empty()); bool foundBoundaryProperty = false; @@ -851,8 +831,6 @@ EstablishBoundaries(JSContext* cx, } MOZ_ASSERT(roots.initialized()); - MOZ_ASSERT_IF(boundaries.mDebugger.WasPassed(), compartments.initialized()); - MOZ_ASSERT_IF(boundaries.mGlobals.WasPassed(), compartments.initialized()); return true; } @@ -1257,12 +1235,6 @@ public: , compartments(compartments) { } - bool init() { - return framesAlreadySerialized.init() && - twoByteStringsAlreadySerialized.init() && - oneByteStringsAlreadySerialized.init(); - } - ~StreamWriter() override { } bool writeMetadata(uint64_t timestamp) final { @@ -1440,8 +1412,6 @@ WriteHeapGraph(JSContext* cx, HeapSnapshotHandler handler(writer, compartments); HeapSnapshotHandler::Traversal traversal(cx, handler, noGC); - if (!traversal.init()) - return false; traversal.wantNames = wantNames; bool ok = traversal.addStartVisited(node) && @@ -1621,11 +1591,7 @@ ChromeUtils::SaveHeapSnapshotShared(GlobalObject& global, return; StreamWriter writer(cx, gzipStream, wantNames, - compartments.initialized() ? &compartments : nullptr); - if (NS_WARN_IF(!writer.init())) { - rv.Throw(NS_ERROR_OUT_OF_MEMORY); - return; - } + !compartments.empty() ? &compartments : nullptr); MOZ_ASSERT(maybeNoGC.isSome()); ubi::Node roots(&rootList); @@ -1638,7 +1604,7 @@ ChromeUtils::SaveHeapSnapshotShared(GlobalObject& global, roots, writer, wantNames, - compartments.initialized() ? &compartments : nullptr, + !compartments.empty() ? &compartments : nullptr, maybeNoGC.ref(), nodeCount, edgeCount)) diff --git a/devtools/shared/heapsnapshot/HeapSnapshot.h b/devtools/shared/heapsnapshot/HeapSnapshot.h index 2dc0451ec34b..d045bfdfdf8b 100644 --- a/devtools/shared/heapsnapshot/HeapSnapshot.h +++ b/devtools/shared/heapsnapshot/HeapSnapshot.h @@ -137,7 +137,6 @@ public: // Get the root node of this heap snapshot's graph. JS::ubi::Node getRoot() { - MOZ_ASSERT(nodes.initialized()); auto p = nodes.lookup(rootId); MOZ_ASSERT(p); const DeserializedNode& node = *p; diff --git a/devtools/shared/heapsnapshot/tests/gtest/DoesCrossCompartmentBoundaries.cpp b/devtools/shared/heapsnapshot/tests/gtest/DoesCrossCompartmentBoundaries.cpp index a1d82a432fbe..a76ae84c2c2c 100644 --- a/devtools/shared/heapsnapshot/tests/gtest/DoesCrossCompartmentBoundaries.cpp +++ b/devtools/shared/heapsnapshot/tests/gtest/DoesCrossCompartmentBoundaries.cpp @@ -27,7 +27,6 @@ DEF_TEST(DoesCrossCompartmentBoundaries, { // Our set of target compartments is both the old and new compartments. JS::CompartmentSet targetCompartments; - ASSERT_TRUE(targetCompartments.init()); ASSERT_TRUE(targetCompartments.put(compartment)); ASSERT_TRUE(targetCompartments.put(newCompartment)); diff --git a/devtools/shared/heapsnapshot/tests/gtest/DoesntCrossCompartmentBoundaries.cpp b/devtools/shared/heapsnapshot/tests/gtest/DoesntCrossCompartmentBoundaries.cpp index 21c646d6f919..95c3f84766e0 100644 --- a/devtools/shared/heapsnapshot/tests/gtest/DoesntCrossCompartmentBoundaries.cpp +++ b/devtools/shared/heapsnapshot/tests/gtest/DoesntCrossCompartmentBoundaries.cpp @@ -28,7 +28,6 @@ DEF_TEST(DoesntCrossCompartmentBoundaries, { // Our set of target compartments is only the pre-existing compartment and // does not include the new compartment. JS::CompartmentSet targetCompartments; - ASSERT_TRUE(targetCompartments.init()); ASSERT_TRUE(targetCompartments.put(compartment)); FakeNode nodeA; diff --git a/dom/base/CustomElementRegistry.cpp b/dom/base/CustomElementRegistry.cpp index 560cd9fd5a43..54be5616a8d6 100644 --- a/dom/base/CustomElementRegistry.cpp +++ b/dom/base/CustomElementRegistry.cpp @@ -285,7 +285,6 @@ CustomElementRegistry::CustomElementRegistry(nsPIDOMWindowInner* aWindow) , mIsCustomDefinitionRunning(false) { MOZ_ASSERT(aWindow); - MOZ_ALWAYS_TRUE(mConstructors.init()); mozilla::HoldJSObjects(this); } diff --git a/dom/plugins/base/nsJSNPRuntime.cpp b/dom/plugins/base/nsJSNPRuntime.cpp index f0ac75cf58af..cea0d9fd8454 100644 --- a/dom/plugins/base/nsJSNPRuntime.cpp +++ b/dom/plugins/base/nsJSNPRuntime.cpp @@ -28,6 +28,7 @@ #include "js/TracingAPI.h" #include "js/Wrapper.h" #include "mozilla/HashFunctions.h" +#include "mozilla/UniquePtr.h" #include "mozilla/dom/ScriptSettings.h" #define NPRUNTIME_JSCLASS_NAME "NPObject JS wrapper class" @@ -85,7 +86,7 @@ typedef JS::GCHashMap JSObjWrapperTable; -static JSObjWrapperTable sJSObjWrappers; +static UniquePtr sJSObjWrappers; // Whether it's safe to iterate sJSObjWrappers. Set to true when sJSObjWrappers // has been initialized and is not currently being enumerated. @@ -294,8 +295,8 @@ OnWrapperDestroyed(); static void TraceJSObjWrappers(JSTracer *trc, void *data) { - if (sJSObjWrappers.initialized()) { - sJSObjWrappers.trace(trc); + if (sJSObjWrappers) { + sJSObjWrappers->trace(trc); } } @@ -361,17 +362,13 @@ static bool CreateJSObjWrapperTable() { MOZ_ASSERT(!sJSObjWrappersAccessible); - MOZ_ASSERT(!sJSObjWrappers.initialized()); + MOZ_ASSERT(!sJSObjWrappers); if (!RegisterGCCallbacks()) { return false; } - if (!sJSObjWrappers.init(16)) { - NS_ERROR("Error initializing PLDHashTable sJSObjWrappers!"); - return false; - } - + sJSObjWrappers = MakeUnique(); sJSObjWrappersAccessible = true; return true; } @@ -380,12 +377,11 @@ static void DestroyJSObjWrapperTable() { MOZ_ASSERT(sJSObjWrappersAccessible); - MOZ_ASSERT(sJSObjWrappers.initialized()); - MOZ_ASSERT(sJSObjWrappers.count() == 0); + MOZ_ASSERT(sJSObjWrappers); + MOZ_ASSERT(sJSObjWrappers->count() == 0); - // No more wrappers, and our hash was initialized. Finish the - // hash to prevent leaking it. - sJSObjWrappers.finish(); + // No more wrappers. Delete the table. + sJSObjWrappers = nullptr; sJSObjWrappersAccessible = false; } @@ -694,9 +690,9 @@ nsJSObjWrapper::NP_Invalidate(NPObject *npobj) if (sJSObjWrappersAccessible) { // Remove the wrapper from the hash nsJSObjWrapperKey key(jsnpobj->mJSObj, jsnpobj->mNpp); - JSObjWrapperTable::Ptr ptr = sJSObjWrappers.lookup(key); + JSObjWrapperTable::Ptr ptr = sJSObjWrappers->lookup(key); MOZ_ASSERT(ptr.found()); - sJSObjWrappers.remove(ptr); + sJSObjWrappers->remove(ptr); } // Forget our reference to the JSObject. @@ -1132,14 +1128,14 @@ nsJSObjWrapper::GetNewOrUsed(NPP npp, JS::Handle obj, return _retainobject(npobj); } - if (!sJSObjWrappers.initialized()) { + if (!sJSObjWrappers) { // No hash yet (or any more), initialize it. if (!CreateJSObjWrapperTable()) return nullptr; } MOZ_ASSERT(sJSObjWrappersAccessible); - JSObjWrapperTable::Ptr p = sJSObjWrappers.lookupForAdd(nsJSObjWrapperKey(obj, npp)); + JSObjWrapperTable::Ptr p = sJSObjWrappers->lookupForAdd(nsJSObjWrapperKey(obj, npp)); if (p) { MOZ_ASSERT(p->value()); // Found a live nsJSObjWrapper, return it. @@ -1162,7 +1158,7 @@ nsJSObjWrapper::GetNewOrUsed(NPP npp, JS::Handle obj, // Insert the new wrapper into the hashtable, rooting the JSObject. Its // lifetime is now tied to that of the NPObject. - if (!sJSObjWrappers.putNew(nsJSObjWrapperKey(obj, npp), wrapper)) { + if (!sJSObjWrappers->putNew(nsJSObjWrapperKey(obj, npp), wrapper)) { // Out of memory, free the wrapper we created. _releaseobject(wrapper); return nullptr; @@ -2032,7 +2028,7 @@ nsJSNPRuntime::OnPluginDestroy(NPP npp) // Prevent modification of sJSObjWrappers table if we go reentrant. sJSObjWrappersAccessible = false; - for (auto iter = sJSObjWrappers.modIter(); !iter.done(); iter.next()) { + for (auto iter = sJSObjWrappers->modIter(); !iter.done(); iter.next()) { nsJSObjWrapper* npobj = iter.get().value(); MOZ_ASSERT(npobj->_class == &nsJSObjWrapper::sJSObjWrapperNPClass); if (npobj->mNpp == npp) { @@ -2105,7 +2101,7 @@ nsJSNPRuntime::OnPluginDestroyPending(NPP npp) if (sJSObjWrappersAccessible) { // Prevent modification of sJSObjWrappers table if we go reentrant. sJSObjWrappersAccessible = false; - for (auto iter = sJSObjWrappers.iter(); !iter.done(); iter.next()) { + for (auto iter = sJSObjWrappers->iter(); !iter.done(); iter.next()) { nsJSObjWrapper* npobj = iter.get().value(); MOZ_ASSERT(npobj->_class == &nsJSObjWrapper::sJSObjWrapperNPClass); if (npobj->mNpp == npp) { diff --git a/js/ipc/JavaScriptChild.cpp b/js/ipc/JavaScriptChild.cpp index fecdcd060a1b..076c69827949 100644 --- a/js/ipc/JavaScriptChild.cpp +++ b/js/ipc/JavaScriptChild.cpp @@ -42,11 +42,6 @@ JavaScriptChild::~JavaScriptChild() bool JavaScriptChild::init() { - if (!WrapperOwner::init()) - return false; - if (!WrapperAnswer::init()) - return false; - JSContext* cx = dom::danger::GetJSContext(); JS_AddWeakPointerZonesCallback(cx, UpdateChildWeakPointersBeforeSweepingZoneGroup, this); JS_AddExtraGCRootsTracer(cx, TraceChild, this); diff --git a/js/ipc/JavaScriptParent.cpp b/js/ipc/JavaScriptParent.cpp index ee6829992bca..e8e6205fd5a3 100644 --- a/js/ipc/JavaScriptParent.cpp +++ b/js/ipc/JavaScriptParent.cpp @@ -31,21 +31,17 @@ TraceParent(JSTracer* trc, void* data) static_cast(data)->trace(trc); } +JavaScriptParent::JavaScriptParent() + : savedNextCPOWNumber_(1) +{ + JS_AddExtraGCRootsTracer(danger::GetJSContext(), TraceParent, this); +} + JavaScriptParent::~JavaScriptParent() { JS_RemoveExtraGCRootsTracer(danger::GetJSContext(), TraceParent, this); } -bool -JavaScriptParent::init() -{ - if (!WrapperOwner::init()) - return false; - - JS_AddExtraGCRootsTracer(danger::GetJSContext(), TraceParent, this); - return true; -} - static bool ForbidUnsafeBrowserCPOWs() { @@ -151,12 +147,7 @@ JavaScriptParent::afterProcessTask() PJavaScriptParent* mozilla::jsipc::NewJavaScriptParent() { - JavaScriptParent* parent = new JavaScriptParent(); - if (!parent->init()) { - delete parent; - return nullptr; - } - return parent; + return new JavaScriptParent(); } void diff --git a/js/ipc/JavaScriptParent.h b/js/ipc/JavaScriptParent.h index 19d4b22b55bc..d8310437c03d 100644 --- a/js/ipc/JavaScriptParent.h +++ b/js/ipc/JavaScriptParent.h @@ -17,10 +17,9 @@ namespace jsipc { class JavaScriptParent : public JavaScriptBase { public: - JavaScriptParent() : savedNextCPOWNumber_(1) {} + JavaScriptParent(); virtual ~JavaScriptParent(); - bool init(); void trace(JSTracer* trc); void drop(JSObject* obj); diff --git a/js/ipc/JavaScriptShared.cpp b/js/ipc/JavaScriptShared.cpp index 3bcb46318d28..2335751907fd 100644 --- a/js/ipc/JavaScriptShared.cpp +++ b/js/ipc/JavaScriptShared.cpp @@ -20,18 +20,10 @@ using namespace mozilla; using namespace mozilla::jsipc; IdToObjectMap::IdToObjectMap() - : table_(SystemAllocPolicy()) + : table_(SystemAllocPolicy(), 32) { } -bool -IdToObjectMap::init() -{ - if (table_.initialized()) - return true; - return table_.init(32); -} - void IdToObjectMap::trace(JSTracer* trc, uint64_t minimumId) { @@ -105,10 +97,9 @@ IdToObjectMap::has(const ObjectId& id, const JSObject* obj) const } #endif -bool -ObjectToIdMap::init() +ObjectToIdMap::ObjectToIdMap() + : table_(SystemAllocPolicy(), 32) { - return table_.initialized() || table_.init(32); } void @@ -179,21 +170,6 @@ JavaScriptShared::~JavaScriptShared() MOZ_RELEASE_ASSERT(cpows_.empty()); } -bool -JavaScriptShared::init() -{ - if (!objects_.init()) - return false; - if (!cpows_.init()) - return false; - if (!unwaivedObjectIds_.init()) - return false; - if (!waivedObjectIds_.init()) - return false; - - return true; -} - void JavaScriptShared::decref() { diff --git a/js/ipc/JavaScriptShared.h b/js/ipc/JavaScriptShared.h index 0aa46e707416..20a43aca00df 100644 --- a/js/ipc/JavaScriptShared.h +++ b/js/ipc/JavaScriptShared.h @@ -98,7 +98,6 @@ class IdToObjectMap public: IdToObjectMap(); - bool init(); void trace(JSTracer* trc, uint64_t minimumId = 0); void sweep(); @@ -125,7 +124,8 @@ class ObjectToIdMap using Table = JS::GCHashMap, ObjectId, Hasher, js::SystemAllocPolicy>; public: - bool init(); + ObjectToIdMap(); + void trace(JSTracer* trc); void sweep(); @@ -146,8 +146,6 @@ class JavaScriptShared : public CPOWManager JavaScriptShared(); virtual ~JavaScriptShared(); - bool init(); - void decref(); void incref(); diff --git a/js/ipc/WrapperOwner.cpp b/js/ipc/WrapperOwner.cpp index 6c28971b2f01..82bfffd3a0bd 100644 --- a/js/ipc/WrapperOwner.cpp +++ b/js/ipc/WrapperOwner.cpp @@ -906,15 +906,6 @@ WrapperOwner::updatePointer(JSObject* obj, const JSObject* old) cpows_.add(objId, obj); } -bool -WrapperOwner::init() -{ - if (!JavaScriptShared::init()) - return false; - - return true; -} - bool WrapperOwner::getPropertyKeys(JSContext* cx, HandleObject proxy, uint32_t flags, AutoIdVector& props) { diff --git a/js/ipc/WrapperOwner.h b/js/ipc/WrapperOwner.h index 382c0cb6349c..7b0c7e7a6320 100644 --- a/js/ipc/WrapperOwner.h +++ b/js/ipc/WrapperOwner.h @@ -24,7 +24,6 @@ class WrapperOwner : public virtual JavaScriptShared ActorDestroyReason; WrapperOwner(); - bool init(); // Standard internal methods. // (The traps should be in the same order like js/Proxy.h) diff --git a/js/public/GCHashTable.h b/js/public/GCHashTable.h index 78f669ac4d99..067776008478 100644 --- a/js/public/GCHashTable.h +++ b/js/public/GCHashTable.h @@ -60,11 +60,11 @@ class GCHashMap : public js::HashMap public: explicit GCHashMap(AllocPolicy a = AllocPolicy()) : Base(a) {} + explicit GCHashMap(size_t length) : Base(length) {} + GCHashMap(AllocPolicy a, size_t length) : Base(a, length) {} static void trace(GCHashMap* map, JSTracer* trc) { map->trace(trc); } void trace(JSTracer* trc) { - if (!this->initialized()) - return; for (typename Base::Enum e(*this); !e.empty(); e.popFront()) { GCPolicy::trace(trc, &e.front().value(), "hashmap value"); GCPolicy::trace(trc, &e.front().mutableKey(), "hashmap key"); @@ -72,13 +72,10 @@ class GCHashMap : public js::HashMap } bool needsSweep() const { - return this->initialized() && !this->empty(); + return !this->empty(); } void sweep() { - if (!this->initialized()) - return; - for (typename Base::Enum e(*this); !e.empty(); e.popFront()) { if (MapSweepPolicy::needsSweep(&e.front().mutableKey(), &e.front().value())) e.removeFront(); @@ -117,12 +114,11 @@ class GCRekeyableHashMap : public JS::GCHashMap; public: - explicit GCRekeyableHashMap(AllocPolicy a = AllocPolicy()) : Base(a) {} + explicit GCRekeyableHashMap(AllocPolicy a = AllocPolicy()) : Base(a) {} + explicit GCRekeyableHashMap(size_t length) : Base(length) {} + GCRekeyableHashMap(AllocPolicy a, size_t length) : Base(a, length) {} void sweep() { - if (!this->initialized()) - return; - for (typename Base::Enum e(*this); !e.empty(); e.popFront()) { Key key(e.front().key()); if (MapSweepPolicy::needsSweep(&key, &e.front().value())) @@ -153,9 +149,7 @@ class WrappedPtrOperations, Wrapper> using Ptr = typename Map::Ptr; using Range = typename Map::Range; - bool initialized() const { return map().initialized(); } Ptr lookup(const Lookup& l) const { return map().lookup(l); } - AddPtr lookupForAdd(const Lookup& l) const { return map().lookupForAdd(l); } Range all() const { return map().all(); } bool empty() const { return map().empty(); } uint32_t count() const { return map().count(); } @@ -184,10 +178,10 @@ class MutableWrappedPtrOperations, Wrapper> using Ptr = typename Map::Ptr; using Range = typename Map::Range; - bool init(uint32_t len = 16) { return map().init(len); } void clear() { map().clear(); } - void finish() { map().finish(); } + void clearAndCompact() { map().clearAndCompact(); } void remove(Ptr p) { map().remove(p); } + AddPtr lookupForAdd(const Lookup& l) { return map().lookupForAdd(l); } template bool add(AddPtr& p, KeyInput&& k, ValueInput&& v) { @@ -243,22 +237,20 @@ class GCHashSet : public js::HashSet public: explicit GCHashSet(AllocPolicy a = AllocPolicy()) : Base(a) {} + explicit GCHashSet(size_t length) : Base(length) {} + GCHashSet(AllocPolicy a, size_t length) : Base(a, length) {} static void trace(GCHashSet* set, JSTracer* trc) { set->trace(trc); } void trace(JSTracer* trc) { - if (!this->initialized()) - return; for (typename Base::Enum e(*this); !e.empty(); e.popFront()) GCPolicy::trace(trc, &e.mutableFront(), "hashset element"); } bool needsSweep() const { - return this->initialized() && !this->empty(); + return !this->empty(); } void sweep() { - if (!this->initialized()) - return; for (typename Base::Enum e(*this); !e.empty(); e.popFront()) { if (GCPolicy::needsSweep(&e.mutableFront())) e.removeFront(); @@ -296,9 +288,7 @@ class WrappedPtrOperations, Wrapper> using Ptr = typename Set::Ptr; using Range = typename Set::Range; - bool initialized() const { return set().initialized(); } Ptr lookup(const Lookup& l) const { return set().lookup(l); } - AddPtr lookupForAdd(const Lookup& l) const { return set().lookupForAdd(l); } Range all() const { return set().all(); } bool empty() const { return set().empty(); } uint32_t count() const { return set().count(); } @@ -328,11 +318,12 @@ class MutableWrappedPtrOperations, Wrapper> using Ptr = typename Set::Ptr; using Range = typename Set::Range; - bool init(uint32_t len = 16) { return set().init(len); } void clear() { set().clear(); } - void finish() { set().finish(); } + void clearAndCompact() { set().clearAndCompact(); } + MOZ_MUST_USE bool reserve(uint32_t len) { return set().reserve(len); } void remove(Ptr p) { set().remove(p); } void remove(const Lookup& l) { set().remove(l); } + AddPtr lookupForAdd(const Lookup& l) { return set().lookupForAdd(l); } template bool add(AddPtr& p, TInput&& t) { @@ -395,9 +386,6 @@ class WeakCache> } size_t sweep() override { - if (!this->initialized()) - return 0; - size_t steps = map.count(); map.sweep(); return steps; @@ -467,10 +455,6 @@ class WeakCache> } }; - bool initialized() const { - return map.initialized(); - } - Ptr lookup(const Lookup& l) const { Ptr ptr = map.lookup(l); if (needsBarrier && ptr && entryNeedsSweep(*ptr)) { @@ -480,7 +464,7 @@ class WeakCache> return ptr; } - AddPtr lookupForAdd(const Lookup& l) const { + AddPtr lookupForAdd(const Lookup& l) { AddPtr ptr = map.lookupForAdd(l); if (needsBarrier && ptr && entryNeedsSweep(*ptr)) { const_cast(map).remove(ptr); @@ -524,11 +508,6 @@ class WeakCache> return mallocSizeOf(this) + map.shallowSizeOfExcludingThis(mallocSizeOf); } - bool init(uint32_t len = 16) { - MOZ_ASSERT(!needsBarrier); - return map.init(len); - } - void clear() { // This operation is not currently allowed while barriers are in place // since it doesn't make sense to clear a cache while it is being swept. @@ -536,11 +515,11 @@ class WeakCache> map.clear(); } - void finish() { + void clearAndCompact() { // This operation is not currently allowed while barriers are in place - // since it doesn't make sense to destroy a cache while it is being swept. + // since it doesn't make sense to clear a cache while it is being swept. MOZ_ASSERT(!needsBarrier); - map.finish(); + map.clearAndCompact(); } void remove(Ptr p) { @@ -602,9 +581,6 @@ class WeakCache> {} size_t sweep() override { - if (!this->initialized()) - return 0; - size_t steps = set.count(); set.sweep(); return steps; @@ -674,10 +650,6 @@ class WeakCache> } }; - bool initialized() const { - return set.initialized(); - } - Ptr lookup(const Lookup& l) const { Ptr ptr = set.lookup(l); if (needsBarrier && ptr && entryNeedsSweep(*ptr)) { @@ -687,7 +659,7 @@ class WeakCache> return ptr; } - AddPtr lookupForAdd(const Lookup& l) const { + AddPtr lookupForAdd(const Lookup& l) { AddPtr ptr = set.lookupForAdd(l); if (needsBarrier && ptr && entryNeedsSweep(*ptr)) { const_cast(set).remove(ptr); @@ -731,11 +703,6 @@ class WeakCache> return mallocSizeOf(this) + set.shallowSizeOfExcludingThis(mallocSizeOf); } - bool init(uint32_t len = 16) { - MOZ_ASSERT(!needsBarrier); - return set.init(len); - } - void clear() { // This operation is not currently allowed while barriers are in place // since it doesn't make sense to clear a cache while it is being swept. @@ -743,11 +710,11 @@ class WeakCache> set.clear(); } - void finish() { + void clearAndCompact() { // This operation is not currently allowed while barriers are in place - // since it doesn't make sense to destroy a cache while it is being swept. + // since it doesn't make sense to clear a cache while it is being swept. MOZ_ASSERT(!needsBarrier); - set.finish(); + set.clearAndCompact(); } void remove(Ptr p) { diff --git a/js/public/MemoryMetrics.h b/js/public/MemoryMetrics.h index 85be91815473..ce157ec651e8 100644 --- a/js/public/MemoryMetrics.h +++ b/js/public/MemoryMetrics.h @@ -569,7 +569,7 @@ struct RuntimeSizes notableScriptSources() { allScriptSources = js_new(); - if (!allScriptSources || !allScriptSources->init()) + if (!allScriptSources) MOZ_CRASH("oom"); } diff --git a/js/public/UbiNodeBreadthFirst.h b/js/public/UbiNodeBreadthFirst.h index bc92b2e3ac0a..f6307ef49a75 100644 --- a/js/public/UbiNodeBreadthFirst.h +++ b/js/public/UbiNodeBreadthFirst.h @@ -88,9 +88,6 @@ struct BreadthFirst { traversalBegun(false), stopRequested(false), abandonRequested(false) { } - // Initialize this traversal object. Return false on OOM. - bool init() { return visited.init(); } - // Add |node| as a starting point for the traversal. You may add // as many starting points as you like. Return false on OOM. bool addStart(Node node) { return pending.append(node); } diff --git a/js/public/UbiNodeCensus.h b/js/public/UbiNodeCensus.h index e385cd7b9da7..6a45b659dd9d 100644 --- a/js/public/UbiNodeCensus.h +++ b/js/public/UbiNodeCensus.h @@ -206,8 +206,6 @@ struct Census { JS::ZoneSet targetZones; explicit Census(JSContext* cx) : cx(cx) { } - - MOZ_MUST_USE JS_PUBLIC_API(bool) init(); }; // A BreadthFirst handler type that conducts a census, using a CountBase to diff --git a/js/public/UbiNodeDominatorTree.h b/js/public/UbiNodeDominatorTree.h index fdb6fdd9a901..b5385f6b8b4a 100644 --- a/js/public/UbiNodeDominatorTree.h +++ b/js/public/UbiNodeDominatorTree.h @@ -338,7 +338,6 @@ class JS_PUBLIC_API(DominatorTree) if (!p) { mozilla::UniquePtr> set(js_new()); if (!set || - !set->init() || !predecessorSets.add(p, edge.referent, std::move(set))) { return false; @@ -349,8 +348,7 @@ class JS_PUBLIC_API(DominatorTree) }; PostOrder traversal(cx, noGC); - return traversal.init() && - traversal.addStart(root) && + return traversal.addStart(root) && traversal.traverse(onNode, onEdge); } @@ -358,10 +356,10 @@ class JS_PUBLIC_API(DominatorTree) // `postOrder`. static MOZ_MUST_USE bool mapNodesToTheirIndices(JS::ubi::Vector& postOrder, NodeToIndexMap& map) { - MOZ_ASSERT(!map.initialized()); + MOZ_ASSERT(map.empty()); MOZ_ASSERT(postOrder.length() < UINT32_MAX); uint32_t length = postOrder.length(); - if (!map.init(length)) + if (!map.reserve(length)) return false; for (uint32_t i = 0; i < length; i++) map.putNewInfallible(postOrder[i], i); @@ -403,7 +401,7 @@ class JS_PUBLIC_API(DominatorTree) predecessorVectors[i].infallibleAppend(ptr->value()); } } - predecessorSets.finish(); + predecessorSets.clearAndCompact(); return true; } @@ -515,7 +513,7 @@ class JS_PUBLIC_API(DominatorTree) Create(JSContext* cx, AutoCheckCannotGC& noGC, const Node& root) { JS::ubi::Vector postOrder; PredecessorSets predecessorSets; - if (!predecessorSets.init() || !doTraversal(cx, noGC, root, postOrder, predecessorSets)) + if (!doTraversal(cx, noGC, root, postOrder, predecessorSets)) return mozilla::Nothing(); MOZ_ASSERT(postOrder.length() < UINT32_MAX); @@ -528,7 +526,7 @@ class JS_PUBLIC_API(DominatorTree) // implementation, but we have to pay a little bit of upfront cost to // convert our data structures to play along first. - NodeToIndexMap nodeToPostOrderIndex; + NodeToIndexMap nodeToPostOrderIndex(postOrder.length()); if (!mapNodesToTheirIndices(postOrder, nodeToPostOrderIndex)) return mozilla::Nothing(); diff --git a/js/public/UbiNodePostOrder.h b/js/public/UbiNodePostOrder.h index 5b864af45819..34f74f850a60 100644 --- a/js/public/UbiNodePostOrder.h +++ b/js/public/UbiNodePostOrder.h @@ -123,9 +123,6 @@ struct PostOrder { #endif { } - // Initialize this traversal object. Return false on OOM. - MOZ_MUST_USE bool init() { return seen.init(); } - // Add `node` as a starting point for the traversal. You may add // as many starting points as you like. Returns false on OOM. MOZ_MUST_USE bool addStart(const Node& node) { diff --git a/js/public/UbiNodeShortestPaths.h b/js/public/UbiNodeShortestPaths.h index e93ca977f59a..c734be8ec99b 100644 --- a/js/public/UbiNodeShortestPaths.h +++ b/js/public/UbiNodeShortestPaths.h @@ -188,18 +188,11 @@ struct JS_PUBLIC_API(ShortestPaths) : maxNumPaths_(maxNumPaths) , root_(root) , targets_(std::move(targets)) - , paths_() + , paths_(targets_.count()) , backEdges_() { MOZ_ASSERT(maxNumPaths_ > 0); MOZ_ASSERT(root_); - MOZ_ASSERT(targets_.initialized()); - } - - bool initialized() const { - return targets_.initialized() && - paths_.initialized() && - backEdges_.initialized(); } public: @@ -249,15 +242,12 @@ struct JS_PUBLIC_API(ShortestPaths) MOZ_ASSERT(targets.count() > 0); MOZ_ASSERT(maxNumPaths > 0); - size_t count = targets.count(); ShortestPaths paths(maxNumPaths, root, std::move(targets)); - if (!paths.paths_.init(count)) - return mozilla::Nothing(); Handler handler(paths); Traversal traversal(cx, handler, noGC); traversal.wantNames = true; - if (!traversal.init() || !traversal.addStart(root) || !traversal.traverse()) + if (!traversal.addStart(root) || !traversal.traverse()) return mozilla::Nothing(); // Take ownership of the back edges we created while traversing the @@ -265,7 +255,6 @@ struct JS_PUBLIC_API(ShortestPaths) // use-after-free. paths.backEdges_ = std::move(traversal.visited); - MOZ_ASSERT(paths.initialized()); return mozilla::Some(std::move(paths)); } @@ -275,7 +264,6 @@ struct JS_PUBLIC_API(ShortestPaths) * instance. */ NodeSet::Iterator targetIter() const { - MOZ_ASSERT(initialized()); return targets_.iter(); } @@ -291,7 +279,6 @@ struct JS_PUBLIC_API(ShortestPaths) */ template MOZ_MUST_USE bool forEachPath(const Node& target, Func func) { - MOZ_ASSERT(initialized()); MOZ_ASSERT(targets_.has(target)); auto ptr = paths_.lookup(target); diff --git a/js/src/builtin/JSON.cpp b/js/src/builtin/JSON.cpp index be833e5b691a..adffaaed200d 100644 --- a/js/src/builtin/JSON.cpp +++ b/js/src/builtin/JSON.cpp @@ -661,9 +661,7 @@ js::Stringify(JSContext* cx, MutableHandleValue vp, JSObject* replacer_, const V // is passed in. If we end up having to add elements past this // size, the set will naturally resize to accommodate them. const uint32_t MaxInitialSize = 32; - Rooted> idSet(cx, GCHashSet(cx)); - if (!idSet.init(Min(len, MaxInitialSize))) - return false; + Rooted> idSet(cx, GCHashSet(cx, Min(len, MaxInitialSize))); /* Step 4b(iii)(4). */ uint32_t k = 0; diff --git a/js/src/builtin/ModuleObject.cpp b/js/src/builtin/ModuleObject.cpp index ece71b2860ed..ac2dc1875a83 100644 --- a/js/src/builtin/ModuleObject.cpp +++ b/js/src/builtin/ModuleObject.cpp @@ -349,11 +349,6 @@ IndirectBindingMap::put(JSContext* cx, HandleId name, if (!map_) { MOZ_ASSERT(!cx->zone()->createdForHelperThread()); map_.emplace(cx->zone()); - if (!map_->init()) { - map_.reset(); - ReportOutOfMemory(cx); - return false; - } } RootedShape shape(cx, environment->lookup(cx, localName)); @@ -1231,14 +1226,6 @@ ModuleBuilder::ModuleBuilder(JSContext* cx, HandleModuleObject module, starExportEntries_(cx, ExportEntryVector(cx)) {} -bool -ModuleBuilder::init() -{ - return requestedModuleSpecifiers_.init() && - importEntries_.init() && - exportNames_.init(); -} - bool ModuleBuilder::buildTables() { diff --git a/js/src/builtin/ModuleObject.h b/js/src/builtin/ModuleObject.h index 9216acbc7111..5664b669ab31 100644 --- a/js/src/builtin/ModuleObject.h +++ b/js/src/builtin/ModuleObject.h @@ -352,7 +352,6 @@ class MOZ_STACK_CLASS ModuleBuilder public: explicit ModuleBuilder(JSContext* cx, HandleModuleObject module, const frontend::TokenStreamAnyChars& tokenStream); - bool init(); bool processImport(frontend::ParseNode* pn); bool processExport(frontend::ParseNode* pn); diff --git a/js/src/builtin/Promise.cpp b/js/src/builtin/Promise.cpp index 38eb7e10538d..761e6b63e49a 100644 --- a/js/src/builtin/Promise.cpp +++ b/js/src/builtin/Promise.cpp @@ -4579,9 +4579,6 @@ OffThreadPromiseRuntimeState::OffThreadPromiseRuntimeState() numCanceled_(0), internalDispatchQueueClosed_(false) { - AutoEnterOOMUnsafeRegion noOOM; - if (!live_.init()) - noOOM.crash("OffThreadPromiseRuntimeState"); } OffThreadPromiseRuntimeState::~OffThreadPromiseRuntimeState() diff --git a/js/src/builtin/ReflectParse.cpp b/js/src/builtin/ReflectParse.cpp index f2057ab7f829..afe16e8b86f5 100644 --- a/js/src/builtin/ReflectParse.cpp +++ b/js/src/builtin/ReflectParse.cpp @@ -3469,8 +3469,6 @@ reflect_parse(JSContext* cx, uint32_t argc, Value* vp) options.allowHTMLComments = target == ParseGoal::Script; mozilla::Range chars = linearChars.twoByteRange(); UsedNameTracker usedNames(cx); - if (!usedNames.init()) - return false; RootedScriptSourceObject sourceObject(cx, frontend::CreateScriptSourceObject(cx, options, mozilla::Nothing())); @@ -3500,8 +3498,6 @@ reflect_parse(JSContext* cx, uint32_t argc, Value* vp) return false; ModuleBuilder builder(cx, module, parser.anyChars); - if (!builder.init()) - return false; ModuleSharedContext modulesc(cx, module, &cx->global()->emptyGlobalScope(), builder); pn = parser.moduleBody(&modulesc); diff --git a/js/src/builtin/TestingFunctions.cpp b/js/src/builtin/TestingFunctions.cpp index 120b38440f54..6e5d1385fbbd 100644 --- a/js/src/builtin/TestingFunctions.cpp +++ b/js/src/builtin/TestingFunctions.cpp @@ -1254,8 +1254,7 @@ ClearSavedFrames(JSContext* cx, unsigned argc, Value* vp) CallArgs args = CallArgsFromVp(argc, vp); js::SavedStacks& savedStacks = cx->realm()->savedStacks(); - if (savedStacks.initialized()) - savedStacks.clear(); + savedStacks.clear(); for (ActivationIterator iter(cx); !iter.done(); ++iter) iter->clearLiveSavedFrameCache(); @@ -3593,7 +3592,7 @@ FindPath(JSContext* cx, unsigned argc, Value* vp) heaptools::FindPathHandler handler(cx, start, target, &nodes, edges); heaptools::FindPathHandler::Traversal traversal(cx, handler, autoCannotGC); - if (!traversal.init() || !traversal.addStart(start)) { + if (!traversal.addStart(start)) { ReportOutOfMemory(cx); return false; } @@ -3719,10 +3718,6 @@ ShortestPaths(JSContext* cx, unsigned argc, Value* vp) JS::AutoCheckCannotGC noGC(cx); JS::ubi::NodeSet targets; - if (!targets.init()) { - ReportOutOfMemory(cx); - return false; - } for (size_t i = 0; i < length; i++) { RootedValue val(cx, objs->getDenseElement(i)); diff --git a/js/src/builtin/TypedObject.cpp b/js/src/builtin/TypedObject.cpp index 05cfc51c15f2..0b3506af52ac 100644 --- a/js/src/builtin/TypedObject.cpp +++ b/js/src/builtin/TypedObject.cpp @@ -2163,11 +2163,6 @@ InlineTransparentTypedObject::getOrCreateBuffer(JSContext* cx) if (!table) return nullptr; - if (!table->init()) { - ReportOutOfMemory(cx); - return nullptr; - } - realm.lazyArrayBuffers = std::move(table); } diff --git a/js/src/builtin/WeakMapObject-inl.h b/js/src/builtin/WeakMapObject-inl.h index be63310c78a2..c1883122f720 100644 --- a/js/src/builtin/WeakMapObject-inl.h +++ b/js/src/builtin/WeakMapObject-inl.h @@ -41,10 +41,6 @@ WeakCollectionPutEntryInternal(JSContext* cx, Handle obj, auto newMap = cx->make_unique(cx, obj.get()); if (!newMap) return false; - if (!newMap->init()) { - JS_ReportOutOfMemory(cx); - return false; - } map = newMap.release(); obj->setPrivate(map); } diff --git a/js/src/builtin/intl/SharedIntlData.cpp b/js/src/builtin/intl/SharedIntlData.cpp index 5db1ae9ff2f3..123854d4292a 100644 --- a/js/src/builtin/intl/SharedIntlData.cpp +++ b/js/src/builtin/intl/SharedIntlData.cpp @@ -111,12 +111,7 @@ js::intl::SharedIntlData::ensureTimeZones(JSContext* cx) // If ensureTimeZones() was called previously, but didn't complete due to // OOM, clear all sets/maps and start from scratch. - if (availableTimeZones.initialized()) - availableTimeZones.finish(); - if (!availableTimeZones.init()) { - ReportOutOfMemory(cx); - return false; - } + availableTimeZones.clearAndCompact(); UErrorCode status = U_ZERO_ERROR; UEnumeration* values = ucal_openTimeZones(&status); @@ -158,12 +153,7 @@ js::intl::SharedIntlData::ensureTimeZones(JSContext* cx) } } - if (ianaZonesTreatedAsLinksByICU.initialized()) - ianaZonesTreatedAsLinksByICU.finish(); - if (!ianaZonesTreatedAsLinksByICU.init()) { - ReportOutOfMemory(cx); - return false; - } + ianaZonesTreatedAsLinksByICU.clearAndCompact(); for (const char* rawTimeZone : timezone::ianaZonesTreatedAsLinksByICU) { MOZ_ASSERT(rawTimeZone != nullptr); @@ -181,12 +171,7 @@ js::intl::SharedIntlData::ensureTimeZones(JSContext* cx) } } - if (ianaLinksCanonicalizedDifferentlyByICU.initialized()) - ianaLinksCanonicalizedDifferentlyByICU.finish(); - if (!ianaLinksCanonicalizedDifferentlyByICU.init()) { - ReportOutOfMemory(cx); - return false; - } + ianaLinksCanonicalizedDifferentlyByICU.clearAndCompact(); RootedAtom linkName(cx); RootedAtom& target = timeZone; @@ -308,12 +293,7 @@ js::intl::SharedIntlData::ensureUpperCaseFirstLocales(JSContext* cx) // If ensureUpperCaseFirstLocales() was called previously, but didn't // complete due to OOM, clear all data and start from scratch. - if (upperCaseFirstLocales.initialized()) - upperCaseFirstLocales.finish(); - if (!upperCaseFirstLocales.init()) { - ReportOutOfMemory(cx); - return false; - } + upperCaseFirstLocales.clearAndCompact(); UErrorCode status = U_ZERO_ERROR; UEnumeration* available = ucol_openAvailableLocales(&status); @@ -393,10 +373,10 @@ js::intl::SharedIntlData::isUpperCaseFirst(JSContext* cx, HandleString locale, b void js::intl::SharedIntlData::destroyInstance() { - availableTimeZones.finish(); - ianaZonesTreatedAsLinksByICU.finish(); - ianaLinksCanonicalizedDifferentlyByICU.finish(); - upperCaseFirstLocales.finish(); + availableTimeZones.clearAndCompact(); + ianaZonesTreatedAsLinksByICU.clearAndCompact(); + ianaLinksCanonicalizedDifferentlyByICU.clearAndCompact(); + upperCaseFirstLocales.clearAndCompact(); } void diff --git a/js/src/ctypes/CTypes.cpp b/js/src/ctypes/CTypes.cpp index 818c71258ff7..f6fa3482a1e4 100644 --- a/js/src/ctypes/CTypes.cpp +++ b/js/src/ctypes/CTypes.cpp @@ -6104,11 +6104,7 @@ StructType::DefineInternal(JSContext* cx, JSObject* typeObj_, JSObject* fieldsOb return false; // Create a FieldInfoHash to stash on the type object. - Rooted fields(cx); - if (!fields.init(len)) { - JS_ReportOutOfMemory(cx); - return false; - } + Rooted fields(cx, len); // Process the field types. size_t structSize, structAlign; @@ -6215,7 +6211,6 @@ StructType::DefineInternal(JSContext* cx, JSObject* typeObj_, JSObject* fieldsOb JS_ReportOutOfMemory(cx); return false; } - MOZ_ASSERT(heapHash->initialized()); JS_SetReservedSlot(typeObj, SLOT_FIELDINFO, PrivateValue(heapHash)); JS_SetReservedSlot(typeObj, SLOT_SIZE, sizeVal); diff --git a/js/src/ds/Bitmap.cpp b/js/src/ds/Bitmap.cpp index 1152c27af17a..79610d3e2f04 100644 --- a/js/src/ds/Bitmap.cpp +++ b/js/src/ds/Bitmap.cpp @@ -12,10 +12,8 @@ using namespace js; SparseBitmap::~SparseBitmap() { - if (data.initialized()) { - for (Data::Range r(data.all()); !r.empty(); r.popFront()) - js_delete(r.front().value()); - } + for (Data::Range r(data.all()); !r.empty(); r.popFront()) + js_delete(r.front().value()); } size_t @@ -28,10 +26,9 @@ SparseBitmap::sizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf) } SparseBitmap::BitBlock& -SparseBitmap::createBlock(Data::AddPtr p, size_t blockId) +SparseBitmap::createBlock(Data::AddPtr p, size_t blockId, AutoEnterOOMUnsafeRegion& oomUnsafe) { - MOZ_ASSERT(!p); - AutoEnterOOMUnsafeRegion oomUnsafe; + MOZ_ASSERT(!p && p.isValid()); BitBlock* block = js_new(); if (!block || !data.add(p, blockId, block)) oomUnsafe.crash("Bitmap OOM"); diff --git a/js/src/ds/Bitmap.h b/js/src/ds/Bitmap.h index 85499d37c72f..e494373984ef 100644 --- a/js/src/ds/Bitmap.h +++ b/js/src/ds/Bitmap.h @@ -88,7 +88,7 @@ class SparseBitmap return std::min((size_t)WordsInBlock, std::max(count, 0)); } - BitBlock& createBlock(Data::AddPtr p, size_t blockId); + BitBlock& createBlock(Data::AddPtr p, size_t blockId, AutoEnterOOMUnsafeRegion& oomUnsafe); MOZ_ALWAYS_INLINE BitBlock* getBlock(size_t blockId) const { Data::Ptr p = data.lookup(blockId); @@ -96,14 +96,16 @@ class SparseBitmap } MOZ_ALWAYS_INLINE BitBlock& getOrCreateBlock(size_t blockId) { + // The lookupForAdd() needs protection against injected OOMs, as does + // the add() within createBlock(). + AutoEnterOOMUnsafeRegion oomUnsafe; Data::AddPtr p = data.lookupForAdd(blockId); if (p) return *p->value(); - return createBlock(p, blockId); + return createBlock(p, blockId, oomUnsafe); } public: - bool init() { return data.init(); } ~SparseBitmap(); size_t sizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf); diff --git a/js/src/ds/InlineTable.h b/js/src/ds/InlineTable.h index 40e9bf1d9f41..7ca2e10fcfb5 100644 --- a/js/src/ds/InlineTable.h +++ b/js/src/ds/InlineTable.h @@ -71,13 +71,7 @@ class InlineTable : private AllocPolicy MOZ_MUST_USE bool switchToTable() { MOZ_ASSERT(inlNext_ == InlineEntries); - if (table_.initialized()) { - table_.clear(); - } else { - if (!table_.init(count())) - return false; - MOZ_ASSERT(table_.initialized()); - } + table_.clear(); InlineEntry* end = inlineEnd(); for (InlineEntry* it = inlineStart(); it != end; ++it) { @@ -330,7 +324,7 @@ class InlineTable : private AllocPolicy --inlCount_; return; } - MOZ_ASSERT(table_.initialized() && usingTable()); + MOZ_ASSERT(usingTable()); table_.remove(p.tablePtr_); } diff --git a/js/src/frontend/BinSourceRuntimeSupport.h b/js/src/frontend/BinSourceRuntimeSupport.h index 86bd7f5f6780..a7401b67812f 100644 --- a/js/src/frontend/BinSourceRuntimeSupport.h +++ b/js/src/frontend/BinSourceRuntimeSupport.h @@ -64,6 +64,8 @@ struct BinaryASTSupport { } }; + BinaryASTSupport(); + JS::Result binVariant(JSContext*, const CharSlice); JS::Result binField(JSContext*, const CharSlice); JS::Result binKind(JSContext*, const CharSlice); diff --git a/js/src/frontend/BinToken.cpp b/js/src/frontend/BinToken.cpp index 836158629c87..30c31f48fc4a 100644 --- a/js/src/frontend/BinToken.cpp +++ b/js/src/frontend/BinToken.cpp @@ -73,15 +73,17 @@ const char* describeBinVariant(const BinVariant& variant) } // namespace frontend +BinaryASTSupport::BinaryASTSupport() + : binKindMap_(frontend::BINKIND_LIMIT) + , binFieldMap_(frontend::BINFIELD_LIMIT) + , binVariantMap_(frontend::BINVARIANT_LIMIT) +{ +} JS::Result BinaryASTSupport::binKind(JSContext* cx, const CharSlice key) { - if (!binKindMap_.initialized()) { - // Initialize lazily. - if (!binKindMap_.init(frontend::BINKIND_LIMIT)) - return ReportOutOfMemoryResult(cx); - + if (binKindMap_.empty()) { for (size_t i = 0; i < frontend::BINKIND_LIMIT; ++i) { const BinKind variant = static_cast(i); const CharSlice& key = getBinKind(variant); @@ -100,12 +102,9 @@ BinaryASTSupport::binKind(JSContext* cx, const CharSlice key) } JS::Result -BinaryASTSupport::binVariant(JSContext* cx, const CharSlice key) { - if (!binVariantMap_.initialized()) { - // Initialize lazily. - if (!binVariantMap_.init(frontend::BINVARIANT_LIMIT)) - return ReportOutOfMemoryResult(cx); - +BinaryASTSupport::binVariant(JSContext* cx, const CharSlice key) +{ + if (binVariantMap_.empty()) { for (size_t i = 0; i < frontend::BINVARIANT_LIMIT; ++i) { const BinVariant variant = static_cast(i); const CharSlice& key = getBinVariant(variant); diff --git a/js/src/frontend/BinTokenReaderMultipart.cpp b/js/src/frontend/BinTokenReaderMultipart.cpp index 5b0bf05bef42..116333667387 100644 --- a/js/src/frontend/BinTokenReaderMultipart.cpp +++ b/js/src/frontend/BinTokenReaderMultipart.cpp @@ -125,8 +125,6 @@ BinTokenReaderMultipart::readHeader() return raiseOOM(); if (!slicesTable_.reserve(stringsNumberOfEntries)) return raiseOOM(); - if (!variantsTable_.init()) - return raiseOOM(); RootedAtom atom(cx_); for (uint32_t i = 0; i < stringsNumberOfEntries; ++i) { diff --git a/js/src/frontend/BytecodeCompiler.cpp b/js/src/frontend/BytecodeCompiler.cpp index 824128e00fc2..a4f8eb7c643e 100644 --- a/js/src/frontend/BytecodeCompiler.cpp +++ b/js/src/frontend/BytecodeCompiler.cpp @@ -223,8 +223,6 @@ bool BytecodeCompiler::createParser(ParseGoal goal) { usedNames.emplace(cx); - if (!usedNames->init()) - return false; if (canLazilyParse()) { syntaxParser.emplace(cx, alloc, options, sourceBuffer.get(), sourceBuffer.length(), @@ -410,8 +408,6 @@ BytecodeCompiler::compileModule() module->init(script); ModuleBuilder builder(cx, module, parser->anyChars); - if (!builder.init()) - return nullptr; ModuleSharedContext modulesc(cx, module, enclosingScope, builder); ParseNode* pn = parser->moduleBody(&modulesc); @@ -629,8 +625,6 @@ frontend::CompileGlobalBinASTScript(JSContext* cx, LifoAlloc& alloc, const ReadO AutoAssertReportedException assertException(cx); frontend::UsedNameTracker usedNames(cx); - if (!usedNames.init()) - return nullptr; RootedScriptSourceObject sourceObj(cx, CreateScriptSourceObject(cx, options)); @@ -819,8 +813,6 @@ frontend::CompileLazyFunction(JSContext* cx, Handle lazy, const cha } UsedNameTracker usedNames(cx); - if (!usedNames.init()) - return false; RootedScriptSourceObject sourceObject(cx, &lazy->sourceObject()); Parser parser(cx, cx->tempLifoAlloc(), options, chars, length, diff --git a/js/src/frontend/ParseContext.h b/js/src/frontend/ParseContext.h index f389eee6194d..1a566c825a29 100644 --- a/js/src/frontend/ParseContext.h +++ b/js/src/frontend/ParseContext.h @@ -121,10 +121,6 @@ class UsedNameTracker scopeCounter_(0) { } - MOZ_MUST_USE bool init() { - return map_.init(); - } - uint32_t nextScriptId() { MOZ_ASSERT(scriptCounter_ != UINT32_MAX, "ParseContext::Scope::init should have prevented wraparound"); diff --git a/js/src/fuzz-tests/testBinASTReader.cpp b/js/src/fuzz-tests/testBinASTReader.cpp index 0ca319242b5b..90f6bc4ec860 100644 --- a/js/src/fuzz-tests/testBinASTReader.cpp +++ b/js/src/fuzz-tests/testBinASTReader.cpp @@ -51,10 +51,6 @@ testBinASTReaderFuzz(const uint8_t* buf, size_t size) { } js::frontend::UsedNameTracker binUsedNames(gCx); - if (!binUsedNames.init()) { - ReportOutOfMemory(gCx); - return 0; - } js::frontend::BinASTParser reader(gCx, gCx->tempLifoAlloc(), binUsedNames, options); diff --git a/js/src/gc/GC.cpp b/js/src/gc/GC.cpp index e3a9837c0a6b..82a89f6c2287 100644 --- a/js/src/gc/GC.cpp +++ b/js/src/gc/GC.cpp @@ -963,6 +963,7 @@ GCRuntime::GCRuntime(JSRuntime* rt) : stats_(rt), marker(rt), usage(nullptr), + rootsHash(256), nextCellUniqueId_(LargestTaggedNullCellPointer + 1), // Ensure disjoint from null tagged pointers. numArenasFreeCommitted(0), verifyPreData(nullptr), @@ -1287,9 +1288,6 @@ GCRuntime::init(uint32_t maxbytes, uint32_t maxNurseryBytes) { MOZ_ASSERT(SystemPageSize()); - if (!rootsHash.ref().init(256)) - return false; - { AutoLockGCBgAlloc lock(rt); @@ -4699,9 +4697,6 @@ js::gc::MarkingValidator::nonIncrementalMark(AutoGCSession& session) * Currently this does not validate gray marking. */ - if (!map.init()) - return; - JSRuntime* runtime = gc->rt; GCMarker* gcmarker = &gc->marker; @@ -4732,8 +4727,6 @@ js::gc::MarkingValidator::nonIncrementalMark(AutoGCSession& session) */ WeakMapSet markedWeakMaps; - if (!markedWeakMaps.init()) - return; /* * For saving, smush all of the keys into one big table and split them back @@ -8077,7 +8070,7 @@ js::NewRealm(JSContext* cx, JSPrincipals* principals, const JS::RealmOptions& op if (!comp) { compHolder = cx->make_unique(zone); - if (!compHolder || !compHolder->init(cx)) + if (!compHolder) return nullptr; comp = compHolder.get(); @@ -8254,9 +8247,6 @@ GCRuntime::mergeRealms(Realm* source, Realm* target) if (!target->scriptNameMap) oomUnsafe.crash("Failed to create a script name map."); - - if (!target->scriptNameMap->init()) - oomUnsafe.crash("Failed to initialize a script name map."); } for (ScriptNameMap::Range r = source->scriptNameMap->all(); !r.empty(); r.popFront()) { diff --git a/js/src/gc/HashUtil.h b/js/src/gc/HashUtil.h index 56be29a79c54..dbdc1a2a4361 100644 --- a/js/src/gc/HashUtil.h +++ b/js/src/gc/HashUtil.h @@ -24,7 +24,7 @@ struct DependentAddPtr typedef typename T::Entry Entry; template - DependentAddPtr(const JSContext* cx, const T& table, const Lookup& lookup) + DependentAddPtr(const JSContext* cx, T& table, const Lookup& lookup) : addPtr(table.lookupForAdd(lookup)) , originalGcNumber(cx->zone()->gcNumber()) {} @@ -56,7 +56,7 @@ struct DependentAddPtr const Entry* operator->() const { return &*addPtr; } private: - AddPtr addPtr ; + AddPtr addPtr; const uint64_t originalGcNumber; template diff --git a/js/src/gc/Marking.cpp b/js/src/gc/Marking.cpp index ec8f9affe8d1..364cfacc3746 100644 --- a/js/src/gc/Marking.cpp +++ b/js/src/gc/Marking.cpp @@ -2711,7 +2711,6 @@ js::gc::StoreBuffer::MonoTypeBuffer::trace(StoreBuffer* owner, TenuringTracer { mozilla::ReentrancyGuard g(*owner); MOZ_ASSERT(owner->isEnabled()); - MOZ_ASSERT(stores_.initialized()); if (last_) last_.trace(mover); for (typename StoreSet::Range r = stores_.all(); !r.empty(); r.popFront()) diff --git a/js/src/gc/Nursery.cpp b/js/src/gc/Nursery.cpp index 9ecd174e5a59..c8bca8890366 100644 --- a/js/src/gc/Nursery.cpp +++ b/js/src/gc/Nursery.cpp @@ -49,7 +49,6 @@ struct js::Nursery::FreeMallocedBuffersTask : public GCParallelTaskHelperruntime()), fop_(fop) {} - bool init() { return buffers_.init(); } void transferBuffersToFree(MallocedBuffersSet& buffersToFree, const AutoLockHelperThreadState& lock); ~FreeMallocedBuffersTask() { join(); } @@ -149,11 +148,8 @@ js::Nursery::Nursery(JSRuntime* rt) bool js::Nursery::init(uint32_t maxNurseryBytes, AutoLockGCBgAlloc& lock) { - if (!mallocedBuffers.init()) - return false; - freeMallocedBuffersTask = js_new(runtime()->defaultFreeOp()); - if (!freeMallocedBuffersTask || !freeMallocedBuffersTask->init()) + if (!freeMallocedBuffersTask) return false; // The nursery is permanently disabled when recording or replaying. Nursery @@ -500,8 +496,6 @@ Nursery::setIndirectForwardingPointer(void* oldData, void* newData) MOZ_ASSERT(!isInside(newData) || (uintptr_t(newData) & ChunkMask) == 0); AutoEnterOOMUnsafeRegion oomUnsafe; - if (!forwardedBuffers.initialized() && !forwardedBuffers.init()) - oomUnsafe.crash("Nursery::setForwardingPointer"); #ifdef DEBUG if (ForwardedBufferMap::Ptr p = forwardedBuffers.lookup(oldData)) MOZ_ASSERT(p->value() == newData); @@ -530,11 +524,9 @@ js::Nursery::forwardBufferPointer(HeapSlot** pSlotsElems) // The new location for this buffer is either stored inline with it or in // the forwardedBuffers table. do { - if (forwardedBuffers.initialized()) { - if (ForwardedBufferMap::Ptr p = forwardedBuffers.lookup(old)) { - *pSlotsElems = reinterpret_cast(p->value()); - break; - } + if (ForwardedBufferMap::Ptr p = forwardedBuffers.lookup(old)) { + *pSlotsElems = reinterpret_cast(p->value()); + break; } *pSlotsElems = *reinterpret_cast(old); @@ -929,7 +921,7 @@ js::Nursery::doCollection(JS::gcreason::Reason reason, TenureCountCache& tenureC // Update any slot or element pointers whose destination has been tenured. startProfile(ProfileKey::UpdateJitActivations); js::jit::UpdateJitActivationsForMinorGC(rt); - forwardedBuffers.finish(); + forwardedBuffers.clearAndCompact(); endProfile(ProfileKey::UpdateJitActivations); startProfile(ProfileKey::ObjectsTenuredCallback); diff --git a/js/src/gc/Nursery.h b/js/src/gc/Nursery.h index 3efec6cbedd5..228f41147900 100644 --- a/js/src/gc/Nursery.h +++ b/js/src/gc/Nursery.h @@ -288,8 +288,6 @@ class Nursery return allocatedChunkCount() * gc::ChunkSize; } size_t sizeOfMallocedBuffers(mozilla::MallocSizeOf mallocSizeOf) const { - if (!mallocedBuffers.initialized()) - return 0; size_t total = 0; for (MallocedBuffersSet::Range r = mallocedBuffers.all(); !r.empty(); r.popFront()) total += mallocSizeOf(r.front()); diff --git a/js/src/gc/NurseryAwareHashMap.h b/js/src/gc/NurseryAwareHashMap.h index 2c8631562341..7697acaedf0b 100644 --- a/js/src/gc/NurseryAwareHashMap.h +++ b/js/src/gc/NurseryAwareHashMap.h @@ -90,8 +90,8 @@ class NurseryAwareHashMap using Entry = typename MapType::Entry; explicit NurseryAwareHashMap(AllocPolicy a = AllocPolicy()) : map(a) {} - - MOZ_MUST_USE bool init(uint32_t len = 16) { return map.init(len); } + explicit NurseryAwareHashMap(size_t length) : map(length) {} + NurseryAwareHashMap(AllocPolicy a, size_t length) : map(a, length) {} bool empty() const { return map.empty(); } Ptr lookup(const Lookup& l) const { return map.lookup(l); } diff --git a/js/src/gc/RootMarking.cpp b/js/src/gc/RootMarking.cpp index f645e5f2c9c9..934eb15651d3 100644 --- a/js/src/gc/RootMarking.cpp +++ b/js/src/gc/RootMarking.cpp @@ -432,8 +432,7 @@ js::gc::GCRuntime::finishRoots() rt->finishAtoms(); - if (rootsHash.ref().initialized()) - rootsHash.ref().clear(); + rootsHash.ref().clear(); rt->finishPersistentRoots(); diff --git a/js/src/gc/StoreBuffer.cpp b/js/src/gc/StoreBuffer.cpp index 46649bf0719c..4360f1b8877c 100644 --- a/js/src/gc/StoreBuffer.cpp +++ b/js/src/gc/StoreBuffer.cpp @@ -50,10 +50,7 @@ StoreBuffer::enable() checkEmpty(); - if (!bufferVal.init() || - !bufferCell.init() || - !bufferSlot.init() || - !bufferWholeCell.init() || + if (!bufferWholeCell.init() || !bufferGeneric.init()) { return false; diff --git a/js/src/gc/StoreBuffer.h b/js/src/gc/StoreBuffer.h index e5807a1b373b..59f03f288c03 100644 --- a/js/src/gc/StoreBuffer.h +++ b/js/src/gc/StoreBuffer.h @@ -83,24 +83,14 @@ class StoreBuffer const static size_t MaxEntries = 48 * 1024 / sizeof(T); explicit MonoTypeBuffer() : last_(T()) {} - ~MonoTypeBuffer() { stores_.finish(); } - - MOZ_MUST_USE bool init() { - if (!stores_.initialized() && !stores_.init()) - return false; - clear(); - return true; - } void clear() { last_ = T(); - if (stores_.initialized()) - stores_.clear(); + stores_.clear(); } /* Add one item to the buffer. */ void put(StoreBuffer* owner, const T& t) { - MOZ_ASSERT(stores_.initialized()); sinkStore(owner); last_ = t; } @@ -117,7 +107,6 @@ class StoreBuffer /* Move any buffered stores to the canonical store set. */ void sinkStore(StoreBuffer* owner) { - MOZ_ASSERT(stores_.initialized()); if (last_) { AutoEnterOOMUnsafeRegion oomUnsafe; if (!stores_.put(last_)) @@ -142,7 +131,7 @@ class StoreBuffer } bool isEmpty() const { - return last_ == T() && (!stores_.initialized() || stores_.empty()); + return last_ == T() && stores_.empty(); } private: diff --git a/js/src/gc/Verifier.cpp b/js/src/gc/Verifier.cpp index 07199adf0d78..495448996d57 100644 --- a/js/src/gc/Verifier.cpp +++ b/js/src/gc/Verifier.cpp @@ -212,9 +212,6 @@ gc::GCRuntime::startVerifyPreBarriers() trc->edgeptr = (char*)trc->root; trc->term = trc->edgeptr + size; - if (!trc->nodemap.init()) - goto oom; - /* Create the root node. */ trc->curnode = MakeNode(trc, nullptr, JS::TraceKind(0)); @@ -458,7 +455,6 @@ class HeapCheckTracerBase : public JS::CallbackTracer { public: explicit HeapCheckTracerBase(JSRuntime* rt, WeakMapTraceKind weakTraceKind); - bool init(); bool traceHeap(AutoTraceSession& session); virtual void checkCell(Cell* cell) = 0; @@ -505,12 +501,6 @@ HeapCheckTracerBase::HeapCheckTracerBase(JSRuntime* rt, WeakMapTraceKind weakTra #endif } -bool -HeapCheckTracerBase::init() -{ - return visited.init(); -} - void HeapCheckTracerBase::onChild(const JS::GCCellPtr& thing) { @@ -674,8 +664,7 @@ js::gc::CheckHeapAfterGC(JSRuntime* rt) gcType = CheckHeapTracer::GCType::NonMoving; CheckHeapTracer tracer(rt, gcType); - if (tracer.init()) - tracer.check(session); + tracer.check(session); } #endif /* JSGC_HASH_TABLE_CHECKS */ @@ -743,8 +732,6 @@ js::CheckGrayMarkingState(JSRuntime* rt) gcstats::AutoPhase ap(rt->gc.stats(), gcstats::PhaseKind::TRACE_HEAP); AutoTraceSession session(rt); CheckGrayMarkingTracer tracer(rt); - if (!tracer.init()) - return true; // Ignore failure return tracer.check(session); } diff --git a/js/src/gc/WeakMap-inl.h b/js/src/gc/WeakMap-inl.h index d7b1ffa11d4b..60cbdf3ae59a 100644 --- a/js/src/gc/WeakMap-inl.h +++ b/js/src/gc/WeakMap-inl.h @@ -28,17 +28,9 @@ static T* extractUnbarriered(T* v) template WeakMap::WeakMap(JSContext* cx, JSObject* memOf) : Base(cx->zone()), WeakMapBase(memOf, cx->zone()) -{} - -template -bool -WeakMap::init(uint32_t len) { - if (!Base::init(len)) - return false; zone()->gcWeakMapList().insertFront(this); marked = JS::IsIncrementalGCInProgress(TlsContext.get()); - return true; } // Trace a WeakMap entry based on 'markedCell' getting marked, where 'origKey' @@ -80,9 +72,6 @@ WeakMap::trace(JSTracer* trc) TraceNullableEdge(trc, &memberOf, "WeakMap owner"); - if (!Base::initialized()) - return; - if (trc->isMarkingTracer()) { MOZ_ASSERT(trc->weakMapAction() == ExpandWeakMaps); marked = true; diff --git a/js/src/gc/WeakMap.cpp b/js/src/gc/WeakMap.cpp index c40a969bae8d..340a0e2f5b2c 100644 --- a/js/src/gc/WeakMap.cpp +++ b/js/src/gc/WeakMap.cpp @@ -81,8 +81,7 @@ WeakMapBase::sweepZone(JS::Zone* zone) if (m->marked) { m->sweep(); } else { - /* Destroy the hash map now to catch any use after this point. */ - m->finish(); + m->clearAndCompact(); m->removeFrom(zone->gcWeakMapList()); } m = next; @@ -157,16 +156,9 @@ ObjectWeakMap::ObjectWeakMap(JSContext* cx) : map(cx, nullptr) {} -bool -ObjectWeakMap::init() -{ - return map.init(); -} - JSObject* ObjectWeakMap::lookup(const JSObject* obj) { - MOZ_ASSERT(map.initialized()); if (ObjectValueMap::Ptr p = map.lookup(const_cast(obj))) return &p->value().toObject(); return nullptr; @@ -176,7 +168,6 @@ bool ObjectWeakMap::add(JSContext* cx, JSObject* obj, JSObject* target) { MOZ_ASSERT(obj && target); - MOZ_ASSERT(map.initialized()); MOZ_ASSERT(!map.has(obj)); if (!map.put(obj, ObjectValue(*target))) { @@ -190,7 +181,6 @@ ObjectWeakMap::add(JSContext* cx, JSObject* obj, JSObject* target) void ObjectWeakMap::clear() { - MOZ_ASSERT(map.initialized()); map.clear(); } @@ -203,7 +193,6 @@ ObjectWeakMap::trace(JSTracer* trc) size_t ObjectWeakMap::sizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf) { - MOZ_ASSERT(map.initialized()); return map.shallowSizeOfExcludingThis(mallocSizeOf); } @@ -211,7 +200,6 @@ ObjectWeakMap::sizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf) void ObjectWeakMap::checkAfterMovingGC() { - MOZ_ASSERT(map.initialized()); for (ObjectValueMap::Range r = map.all(); !r.empty(); r.popFront()) { CheckGCThingAfterMovingGC(r.front().key().get()); CheckGCThingAfterMovingGC(&r.front().value().toObject()); diff --git a/js/src/gc/WeakMap.h b/js/src/gc/WeakMap.h index b8afa65725b7..5d6e289d0394 100644 --- a/js/src/gc/WeakMap.h +++ b/js/src/gc/WeakMap.h @@ -92,7 +92,7 @@ class WeakMapBase : public mozilla::LinkedListElement virtual bool findZoneEdges() = 0; virtual void sweep() = 0; virtual void traceMappings(WeakMapTracer* tracer) = 0; - virtual void finish() = 0; + virtual void clearAndCompact() = 0; // Any weakmap key types that want to participate in the non-iterative // ephemeron marking must override this method. @@ -127,8 +127,6 @@ class WeakMap : public HashMap, explicit WeakMap(JSContext* cx, JSObject* memOf = nullptr); - bool init(uint32_t len = 16); - // Overwritten to add a read barrier to prevent an incorrectly gray value // from escaping the weak map. See the UnmarkGrayTracer::onChild comment in // gc/Marking.cpp. @@ -139,7 +137,7 @@ class WeakMap : public HashMap, return p; } - AddPtr lookupForAdd(const Lookup& l) const { + AddPtr lookupForAdd(const Lookup& l) { AddPtr p = Base::lookupForAdd(l); if (p) exposeGCThingToActiveJS(p->value()); @@ -178,8 +176,9 @@ class WeakMap : public HashMap, void sweep() override; - void finish() override { - Base::finish(); + void clearAndCompact() override { + Base::clear(); + Base::compact(); } /* memberOf can be nullptr, which means that the map is not part of a JSObject. */ @@ -212,7 +211,6 @@ class ObjectWeakMap public: explicit ObjectWeakMap(JSContext* cx); - bool init(); JS::Zone* zone() const { return map.zone(); } diff --git a/js/src/gc/WeakMapPtr.cpp b/js/src/gc/WeakMapPtr.cpp index 5421a66d22e4..f6e8b8ae7c7b 100644 --- a/js/src/gc/WeakMapPtr.cpp +++ b/js/src/gc/WeakMapPtr.cpp @@ -66,7 +66,7 @@ JS::WeakMapPtr::init(JSContext* cx) MOZ_ASSERT(!initialized()); typename WeakMapDetails::Utils::PtrType map = cx->new_::Type>(cx); - if (!map || !map->init()) + if (!map) return false; ptr = map; return true; diff --git a/js/src/gc/Zone.cpp b/js/src/gc/Zone.cpp index 24c1b2cf47b4..7c9dbc3b1859 100644 --- a/js/src/gc/Zone.cpp +++ b/js/src/gc/Zone.cpp @@ -105,13 +105,7 @@ bool Zone::init(bool isSystemArg) { isSystem = isSystemArg; - return uniqueIds().init() && - gcSweepGroupEdges().init() && - gcWeakKeys().init() && - typeDescrObjects().init() && - markedAtoms().init() && - atomCache().init() && - regExps.init(); + return gcWeakKeys().init(); } void @@ -288,7 +282,7 @@ Zone::createJitZone(JSContext* cx) return nullptr; UniquePtr jitZone(cx->new_()); - if (!jitZone || !jitZone->init(cx)) + if (!jitZone) return nullptr; jitZone_ = jitZone.release(); @@ -364,10 +358,8 @@ Zone::clearTables() { MOZ_ASSERT(regExps.empty()); - if (baseShapes().initialized()) - baseShapes().clear(); - if (initialShapes().initialized()) - initialShapes().clear(); + baseShapes().clear(); + initialShapes().clear(); } void @@ -453,7 +445,7 @@ Zone::purgeAtomCache() MOZ_ASSERT(!hasKeptAtoms()); MOZ_ASSERT(!purgeAtomsDeferred); - atomCache().clearAndShrink(); + atomCache().clearAndCompact(); // Also purge the dtoa caches so that subsequent lookups populate atom // cache too. diff --git a/js/src/jit/CodeGenerator.cpp b/js/src/jit/CodeGenerator.cpp index 8a0d83e44025..18f21d18d372 100644 --- a/js/src/jit/CodeGenerator.cpp +++ b/js/src/jit/CodeGenerator.cpp @@ -10217,9 +10217,6 @@ CodeGenerator::generate() if (!addNativeToBytecodeEntry(startSite)) return false; - if (!snapshots_.init()) - return false; - if (!safepoints_.init(gen->alloc())) return false; diff --git a/js/src/jit/ExecutableAllocator.cpp b/js/src/jit/ExecutableAllocator.cpp index 50d32d922b50..d78ce8358592 100644 --- a/js/src/jit/ExecutableAllocator.cpp +++ b/js/src/jit/ExecutableAllocator.cpp @@ -99,8 +99,7 @@ ExecutableAllocator::~ExecutableAllocator() m_smallPools[i]->release(/* willDestroy = */true); // If this asserts we have a pool leak. - MOZ_ASSERT_IF((m_pools.initialized() && - TlsContext.get()->runtime()->gc.shutdownCollectedEverything()), + MOZ_ASSERT_IF(TlsContext.get()->runtime()->gc.shutdownCollectedEverything(), m_pools.empty()); } @@ -180,9 +179,6 @@ ExecutableAllocator::createPool(size_t n) if (allocSize == OVERSIZE_ALLOCATION) return nullptr; - if (!m_pools.initialized() && !m_pools.init()) - return nullptr; - ExecutablePool::Allocation a = systemAlloc(allocSize); if (!a.pages) return nullptr; @@ -235,8 +231,6 @@ ExecutableAllocator::releasePoolPages(ExecutablePool* pool) MOZ_ASSERT(pool->m_allocation.pages); systemRelease(pool->m_allocation); - MOZ_ASSERT(m_pools.initialized()); - // Pool may not be present in m_pools if we hit OOM during creation. if (auto ptr = m_pools.lookup(pool)) m_pools.remove(ptr); @@ -263,15 +257,13 @@ ExecutableAllocator::purge() void ExecutableAllocator::addSizeOfCode(JS::CodeSizes* sizes) const { - if (m_pools.initialized()) { - for (ExecPoolHashSet::Range r = m_pools.all(); !r.empty(); r.popFront()) { - ExecutablePool* pool = r.front(); - sizes->ion += pool->m_codeBytes[CodeKind::Ion]; - sizes->baseline += pool->m_codeBytes[CodeKind::Baseline]; - sizes->regexp += pool->m_codeBytes[CodeKind::RegExp]; - sizes->other += pool->m_codeBytes[CodeKind::Other]; - sizes->unused += pool->m_allocation.size - pool->usedCodeBytes(); - } + for (ExecPoolHashSet::Range r = m_pools.all(); !r.empty(); r.popFront()) { + ExecutablePool* pool = r.front(); + sizes->ion += pool->m_codeBytes[CodeKind::Ion]; + sizes->baseline += pool->m_codeBytes[CodeKind::Baseline]; + sizes->regexp += pool->m_codeBytes[CodeKind::RegExp]; + sizes->other += pool->m_codeBytes[CodeKind::Other]; + sizes->unused += pool->m_allocation.size - pool->usedCodeBytes(); } } diff --git a/js/src/jit/Ion.cpp b/js/src/jit/Ion.cpp index 48f2eca6bcb3..eb91637dfa5d 100644 --- a/js/src/jit/Ion.cpp +++ b/js/src/jit/Ion.cpp @@ -221,7 +221,7 @@ JitRuntime::initialize(JSContext* cx) JitContext jctx(cx, nullptr); functionWrappers_ = cx->new_(cx); - if (!functionWrappers_ || !functionWrappers_->init()) + if (!functionWrappers_) return false; StackMacroAssembler masm; @@ -410,11 +410,6 @@ JitRealm::initialize(JSContext* cx) if (!stubCodes_) return false; - if (!stubCodes_->init()) { - ReportOutOfMemory(cx); - return false; - } - stringsCanBeInNursery = cx->nursery().canAllocateStrings(); return true; @@ -443,17 +438,6 @@ JitRealm::performStubReadBarriers(uint32_t stubsToBarrier) const } } -bool -JitZone::init(JSContext* cx) -{ - if (!baselineCacheIRStubCodes_.init()) { - ReportOutOfMemory(cx); - return false; - } - - return true; -} - void jit::FreeIonBuilder(IonBuilder* builder) { @@ -686,7 +670,6 @@ TrampolinePtr JitRuntime::getVMWrapper(const VMFunction& f) const { MOZ_ASSERT(functionWrappers_); - MOZ_ASSERT(functionWrappers_->initialized()); MOZ_ASSERT(trampolineCode_); JitRuntime::VMWrapperMap::Ptr p = functionWrappers_->readonlyThreadsafeLookup(&f); @@ -1483,8 +1466,6 @@ OptimizeMIR(MIRGenerator* mir) } ValueNumberer gvn(mir, graph); - if (!gvn.init()) - return false; // Alias analysis is required for LICM and GVN so that we don't move // loads across stores. diff --git a/js/src/jit/IonAnalysis.cpp b/js/src/jit/IonAnalysis.cpp index fd895463f9df..4b91dfbd4224 100644 --- a/js/src/jit/IonAnalysis.cpp +++ b/js/src/jit/IonAnalysis.cpp @@ -3581,9 +3581,6 @@ jit::EliminateRedundantChecks(MIRGraph& graph) { BoundsCheckMap checks(graph.alloc()); - if (!checks.init()) - return false; - // Stack for pre-order CFG traversal. Vector worklist(graph.alloc()); diff --git a/js/src/jit/JitRealm.h b/js/src/jit/JitRealm.h index fb859bf8f729..f581acf70e0d 100644 --- a/js/src/jit/JitRealm.h +++ b/js/src/jit/JitRealm.h @@ -398,7 +398,6 @@ class JitZone BaselineCacheIRStubCodeMap baselineCacheIRStubCodes_; public: - MOZ_MUST_USE bool init(JSContext* cx); void sweep(); void addSizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf, @@ -433,22 +432,18 @@ class JitZone } CacheIRStubInfo* getIonCacheIRStubInfo(const CacheIRStubKey::Lookup& key) { - if (!ionCacheIRStubInfoSet_.initialized()) - return nullptr; IonCacheIRStubInfoSet::Ptr p = ionCacheIRStubInfoSet_.lookup(key); return p ? p->stubInfo.get() : nullptr; } MOZ_MUST_USE bool putIonCacheIRStubInfo(const CacheIRStubKey::Lookup& lookup, CacheIRStubKey& key) { - if (!ionCacheIRStubInfoSet_.initialized() && !ionCacheIRStubInfoSet_.init()) - return false; IonCacheIRStubInfoSet::AddPtr p = ionCacheIRStubInfoSet_.lookupForAdd(lookup); MOZ_ASSERT(!p); return ionCacheIRStubInfoSet_.add(p, std::move(key)); } void purgeIonCacheIRStubInfo() { - ionCacheIRStubInfoSet_.finish(); + ionCacheIRStubInfoSet_.clearAndCompact(); } }; diff --git a/js/src/jit/LIR.cpp b/js/src/jit/LIR.cpp index b2cc148d2359..2a3aea2e6e7e 100644 --- a/js/src/jit/LIR.cpp +++ b/js/src/jit/LIR.cpp @@ -37,8 +37,6 @@ LIRGraph::LIRGraph(MIRGraph* mir) bool LIRGraph::addConstantToPool(const Value& v, uint32_t* index) { - MOZ_ASSERT(constantPoolMap_.initialized()); - ConstantPoolMap::AddPtr p = constantPoolMap_.lookupForAdd(v); if (p) { *index = p->value(); diff --git a/js/src/jit/LIR.h b/js/src/jit/LIR.h index 8703fb36ea01..04c03473d130 100644 --- a/js/src/jit/LIR.h +++ b/js/src/jit/LIR.h @@ -1898,7 +1898,7 @@ class LIRGraph explicit LIRGraph(MIRGraph* mir); MOZ_MUST_USE bool init() { - return constantPoolMap_.init() && blocks_.init(mir_.alloc(), mir_.numBlocks()); + return blocks_.init(mir_.alloc(), mir_.numBlocks()); } MIRGraph& mir() const { return mir_; diff --git a/js/src/jit/LoopUnroller.cpp b/js/src/jit/LoopUnroller.cpp index 383a1f657224..c1394b117b0c 100644 --- a/js/src/jit/LoopUnroller.cpp +++ b/js/src/jit/LoopUnroller.cpp @@ -250,9 +250,6 @@ LoopUnroller::go(LoopIterationBound* bound) graph.insertBlockAfter(unrolledBackedge, newPreheader); graph.renumberBlocksAfter(oldPreheader); - if (!unrolledDefinitions.init()) - return false; - // Add phis to the unrolled loop header which correspond to the phis in the // original loop header. MOZ_ASSERT(header->getPredecessor(0) == oldPreheader); diff --git a/js/src/jit/OptimizationTracking.cpp b/js/src/jit/OptimizationTracking.cpp index f68d14183372..9261434f8f5b 100644 --- a/js/src/jit/OptimizationTracking.cpp +++ b/js/src/jit/OptimizationTracking.cpp @@ -373,7 +373,6 @@ class jit::UniqueTrackedTypes list_(cx) { } - bool init() { return map_.init(); } bool getIndexOf(TypeSet::Type ty, uint8_t* indexp); uint32_t count() const { MOZ_ASSERT(map_.count() == list_.length()); return list_.length(); } @@ -965,8 +964,6 @@ jit::WriteIonTrackedOptimizationsTable(JSContext* cx, CompactBufferWriter& write // Write out type info payloads. UniqueTrackedTypes uniqueTypes(cx); - if (!uniqueTypes.init()) - return false; for (const UniqueTrackedOptimizations::SortEntry* p = vec.begin(); p != vec.end(); p++) { const TempOptimizationTypeInfoVector* v = p->types; diff --git a/js/src/jit/OptimizationTracking.h b/js/src/jit/OptimizationTracking.h index 8feb06e10885..48c77fb69f09 100644 --- a/js/src/jit/OptimizationTracking.h +++ b/js/src/jit/OptimizationTracking.h @@ -182,7 +182,6 @@ class UniqueTrackedOptimizations sorted_(cx) { } - MOZ_MUST_USE bool init() { return map_.init(); } MOZ_MUST_USE bool add(const TrackedOptimizations* optimizations); MOZ_MUST_USE bool sortByFrequency(JSContext* cx); diff --git a/js/src/jit/RegisterAllocator.cpp b/js/src/jit/RegisterAllocator.cpp index 0ed1480fe9cd..36fa07fd8ee6 100644 --- a/js/src/jit/RegisterAllocator.cpp +++ b/js/src/jit/RegisterAllocator.cpp @@ -75,7 +75,7 @@ AllocationIntegrityState::record() } } - return seen.init(); + return true; } bool diff --git a/js/src/jit/Snapshots.cpp b/js/src/jit/Snapshots.cpp index 47dd04e3fea5..d2b5d6413f02 100644 --- a/js/src/jit/Snapshots.cpp +++ b/js/src/jit/Snapshots.cpp @@ -547,14 +547,12 @@ SnapshotReader::readAllocation() return RValueAllocation::read(allocReader_); } -bool -SnapshotWriter::init() -{ - // Based on the measurements made in Bug 962555 comment 20, this should be - // enough to prevent the reallocation of the hash table for at least half of - // the compilations. - return allocMap_.init(32); -} +SnapshotWriter::SnapshotWriter() + // Based on the measurements made in Bug 962555 comment 20, this length + // should be enough to prevent the reallocation of the hash table for at + // least half of the compilations. + : allocMap_(32) +{} RecoverReader::RecoverReader(SnapshotReader& snapshot, const uint8_t* recovers, uint32_t size) : reader_(nullptr, nullptr), @@ -647,8 +645,6 @@ SnapshotWriter::trackSnapshot(uint32_t pcOpcode, uint32_t mirOpcode, uint32_t mi bool SnapshotWriter::add(const RValueAllocation& alloc) { - MOZ_ASSERT(allocMap_.initialized()); - uint32_t offset; RValueAllocMap::AddPtr p = allocMap_.lookupForAdd(alloc); if (!p) { diff --git a/js/src/jit/Snapshots.h b/js/src/jit/Snapshots.h index f5948d058df0..263da3fda3d6 100644 --- a/js/src/jit/Snapshots.h +++ b/js/src/jit/Snapshots.h @@ -400,7 +400,7 @@ class SnapshotWriter SnapshotOffset lastStart_; public: - MOZ_MUST_USE bool init(); + SnapshotWriter(); SnapshotOffset startSnapshot(RecoverOffset recoverOffset, BailoutKind kind); #ifdef TRACK_SNAPSHOTS diff --git a/js/src/jit/ValueNumbering.cpp b/js/src/jit/ValueNumbering.cpp index 9a2f96541c08..9f2a075b4c89 100644 --- a/js/src/jit/ValueNumbering.cpp +++ b/js/src/jit/ValueNumbering.cpp @@ -78,13 +78,6 @@ ValueNumberer::VisibleValues::VisibleValues(TempAllocator& alloc) : set_(alloc) {} -// Initialize the set. -bool -ValueNumberer::VisibleValues::init() -{ - return set_.init(); -} - // Look up the first entry for |def|. ValueNumberer::VisibleValues::Ptr ValueNumberer::VisibleValues::findLeader(const MDefinition* def) const @@ -1208,6 +1201,12 @@ bool ValueNumberer::cleanupOSRFixups() ValueNumberer::ValueNumberer(MIRGenerator* mir, MIRGraph& graph) : mir_(mir), graph_(graph), + // Initialize the value set. It's tempting to pass in a length that is a + // function of graph_.getNumInstructionIds(). But if we start out with a + // large capacity, it will be far larger than the actual element count for + // most of the pass, so when we remove elements, it would often think it + // needs to compact itself. Empirically, just letting the HashTable grow as + // needed on its own seems to work pretty well. values_(graph.alloc()), deadDefs_(graph.alloc()), remainingBlocks_(graph.alloc()), @@ -1220,18 +1219,6 @@ ValueNumberer::ValueNumberer(MIRGenerator* mir, MIRGraph& graph) hasOSRFixups_(false) {} -bool -ValueNumberer::init() -{ - // Initialize the value set. It's tempting to pass in a size here of some - // function of graph_.getNumInstructionIds(), however if we start out with a - // large capacity, it will be far larger than the actual element count for - // most of the pass, so when we remove elements, it would often think it - // needs to compact itself. Empirically, just letting the HashTable grow as - // needed on its own seems to work pretty well. - return values_.init(); -} - bool ValueNumberer::run(UpdateAliasAnalysisFlag updateAliasAnalysis) { diff --git a/js/src/jit/ValueNumbering.h b/js/src/jit/ValueNumbering.h index a4e71f53c2de..927cbf676ff8 100644 --- a/js/src/jit/ValueNumbering.h +++ b/js/src/jit/ValueNumbering.h @@ -41,7 +41,6 @@ class ValueNumberer public: explicit VisibleValues(TempAllocator& alloc); - MOZ_MUST_USE bool init(); typedef ValueSet::Ptr Ptr; typedef ValueSet::AddPtr AddPtr; @@ -108,7 +107,6 @@ class ValueNumberer public: ValueNumberer(MIRGenerator* mir, MIRGraph& graph); - MOZ_MUST_USE bool init(); enum UpdateAliasAnalysisFlag { DontUpdateAliasAnalysis, diff --git a/js/src/jit/WasmBCE.cpp b/js/src/jit/WasmBCE.cpp index 7ee72cb435d7..864c2c2cee25 100644 --- a/js/src/jit/WasmBCE.cpp +++ b/js/src/jit/WasmBCE.cpp @@ -31,8 +31,6 @@ jit::EliminateBoundsChecks(MIRGenerator* mir, MIRGraph& graph) { // Map for dominating block where a given definition was checked LastSeenMap lastSeen; - if (!lastSeen.init()) - return false; for (ReversePostorderIterator bIter(graph.rpoBegin()); bIter != graph.rpoEnd(); bIter++) { MBasicBlock* block = *bIter; diff --git a/js/src/jit/arm/Simulator-arm.cpp b/js/src/jit/arm/Simulator-arm.cpp index cdd212611d30..3c875c766910 100644 --- a/js/src/jit/arm/Simulator-arm.cpp +++ b/js/src/jit/arm/Simulator-arm.cpp @@ -1282,7 +1282,10 @@ Simulator::~Simulator() SimulatorProcess::SimulatorProcess() : cacheLock_(mutexid::SimulatorCacheLock) , redirection_(nullptr) -{} +{ + if (getenv("ARM_SIM_ICACHE_CHECKS")) + ICacheCheckingDisableCount = 0; +} SimulatorProcess::~SimulatorProcess() { @@ -1294,15 +1297,6 @@ SimulatorProcess::~SimulatorProcess() } } -bool -SimulatorProcess::init() -{ - if (getenv("ARM_SIM_ICACHE_CHECKS")) - ICacheCheckingDisableCount = 0; - - return icache_.init(); -} - /* static */ void* Simulator::RedirectNativeFunction(void* nativeFunction, ABIFunctionType type) { diff --git a/js/src/jit/arm/Simulator-arm.h b/js/src/jit/arm/Simulator-arm.h index 66fbf1d0708a..021083c92ca6 100644 --- a/js/src/jit/arm/Simulator-arm.h +++ b/js/src/jit/arm/Simulator-arm.h @@ -487,7 +487,7 @@ class SimulatorProcess static bool initialize() { singleton_ = js_new(); - return singleton_ && singleton_->init(); + return singleton_; } static void destroy() { js_delete(singleton_); @@ -498,8 +498,6 @@ class SimulatorProcess ~SimulatorProcess(); private: - bool init(); - static SimulatorProcess* singleton_; // This lock creates a critical section around 'redirection_' and diff --git a/js/src/jit/arm/Trampoline-arm.cpp b/js/src/jit/arm/Trampoline-arm.cpp index 07a79e975320..7bbdb6282d04 100644 --- a/js/src/jit/arm/Trampoline-arm.cpp +++ b/js/src/jit/arm/Trampoline-arm.cpp @@ -716,7 +716,6 @@ bool JitRuntime::generateVMWrapper(JSContext* cx, MacroAssembler& masm, const VMFunction& f) { MOZ_ASSERT(functionWrappers_); - MOZ_ASSERT(functionWrappers_->initialized()); uint32_t wrapperOffset = startTrampolineCode(masm); diff --git a/js/src/jit/arm64/Trampoline-arm64.cpp b/js/src/jit/arm64/Trampoline-arm64.cpp index 56a6161f27b8..c789c6932b6a 100644 --- a/js/src/jit/arm64/Trampoline-arm64.cpp +++ b/js/src/jit/arm64/Trampoline-arm64.cpp @@ -524,7 +524,6 @@ bool JitRuntime::generateVMWrapper(JSContext* cx, MacroAssembler& masm, const VMFunction& f) { MOZ_ASSERT(functionWrappers_); - MOZ_ASSERT(functionWrappers_->initialized()); uint32_t wrapperOffset = startTrampolineCode(masm); diff --git a/js/src/jit/shared/CodeGenerator-shared.cpp b/js/src/jit/shared/CodeGenerator-shared.cpp index ab61e5434062..f627bda6eaa6 100644 --- a/js/src/jit/shared/CodeGenerator-shared.cpp +++ b/js/src/jit/shared/CodeGenerator-shared.cpp @@ -880,8 +880,6 @@ CodeGeneratorShared::generateCompactTrackedOptimizationsMap(JSContext* cx, JitCo return true; UniqueTrackedOptimizations unique(cx); - if (!unique.init()) - return false; // Iterate through all entries to deduplicate their optimization attempts. for (size_t i = 0; i < trackedOptimizations_.length(); i++) { diff --git a/js/src/jit/x64/Trampoline-x64.cpp b/js/src/jit/x64/Trampoline-x64.cpp index e090add208c9..877076895168 100644 --- a/js/src/jit/x64/Trampoline-x64.cpp +++ b/js/src/jit/x64/Trampoline-x64.cpp @@ -604,7 +604,6 @@ bool JitRuntime::generateVMWrapper(JSContext* cx, MacroAssembler& masm, const VMFunction& f) { MOZ_ASSERT(functionWrappers_); - MOZ_ASSERT(functionWrappers_->initialized()); uint32_t wrapperOffset = startTrampolineCode(masm); diff --git a/js/src/jit/x86-shared/MacroAssembler-x86-shared.cpp b/js/src/jit/x86-shared/MacroAssembler-x86-shared.cpp index f63c9a71eb7a..eedb2a557ab2 100644 --- a/js/src/jit/x86-shared/MacroAssembler-x86-shared.cpp +++ b/js/src/jit/x86-shared/MacroAssembler-x86-shared.cpp @@ -139,11 +139,6 @@ MacroAssemblerX86Shared::getConstant(const typename T::Pod& value, Map& map, Vector& vec) { typedef typename Map::AddPtr AddPtr; - if (!map.initialized()) { - enoughMemory_ &= map.init(); - if (!enoughMemory_) - return nullptr; - } size_t index; if (AddPtr p = map.lookupForAdd(value)) { index = p->value(); diff --git a/js/src/jit/x86/Trampoline-x86.cpp b/js/src/jit/x86/Trampoline-x86.cpp index 68baafcf128c..a37b07c23c60 100644 --- a/js/src/jit/x86/Trampoline-x86.cpp +++ b/js/src/jit/x86/Trampoline-x86.cpp @@ -624,7 +624,6 @@ bool JitRuntime::generateVMWrapper(JSContext* cx, MacroAssembler& masm, const VMFunction& f) { MOZ_ASSERT(functionWrappers_); - MOZ_ASSERT(functionWrappers_->initialized()); uint32_t wrapperOffset = startTrampolineCode(masm); diff --git a/js/src/jsapi-tests/testBinASTReader.cpp b/js/src/jsapi-tests/testBinASTReader.cpp index d361f8442bef..ced2401bc753 100644 --- a/js/src/jsapi-tests/testBinASTReader.cpp +++ b/js/src/jsapi-tests/testBinASTReader.cpp @@ -166,8 +166,6 @@ runTestFromPath(JSContext* cx, const char* path) txtOptions.setFileAndLine(txtPath.begin(), 0); UsedNameTracker txtUsedNames(cx); - if (!txtUsedNames.init()) - MOZ_CRASH("Couldn't initialize used names"); RootedScriptSourceObject sourceObject(cx, frontend::CreateScriptSourceObject( cx, txtOptions, mozilla::Nothing())); @@ -206,8 +204,6 @@ runTestFromPath(JSContext* cx, const char* path) binOptions.setFileAndLine(binPath.begin(), 0); js::frontend::UsedNameTracker binUsedNames(cx); - if (!binUsedNames.init()) - MOZ_CRASH("Couldn't initialized binUsedNames"); js::frontend::BinASTParser binParser(cx, allocScope.alloc(), binUsedNames, binOptions); diff --git a/js/src/jsapi-tests/testGCExactRooting.cpp b/js/src/jsapi-tests/testGCExactRooting.cpp index f4dc23dab474..1d105f86198c 100644 --- a/js/src/jsapi-tests/testGCExactRooting.cpp +++ b/js/src/jsapi-tests/testGCExactRooting.cpp @@ -145,9 +145,7 @@ using MyHashMap = js::GCHashMap; BEGIN_TEST(testGCRootedHashMap) { - JS::Rooted map(cx, MyHashMap(cx)); - CHECK(map.init(15)); - CHECK(map.initialized()); + JS::Rooted map(cx, MyHashMap(cx, 15)); for (size_t i = 0; i < 10; ++i) { RootedObject obj(cx, JS_NewObject(cx, nullptr)); @@ -205,9 +203,7 @@ CheckMyHashMap(JSContext* cx, Handle map) BEGIN_TEST(testGCHandleHashMap) { - JS::Rooted map(cx, MyHashMap(cx)); - CHECK(map.init(15)); - CHECK(map.initialized()); + JS::Rooted map(cx, MyHashMap(cx, 15)); CHECK(FillMyHashMap(cx, &map)); diff --git a/js/src/jsapi-tests/testGCGrayMarking.cpp b/js/src/jsapi-tests/testGCGrayMarking.cpp index 56e0363f19aa..d22a998ee79b 100644 --- a/js/src/jsapi-tests/testGCGrayMarking.cpp +++ b/js/src/jsapi-tests/testGCGrayMarking.cpp @@ -344,7 +344,6 @@ TestUnassociatedWeakMaps() // Make a weakmap that's not associated with a JSObject. auto weakMap = cx->make_unique(cx); CHECK(weakMap); - CHECK(weakMap->init()); // Make sure this gets traced during GC. Rooted rootMap(cx, weakMap.get()); diff --git a/js/src/jsapi-tests/testGCMarking.cpp b/js/src/jsapi-tests/testGCMarking.cpp index 36849f94266f..0b5f46c6d932 100644 --- a/js/src/jsapi-tests/testGCMarking.cpp +++ b/js/src/jsapi-tests/testGCMarking.cpp @@ -122,7 +122,6 @@ BEGIN_TEST(testTracingIncomingCCWs) // Ensure that |TraceIncomingCCWs| finds the object wrapped by the CCW. JS::CompartmentSet compartments; - CHECK(compartments.init()); CHECK(compartments.put(global2->compartment())); void* thing = wrappee.get(); diff --git a/js/src/jsapi-tests/testGCWeakCache.cpp b/js/src/jsapi-tests/testGCWeakCache.cpp index 5f99f41a9b58..992f58415d30 100644 --- a/js/src/jsapi-tests/testGCWeakCache.cpp +++ b/js/src/jsapi-tests/testGCWeakCache.cpp @@ -32,7 +32,6 @@ BEGIN_TEST(testWeakCacheSet) SystemAllocPolicy>; using Cache = JS::WeakCache; Cache cache(JS::GetObjectZone(tenured1)); - CHECK(cache.init()); cache.put(tenured1); cache.put(tenured2); @@ -73,7 +72,6 @@ BEGIN_TEST(testWeakCacheMap) js::MovableCellHasher>>; using Cache = JS::WeakCache; Cache cache(JS::GetObjectZone(tenured1), cx); - CHECK(cache.init()); cache.put(tenured1, 1); cache.put(tenured2, 2); @@ -284,8 +282,6 @@ TestSet() TempAllocPolicy>; using Cache = JS::WeakCache; Cache cache(JS::GetObjectZone(global), cx); - CHECK(cache.init()); - CHECK(cache.initialized()); // Sweep empty cache. @@ -405,7 +401,6 @@ TestSet() CHECK(cache.has(obj4)); cache.clear(); - cache.finish(); return true; } @@ -418,8 +413,6 @@ TestMap() TempAllocPolicy>; using Cache = JS::WeakCache; Cache cache(JS::GetObjectZone(global), cx); - CHECK(cache.init()); - CHECK(cache.initialized()); // Sweep empty cache. @@ -541,7 +534,6 @@ TestMap() CHECK(cache.has(obj4)); cache.clear(); - cache.finish(); return true; } @@ -556,7 +548,6 @@ TestReplaceDyingInSet() MovableCellHasher, TempAllocPolicy>>; Cache cache(JS::GetObjectZone(global), cx); - CHECK(cache.init()); RootedObject value1(cx, JS_NewPlainObject(cx)); RootedObject value2(cx, JS_NewPlainObject(cx)); @@ -620,7 +611,6 @@ TestReplaceDyingInMap() DefaultHasher, TempAllocPolicy>>; Cache cache(JS::GetObjectZone(global), cx); - CHECK(cache.init()); RootedObject value1(cx, JS_NewPlainObject(cx)); RootedObject value2(cx, JS_NewPlainObject(cx)); @@ -687,7 +677,6 @@ TestUniqueIDLookups() MovableCellHasher, TempAllocPolicy>>; Cache cache(JS::GetObjectZone(global), cx); - CHECK(cache.init()); Rooted> liveObjects(cx); diff --git a/js/src/jsapi-tests/testHashTable.cpp b/js/src/jsapi-tests/testHashTable.cpp index f36f85e05528..50708610804d 100644 --- a/js/src/jsapi-tests/testHashTable.cpp +++ b/js/src/jsapi-tests/testHashTable.cpp @@ -143,8 +143,6 @@ template static bool SlowRekey(IntMap* m) { IntMap tmp; - if (!tmp.init()) - return false; for (auto iter = m->iter(); !iter.done(); iter.next()) { if (NewKeyFunction::shouldBeRemoved(iter.get().key())) @@ -169,8 +167,6 @@ template static bool SlowRekey(IntSet* s) { IntSet tmp; - if (!tmp.init()) - return false; for (auto iter = s->iter(); !iter.done(); iter.next()) { if (NewKeyFunction::shouldBeRemoved(iter.get())) @@ -194,8 +190,6 @@ SlowRekey(IntSet* s) { BEGIN_TEST(testHashRekeyManual) { IntMap am, bm; - CHECK(am.init()); - CHECK(bm.init()); for (size_t i = 0; i < TestIterations; ++i) { #ifdef FUZZ fprintf(stderr, "map1: %lu\n", i); @@ -216,8 +210,6 @@ BEGIN_TEST(testHashRekeyManual) } IntSet as, bs; - CHECK(as.init()); - CHECK(bs.init()); for (size_t i = 0; i < TestIterations; ++i) { #ifdef FUZZ fprintf(stderr, "set1: %lu\n", i); @@ -244,8 +236,6 @@ END_TEST(testHashRekeyManual) BEGIN_TEST(testHashRekeyManualRemoval) { IntMap am, bm; - CHECK(am.init()); - CHECK(bm.init()); for (size_t i = 0; i < TestIterations; ++i) { #ifdef FUZZ fprintf(stderr, "map2: %lu\n", i); @@ -270,8 +260,6 @@ BEGIN_TEST(testHashRekeyManualRemoval) } IntSet as, bs; - CHECK(as.init()); - CHECK(bs.init()); for (size_t i = 0; i < TestIterations; ++i) { #ifdef FUZZ fprintf(stderr, "set1: %lu\n", i); @@ -338,7 +326,6 @@ BEGIN_TEST(testHashSetOfMoveOnlyType) typedef js::HashSet Set; Set set; - CHECK(set.init()); MoveOnlyType a(1); @@ -357,9 +344,6 @@ GrowUntilResize() { IntMap m; - if (!m.init()) - return false; - // Add entries until we've resized the table four times. size_t lastCapacity = m.capacity(); size_t resizes = 0; @@ -367,7 +351,7 @@ GrowUntilResize() while (resizes < 4) { auto p = m.lookupForAdd(key); if (!p && !m.add(p, key, 0)) - return false; // OOM'd while adding + return false; // OOM'd in lookupForAdd() or add() size_t capacity = m.capacity(); if (capacity != lastCapacity) { @@ -398,7 +382,6 @@ END_TEST(testHashMapGrowOOM) BEGIN_TEST(testHashTableMovableModIterator) { IntSet set; - CHECK(set.init()); // Exercise returning a hash table ModIterator object from a function. @@ -435,3 +418,84 @@ IntSet::ModIterator setModIter(IntSet& set) } END_TEST(testHashTableMovableModIterator) + +BEGIN_TEST(testHashLazyStorage) +{ + // The following code depends on the current capacity computation, which + // could change in the future. + uint32_t defaultCap = 32; + uint32_t minCap = 4; + + IntSet set; + CHECK(set.capacity() == 0); + + CHECK(set.put(1)); + CHECK(set.capacity() == defaultCap); + + set.compact(); // effectively a no-op + CHECK(set.capacity() == minCap); + + set.clear(); + CHECK(set.capacity() == minCap); + + set.compact(); + CHECK(set.capacity() == 0); + + CHECK(set.putNew(1)); + CHECK(set.capacity() == minCap); + + set.clear(); + set.compact(); + CHECK(set.capacity() == 0); + + // lookupForAdd() instantiates, even if not followed by add(). + set.lookupForAdd(1); + CHECK(set.capacity() == minCap); + + set.clear(); + set.compact(); + CHECK(set.capacity() == 0); + + CHECK(set.reserve(0)); // a no-op + CHECK(set.capacity() == 0); + + CHECK(set.reserve(1)); + CHECK(set.capacity() == minCap); + + CHECK(set.reserve(0)); // a no-op + CHECK(set.capacity() == minCap); + + CHECK(set.reserve(2)); // effectively a no-op + CHECK(set.capacity() == minCap); + + // No need to clear here because we didn't add anything. + set.compact(); + CHECK(set.capacity() == 0); + + CHECK(set.reserve(128)); + CHECK(set.capacity() == 256); + CHECK(set.reserve(3)); // effectively a no-op + CHECK(set.capacity() == 256); + for (int i = 0; i < 8; i++) { + CHECK(set.putNew(i)); + } + CHECK(set.count() == 8); + CHECK(set.capacity() == 256); + set.compact(); + CHECK(set.capacity() == 16); + set.compact(); // effectively a no-op + CHECK(set.capacity() == 16); + for (int i = 8; i < 16; i++) { + CHECK(set.putNew(i)); + } + CHECK(set.count() == 16); + CHECK(set.capacity() == 32); + set.clear(); + CHECK(set.capacity() == 32); + set.compact(); + CHECK(set.capacity() == 0); + + return true; +} +END_TEST(testHashLazyStorage) + diff --git a/js/src/jsapi-tests/testJitMinimalFunc.h b/js/src/jsapi-tests/testJitMinimalFunc.h index a88438ce495d..34b99b5e2e69 100644 --- a/js/src/jsapi-tests/testJitMinimalFunc.h +++ b/js/src/jsapi-tests/testJitMinimalFunc.h @@ -86,8 +86,6 @@ struct MinimalFunc : MinimalAlloc if (!BuildPhiReverseMapping(graph)) return false; ValueNumberer gvn(&mir, graph); - if (!gvn.init()) - return false; if (!gvn.run(ValueNumberer::DontUpdateAliasAnalysis)) return false; return true; diff --git a/js/src/jsapi-tests/testUbiNode.cpp b/js/src/jsapi-tests/testUbiNode.cpp index 4835f5bf2fe3..25d3bb3694f3 100644 --- a/js/src/jsapi-tests/testUbiNode.cpp +++ b/js/src/jsapi-tests/testUbiNode.cpp @@ -368,7 +368,6 @@ BEGIN_TEST(test_ubiPostOrder) FakeNode g('g'); js::HashSet expectedEdges(cx); - CHECK(expectedEdges.init()); auto declareEdge = [&](FakeNode& from, FakeNode& to) { return from.addEdgeTo(to) && expectedEdges.putNew(ExpectedEdge(from, to)); @@ -395,7 +394,6 @@ BEGIN_TEST(test_ubiPostOrder) JS::AutoCheckCannotGC nogc(cx); JS::ubi::PostOrder traversal(cx, nogc); - CHECK(traversal.init()); CHECK(traversal.addStart(&r)); auto onNode = [&](const JS::ubi::Node& node) { @@ -590,7 +588,6 @@ BEGIN_TEST(test_JS_ubi_DominatorTree) fprintf(stderr, "Checking %c's dominated set:\n", node.name); js::HashSet expectedDominatedSet(cx); - CHECK(expectedDominatedSet.init()); for (auto& rel : domination) { if (&rel.dominator == &node) { fprintf(stderr, " Expecting %c\n", rel.dominated.name); @@ -714,7 +711,6 @@ BEGIN_TEST(test_JS_ubi_ShortestPaths_no_path) JS::AutoCheckCannotGC noGC(cx); JS::ubi::NodeSet targets; - CHECK(targets.init()); CHECK(targets.put(&b)); maybeShortestPaths = JS::ubi::ShortestPaths::Create(cx, noGC, 10, &a, @@ -756,7 +752,6 @@ BEGIN_TEST(test_JS_ubi_ShortestPaths_one_path) JS::AutoCheckCannotGC noGC(cx); JS::ubi::NodeSet targets; - CHECK(targets.init()); CHECK(targets.put(&b)); maybeShortestPaths = JS::ubi::ShortestPaths::Create(cx, noGC, 10, &a, @@ -823,7 +818,6 @@ BEGIN_TEST(test_JS_ubi_ShortestPaths_multiple_paths) JS::AutoCheckCannotGC noGC(cx); JS::ubi::NodeSet targets; - CHECK(targets.init()); CHECK(targets.put(&f)); maybeShortestPaths = JS::ubi::ShortestPaths::Create(cx, noGC, 10, &a, @@ -915,7 +909,6 @@ BEGIN_TEST(test_JS_ubi_ShortestPaths_more_paths_than_max) JS::AutoCheckCannotGC noGC(cx); JS::ubi::NodeSet targets; - CHECK(targets.init()); CHECK(targets.put(&f)); maybeShortestPaths = JS::ubi::ShortestPaths::Create(cx, noGC, 1, &a, @@ -965,7 +958,6 @@ BEGIN_TEST(test_JS_ubi_ShortestPaths_multiple_edges_to_target) JS::AutoCheckCannotGC noGC(cx); JS::ubi::NodeSet targets; - CHECK(targets.init()); CHECK(targets.put(&b)); maybeShortestPaths = JS::ubi::ShortestPaths::Create(cx, noGC, 10, &a, diff --git a/js/src/jsapi.cpp b/js/src/jsapi.cpp index 78839ca8400c..2365bbc4e623 100644 --- a/js/src/jsapi.cpp +++ b/js/src/jsapi.cpp @@ -4385,8 +4385,6 @@ JS_BufferIsCompilableUnit(JSContext* cx, HandleObject obj, const char* utf8, siz CompileOptions options(cx); frontend::UsedNameTracker usedNames(cx); - if (!usedNames.init()) - return false; RootedScriptSourceObject sourceObject(cx, frontend::CreateScriptSourceObject(cx, options, mozilla::Nothing())); diff --git a/js/src/proxy/ScriptedProxyHandler.cpp b/js/src/proxy/ScriptedProxyHandler.cpp index a4d6919e9be4..97dcaacd069e 100644 --- a/js/src/proxy/ScriptedProxyHandler.cpp +++ b/js/src/proxy/ScriptedProxyHandler.cpp @@ -749,9 +749,7 @@ ScriptedProxyHandler::ownPropertyKeys(JSContext* cx, HandleObject proxy, AutoIdV return false; // Steps 9, 18. - Rooted> uncheckedResultKeys(cx, GCHashSet(cx)); - if (!uncheckedResultKeys.init(trapResult.length())) - return false; + Rooted> uncheckedResultKeys(cx, GCHashSet(cx, trapResult.length())); for (size_t i = 0, len = trapResult.length(); i < len; i++) { MOZ_ASSERT(!JSID_IS_VOID(trapResult[i])); diff --git a/js/src/shell/js.cpp b/js/src/shell/js.cpp index 429a20b9c7ea..14382aec94e7 100644 --- a/js/src/shell/js.cpp +++ b/js/src/shell/js.cpp @@ -4484,8 +4484,6 @@ BinParse(JSContext* cx, unsigned argc, Value* vp) .setFileAndLine("", 1); UsedNameTracker usedNames(cx); - if (!usedNames.init()) - return false; JS::Result parsed(nullptr); if (useMultipart) { @@ -4581,8 +4579,6 @@ Parse(JSContext* cx, unsigned argc, Value* vp) .setAllowSyntaxParser(allowSyntaxParser); UsedNameTracker usedNames(cx); - if (!usedNames.init()) - return false; RootedScriptSourceObject sourceObject(cx, frontend::CreateScriptSourceObject(cx, options, Nothing())); @@ -4638,8 +4634,6 @@ SyntaxParse(JSContext* cx, unsigned argc, Value* vp) const char16_t* chars = stableChars.twoByteRange().begin().get(); size_t length = scriptContents->length(); UsedNameTracker usedNames(cx); - if (!usedNames.init()) - return false; RootedScriptSourceObject sourceObject(cx, frontend::CreateScriptSourceObject(cx, options, Nothing())); diff --git a/js/src/vm/ArrayBufferObject.cpp b/js/src/vm/ArrayBufferObject.cpp index 7b4b0094c0e3..f3c158d232d4 100644 --- a/js/src/vm/ArrayBufferObject.cpp +++ b/js/src/vm/ArrayBufferObject.cpp @@ -1500,11 +1500,6 @@ InnerViewTable::addView(JSContext* cx, ArrayBufferObject* buffer, ArrayBufferVie // ArrayBufferObject entries are only added when there are multiple views. MOZ_ASSERT(buffer->firstView()); - if (!map.initialized() && !map.init()) { - ReportOutOfMemory(cx); - return false; - } - Map::AddPtr p = map.lookupForAdd(buffer); MOZ_ASSERT(!gc::IsInsideNursery(buffer)); @@ -1553,9 +1548,6 @@ InnerViewTable::addView(JSContext* cx, ArrayBufferObject* buffer, ArrayBufferVie InnerViewTable::ViewVector* InnerViewTable::maybeViewsUnbarriered(ArrayBufferObject* buffer) { - if (!map.initialized()) - return nullptr; - Map::Ptr p = map.lookup(buffer); if (p) return &p->value(); @@ -1628,9 +1620,6 @@ InnerViewTable::sweepAfterMinorGC() size_t InnerViewTable::sizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf) { - if (!map.initialized()) - return 0; - size_t vectorSize = 0; for (Map::Enum e(map); !e.empty(); e.popFront()) vectorSize += e.front().value().sizeOfExcludingThis(mallocSizeOf); diff --git a/js/src/vm/Caches.cpp b/js/src/vm/Caches.cpp index df172a369db7..7f24a556f024 100644 --- a/js/src/vm/Caches.cpp +++ b/js/src/vm/Caches.cpp @@ -12,15 +12,6 @@ using namespace js; using mozilla::PodZero; -bool -RuntimeCaches::init() -{ - if (!evalCache.init()) - return false; - - return true; -} - void NewObjectCache::clearNurseryObjects(JSRuntime* rt) { diff --git a/js/src/vm/Caches.h b/js/src/vm/Caches.h index 6d19219d2314..5fece2c3dba8 100644 --- a/js/src/vm/Caches.h +++ b/js/src/vm/Caches.h @@ -247,8 +247,6 @@ class RuntimeCaches js::UncompressedSourceCache uncompressedSourceCache; js::EvalCache evalCache; - bool init(); - void purgeForMinorGC(JSRuntime* rt) { newObjectCache.clearNurseryObjects(rt); evalCache.sweep(); @@ -256,8 +254,7 @@ class RuntimeCaches void purgeForCompaction() { newObjectCache.purge(); - if (evalCache.initialized()) - evalCache.clear(); + evalCache.clear(); } void purge() { diff --git a/js/src/vm/CodeCoverage.cpp b/js/src/vm/CodeCoverage.cpp index 372b88e05e39..10a5602526d9 100644 --- a/js/src/vm/CodeCoverage.cpp +++ b/js/src/vm/CodeCoverage.cpp @@ -114,7 +114,7 @@ LCovSource::exportInto(GenericPrinter& out) const out.printf("BRF:%zu\n", numBranchesFound_); out.printf("BRH:%zu\n", numBranchesHit_); - if (linesHit_.initialized()) { + if (!linesHit_.empty()) { for (size_t lineno = 1; lineno <= maxLineHit_; ++lineno) { if (auto p = linesHit_.lookup(lineno)) out.printf("DA:%zu,%" PRIu64 "\n", lineno, p->value()); @@ -140,9 +140,6 @@ LCovSource::writeScriptName(LSprinter& out, JSScript* script) bool LCovSource::writeScript(JSScript* script) { - if (!linesHit_.initialized() && !linesHit_.init()) - return false; - numFunctionsFound_++; outFN_.printf("FN:%u,", script->lineno()); if (!writeScriptName(outFN_, script)) diff --git a/js/src/vm/Compartment.cpp b/js/src/vm/Compartment.cpp index 950d17ad3b29..28d56102b562 100644 --- a/js/src/vm/Compartment.cpp +++ b/js/src/vm/Compartment.cpp @@ -38,20 +38,10 @@ using namespace js::gc; Compartment::Compartment(Zone* zone) : zone_(zone), - runtime_(zone->runtimeFromAnyThread()) + runtime_(zone->runtimeFromAnyThread()), + crossCompartmentWrappers(0) {} -bool -Compartment::init(JSContext* cx) -{ - if (!crossCompartmentWrappers.init(0)) { - ReportOutOfMemory(cx); - return false; - } - - return true; -} - #ifdef JSGC_HASH_TABLE_CHECKS namespace { diff --git a/js/src/vm/Compartment.h b/js/src/vm/Compartment.h index 5e5c1a6d2d9e..eb8838d1a571 100644 --- a/js/src/vm/Compartment.h +++ b/js/src/vm/Compartment.h @@ -273,7 +273,8 @@ class WrapperMap Ptr(const InnerMap::Ptr& p, InnerMap& m) : InnerMap::Ptr(p), map(&m) {} }; - MOZ_MUST_USE bool init(uint32_t len) { return map.init(len); } + WrapperMap() {} + explicit WrapperMap(size_t aLen) : map(aLen) {} bool empty() { if (map.empty()) @@ -305,8 +306,8 @@ class WrapperMap MOZ_ASSERT(k.is() == !c); auto p = map.lookupForAdd(c); if (!p) { - InnerMap m; - if (!m.init(InitialInnerMapSize) || !map.add(p, c, std::move(m))) + InnerMap m(InitialInnerMapSize); + if (!map.add(p, c, std::move(m))) return false; } return p->value().put(k, v); @@ -436,7 +437,6 @@ class JS::Compartment public: explicit Compartment(JS::Zone* zone); - MOZ_MUST_USE bool init(JSContext* cx); void destroy(js::FreeOp* fop); MOZ_MUST_USE inline bool wrap(JSContext* cx, JS::MutableHandleValue vp); diff --git a/js/src/vm/Debugger.cpp b/js/src/vm/Debugger.cpp index d2d92e8cb0a7..670a3e929477 100644 --- a/js/src/vm/Debugger.cpp +++ b/js/src/vm/Debugger.cpp @@ -697,11 +697,13 @@ Debugger::Debugger(JSContext* cx, NativeObject* dbg) &traceLoggerScriptedCallsLastDrainedSize); } #endif + + cx->runtime()->debuggerList().insertBack(this); } Debugger::~Debugger() { - MOZ_ASSERT_IF(debuggees.initialized(), debuggees.empty()); + MOZ_ASSERT(debuggees.empty()); allocationsLog.clear(); // We don't have to worry about locking here since Debugger is not @@ -715,29 +717,6 @@ Debugger::~Debugger() } } -bool -Debugger::init(JSContext* cx) -{ - if (!debuggees.init() || - !debuggeeZones.init() || - !frames.init() || - !scripts.init() || - !lazyScripts.init() || - !sources.init() || - !objects.init() || - !observedGCs.init() || - !environments.init() || - !wasmInstanceScripts.init() || - !wasmInstanceSources.init()) - { - ReportOutOfMemory(cx); - return false; - } - - cx->runtime()->debuggerList().insertBack(this); - return true; -} - JS_STATIC_ASSERT(unsigned(JSSLOT_DEBUGFRAME_OWNER) == unsigned(JSSLOT_DEBUGSCRIPT_OWNER)); JS_STATIC_ASSERT(unsigned(JSSLOT_DEBUGFRAME_OWNER) == unsigned(JSSLOT_DEBUGSOURCE_OWNER)); JS_STATIC_ASSERT(unsigned(JSSLOT_DEBUGFRAME_OWNER) == unsigned(JSSLOT_DEBUGOBJECT_OWNER)); @@ -2395,7 +2374,6 @@ class MOZ_RAII ExecutionObservableRealms : public Debugger::ExecutionObservableS MOZ_GUARD_OBJECT_NOTIFIER_INIT; } - bool init() { return realms_.init() && zones_.init(); } bool add(Realm* realm) { return realms_.put(realm) && zones_.put(realm->zone()); } using RealmRange = HashSet::Range; @@ -2760,7 +2738,7 @@ Debugger::ensureExecutionObservabilityOfRealm(JSContext* cx, Realm* realm) if (realm->debuggerObservesAllExecution()) return true; ExecutionObservableRealms obs(cx); - if (!obs.init() || !obs.add(realm)) + if (!obs.add(realm)) return false; realm->updateDebuggerObservesAllExecution(); return updateExecutionObservability(cx, obs, Observing); @@ -2811,8 +2789,6 @@ bool Debugger::updateObservesAllExecutionOnDebuggees(JSContext* cx, IsObserving observing) { ExecutionObservableRealms obs(cx); - if (!obs.init()) - return false; for (WeakGlobalObjectSet::Range r = debuggees.all(); !r.empty(); r.popFront()) { GlobalObject* global = r.front(); @@ -2841,8 +2817,6 @@ bool Debugger::updateObservesCoverageOnDebuggees(JSContext* cx, IsObserving observing) { ExecutionObservableRealms obs(cx); - if (!obs.init()) - return false; for (WeakGlobalObjectSet::Range r = debuggees.all(); !r.empty(); r.popFront()) { GlobalObject* global = r.front(); @@ -3195,12 +3169,10 @@ Debugger::trace(JSTracer* trc) // (Once we support generator frames properly, we will need // weakly-referenced Debugger.Frame objects as well, for suspended generator // frames.) - if (frames.initialized()) { - for (FrameMap::Range r = frames.all(); !r.empty(); r.popFront()) { - HeapPtr& frameobj = r.front().value(); - TraceEdge(trc, &frameobj, "live Debugger.Frame"); - MOZ_ASSERT(frameobj->getPrivate(frameobj->numFixedSlotsMaybeForwarded())); - } + for (FrameMap::Range r = frames.all(); !r.empty(); r.popFront()) { + HeapPtr& frameobj = r.front().value(); + TraceEdge(trc, &frameobj, "live Debugger.Frame"); + MOZ_ASSERT(frameobj->getPrivate(frameobj->numFixedSlotsMaybeForwarded())); } allocationsLog.trace(trc); @@ -3778,8 +3750,6 @@ Debugger::removeDebuggee(JSContext* cx, unsigned argc, Value* vp) return false; ExecutionObservableRealms obs(cx); - if (!obs.init()) - return false; if (dbg->debuggees.has(global)) { dbg->removeDebuggeeGlobal(cx->runtime()->defaultFreeOp(), global, nullptr); @@ -3803,8 +3773,6 @@ Debugger::removeAllDebuggees(JSContext* cx, unsigned argc, Value* vp) THIS_DEBUGGER(cx, argc, vp, "removeAllDebuggees", args, dbg); ExecutionObservableRealms obs(cx); - if (!obs.init()) - return false; for (WeakGlobalObjectSet::Enum e(dbg->debuggees); !e.empty(); e.popFront()) { Rooted global(cx, e.front()); @@ -3940,7 +3908,7 @@ Debugger::construct(JSContext* cx, unsigned argc, Value* vp) { // Construct the underlying C++ object. auto dbg = cx->make_unique(cx, obj.get()); - if (!dbg || !dbg->init(cx)) + if (!dbg) return false; debugger = dbg.release(); @@ -4227,21 +4195,6 @@ class MOZ_STACK_CLASS Debugger::ScriptQuery oom(false) {} - /* - * Initialize this ScriptQuery. Raise an error and return false if we - * haven't enough memory. - */ - bool init() { - if (!realms.init() || - !innermostForRealm.init()) - { - ReportOutOfMemory(cx); - return false; - } - - return true; - } - /* * Parse the query object |query|, and prepare to match only the scripts * it specifies. @@ -4741,8 +4694,6 @@ Debugger::findScripts(JSContext* cx, unsigned argc, Value* vp) } ScriptQuery query(cx, dbg); - if (!query.init()) - return false; if (args.length() >= 1) { RootedObject queryObject(cx, NonNullObject(cx, args[0])); @@ -4846,11 +4797,6 @@ class MOZ_STACK_CLASS Debugger::ObjectQuery if (!prepareQuery()) return false; - if (!debuggeeCompartments.init()) { - ReportOutOfMemory(cx); - return false; - } - for (WeakGlobalObjectSet::Range r = dbg->allDebuggees(); !r.empty(); r.popFront()) { if (!debuggeeCompartments.put(r.front()->compartment())) { ReportOutOfMemory(cx); @@ -4870,10 +4816,6 @@ class MOZ_STACK_CLASS Debugger::ObjectQuery } Traversal traversal(cx, *this, maybeNoGC.ref()); - if (!traversal.init()) { - ReportOutOfMemory(cx); - return false; - } traversal.wantNames = false; return traversal.addStart(JS::ubi::Node(&rootList)) && @@ -5104,8 +5046,6 @@ Debugger::isCompilableUnit(JSContext* cx, unsigned argc, Value* vp) CompileOptions options(cx); frontend::UsedNameTracker usedNames(cx); - if (!usedNames.init()) - return false; RootedScriptSourceObject sourceObject(cx, frontend::CreateScriptSourceObject(cx, options, Nothing())); diff --git a/js/src/vm/Debugger.h b/js/src/vm/Debugger.h index bd0d2211f27d..df5bfc205730 100644 --- a/js/src/vm/Debugger.h +++ b/js/src/vm/Debugger.h @@ -165,10 +165,6 @@ class DebuggerWeakMap : private WeakMap, HeapPtr bool relookupOrAdd(AddPtr& p, const KeyInput& k, const ValueInput& v) { MOZ_ASSERT(v->compartment() == this->compartment); @@ -881,7 +877,6 @@ class Debugger : private mozilla::LinkedListElement Debugger(JSContext* cx, NativeObject* dbg); ~Debugger(); - MOZ_MUST_USE bool init(JSContext* cx); inline const js::GCPtrNativeObject& toJSObject() const; inline js::GCPtrNativeObject& toJSObjectRef(); static inline Debugger* fromJSObject(const JSObject* obj); diff --git a/js/src/vm/DebuggerMemory.cpp b/js/src/vm/DebuggerMemory.cpp index 7dc8a42b8313..b63a8b635b89 100644 --- a/js/src/vm/DebuggerMemory.cpp +++ b/js/src/vm/DebuggerMemory.cpp @@ -383,8 +383,6 @@ DebuggerMemory::takeCensus(JSContext* cx, unsigned argc, Value* vp) #endif Census census(cx); - if (!census.init()) - return false; CountTypePtr rootType; RootedObject options(cx); @@ -417,10 +415,6 @@ DebuggerMemory::takeCensus(JSContext* cx, unsigned argc, Value* vp) } JS::ubi::CensusTraversal traversal(cx, handler, maybeNoGC.ref()); - if (!traversal.init()) { - ReportOutOfMemory(cx); - return false; - } traversal.wantNames = false; if (!traversal.addStart(JS::ubi::Node(&rootList)) || diff --git a/js/src/vm/EnvironmentObject.cpp b/js/src/vm/EnvironmentObject.cpp index cbf4ed248d61..cbe1ad1b8777 100644 --- a/js/src/vm/EnvironmentObject.cpp +++ b/js/src/vm/EnvironmentObject.cpp @@ -58,8 +58,7 @@ void EnvironmentCoordinateNameCache::purge() { shape = nullptr; - if (map.initialized()) - map.finish(); + map.clearAndCompact(); } PropertyName* @@ -69,14 +68,11 @@ js::EnvironmentCoordinateName(EnvironmentCoordinateNameCache& cache, JSScript* s Shape* shape = EnvironmentCoordinateToEnvironmentShape(script, pc); if (shape != cache.shape && shape->slot() >= ENV_COORDINATE_NAME_THRESHOLD) { cache.purge(); - if (cache.map.init(shape->slot())) { + if (cache.map.reserve(shape->slot())) { cache.shape = shape; Shape::Range r(shape); while (!r.empty()) { - if (!cache.map.putNew(r.front().slot(), r.front().propid())) { - cache.purge(); - break; - } + cache.map.putNewInfallible(r.front().slot(), r.front().propid()); r.popFront(); } } @@ -2414,13 +2410,7 @@ DebugEnvironments::DebugEnvironments(JSContext* cx, Zone* zone) DebugEnvironments::~DebugEnvironments() { - MOZ_ASSERT_IF(missingEnvs.initialized(), missingEnvs.empty()); -} - -bool -DebugEnvironments::init() -{ - return proxiedEnvs.init() && missingEnvs.init() && liveEnvs.init(); + MOZ_ASSERT(missingEnvs.empty()); } void @@ -2525,11 +2515,6 @@ DebugEnvironments::ensureRealmData(JSContext* cx) if (!debugEnvs) return nullptr; - if (!debugEnvs->init()) { - ReportOutOfMemory(cx); - return nullptr; - } - realm->debugEnvsRef() = std::move(debugEnvs); return realm->debugEnvs(); } @@ -3687,8 +3672,6 @@ static bool AnalyzeEntrainedVariablesInScript(JSContext* cx, HandleScript script, HandleScript innerScript) { PropertyNameSet remainingNames(cx); - if (!remainingNames.init()) - return false; for (BindingIter bi(script); bi; bi++) { if (bi.closedOver()) { diff --git a/js/src/vm/EnvironmentObject.h b/js/src/vm/EnvironmentObject.h index 98678ec2b69f..620073e4efd3 100644 --- a/js/src/vm/EnvironmentObject.h +++ b/js/src/vm/EnvironmentObject.h @@ -994,8 +994,6 @@ class DebugEnvironments Zone* zone() const { return zone_; } private: - bool init(); - static DebugEnvironments* ensureRealmData(JSContext* cx); template diff --git a/js/src/vm/GeckoProfiler.cpp b/js/src/vm/GeckoProfiler.cpp index 0354a31ce3cf..e33b05eaf87f 100644 --- a/js/src/vm/GeckoProfiler.cpp +++ b/js/src/vm/GeckoProfiler.cpp @@ -42,16 +42,6 @@ GeckoProfilerRuntime::GeckoProfilerRuntime(JSRuntime* rt) MOZ_ASSERT(rt != nullptr); } -bool -GeckoProfilerRuntime::init() -{ - auto locked = strings.lock(); - if (!locked->init()) - return false; - - return true; -} - void GeckoProfilerThread::setProfilingStack(ProfilingStack* profilingStack) { @@ -163,7 +153,6 @@ const char* GeckoProfilerRuntime::profileString(JSScript* script, JSFunction* maybeFun) { auto locked = strings.lock(); - MOZ_ASSERT(locked->initialized()); ProfileStringMap::AddPtr s = locked->lookupForAdd(script); @@ -187,8 +176,6 @@ GeckoProfilerRuntime::onScriptFinalized(JSScript* script) * done. */ auto locked = strings.lock(); - if (!locked->initialized()) - return; if (ProfileStringMap::Ptr entry = locked->lookup(script)) locked->remove(entry); } @@ -334,9 +321,6 @@ void GeckoProfilerRuntime::fixupStringsMapAfterMovingGC() { auto locked = strings.lock(); - if (!locked->initialized()) - return; - for (ProfileStringMap::Enum e(locked.get()); !e.empty(); e.popFront()) { JSScript* script = e.front().key(); if (IsForwarded(script)) { @@ -351,9 +335,6 @@ void GeckoProfilerRuntime::checkStringsMapAfterMovingGC() { auto locked = strings.lock(); - if (!locked->initialized()) - return; - for (auto r = locked->all(); !r.empty(); r.popFront()) { JSScript* script = r.front().key(); CheckGCThingAfterMovingGC(script); diff --git a/js/src/vm/GeckoProfiler.h b/js/src/vm/GeckoProfiler.h index 67c42a0f2c08..92267c0c2a28 100644 --- a/js/src/vm/GeckoProfiler.h +++ b/js/src/vm/GeckoProfiler.h @@ -122,8 +122,6 @@ class GeckoProfilerRuntime public: explicit GeckoProfilerRuntime(JSRuntime* rt); - bool init(); - /* management of whether instrumentation is on or off */ bool enabled() { return enabled_; } void enable(bool enabled); diff --git a/js/src/vm/Iteration.cpp b/js/src/vm/Iteration.cpp index d0b80ae8f7b5..b07819275b74 100644 --- a/js/src/vm/Iteration.cpp +++ b/js/src/vm/Iteration.cpp @@ -108,10 +108,8 @@ Enumerate(JSContext* cx, HandleObject pobj, jsid id, { if (CheckForDuplicates) { if (!ht) { - ht.emplace(cx); // Most of the time there are only a handful of entries. - if (!ht->init(5)) - return false; + ht.emplace(cx, 5); } // If we've already seen this, we definitely won't add it. diff --git a/js/src/vm/JSAtom.cpp b/js/src/vm/JSAtom.cpp index 4dc4a317039a..3571619fc4fb 100644 --- a/js/src/vm/JSAtom.cpp +++ b/js/src/vm/JSAtom.cpp @@ -171,8 +171,8 @@ JSRuntime::initializeAtoms(JSContext* cx) return atoms_->init(); } - permanentAtomsDuringInit_ = js_new(); - if (!permanentAtomsDuringInit_ || !permanentAtomsDuringInit_->init(JS_PERMANENT_ATOM_SIZE)) + permanentAtomsDuringInit_ = js_new(JS_PERMANENT_ATOM_SIZE); + if (!permanentAtomsDuringInit_) return false; staticStrings = js_new(); @@ -270,6 +270,7 @@ class AtomsTable::AutoLock AtomsTable::Partition::Partition(uint32_t index) : lock(MutexId { mutexid::AtomsTable.name, mutexid::AtomsTable.order + index }), + atoms(InitialTableSize), atomsAddedWhileSweeping(nullptr) {} @@ -291,8 +292,6 @@ AtomsTable::init() partitions[i] = js_new(i); if (!partitions[i]) return false; - if (!partitions[i]->atoms.init(InitialTableSize)) - return false; } return true; } @@ -495,7 +494,7 @@ AtomsTable::startIncrementalSweep() auto& part = *partitions[i]; auto newAtoms = js_new(); - if (!newAtoms || !newAtoms->init()) { + if (!newAtoms) { ok = false; break; } diff --git a/js/src/vm/JSScript.cpp b/js/src/vm/JSScript.cpp index cd6c04bb480a..c9232f5987e3 100644 --- a/js/src/vm/JSScript.cpp +++ b/js/src/vm/JSScript.cpp @@ -1064,11 +1064,6 @@ JSScript::initScriptCounts(JSContext* cx) if (!map) return false; - if (!map->init()) { - ReportOutOfMemory(cx); - return false; - } - realm()->scriptCountsMap = std::move(map); } @@ -1541,7 +1536,7 @@ UncompressedSourceCache::put(const ScriptSourceChunk& ssc, UniqueTwoByteChars st if (!map_) { UniquePtr map = MakeUnique(); - if (!map || !map->init()) + if (!map) return false; map_ = std::move(map); @@ -2025,11 +2020,6 @@ ScriptSource::xdrEncodeTopLevel(JSContext* cx, HandleScript script) xdrEncoder_.reset(nullptr); }); - if (!xdrEncoder_->init()) { - ReportOutOfMemory(cx); - return false; - } - RootedScript s(cx, script); XDRResult res = xdrEncoder_->codeScript(&s); if (res.isErr()) { @@ -2501,8 +2491,6 @@ js::FreeScriptData(JSRuntime* rt) AutoLockScriptData lock(rt); ScriptDataTable& table = rt->scriptDataTable(lock); - if (!table.initialized()) - return; // The table should be empty unless the embedding leaked GC things. MOZ_ASSERT_IF(rt->gc.shutdownCollectedEverything(), table.empty()); @@ -2721,11 +2709,6 @@ JSScript::initScriptName(JSContext* cx) if (!map) return false; - if (!map->init()) { - ReportOutOfMemory(cx); - return false; - } - realm()->scriptNameMap = std::move(map); } @@ -3184,8 +3167,7 @@ void GSNCache::purge() { code = nullptr; - if (map.initialized()) - map.finish(); + map.clearAndCompact(); } jssrcnote* @@ -3196,7 +3178,6 @@ js::GetSrcNote(GSNCache& cache, JSScript* script, jsbytecode* pc) return nullptr; if (cache.code == script->code()) { - MOZ_ASSERT(cache.map.initialized()); GSNCache::Map::Ptr p = cache.map.lookup(pc); return p ? p->value() : nullptr; } @@ -3217,18 +3198,15 @@ js::GetSrcNote(GSNCache& cache, JSScript* script, jsbytecode* pc) if (cache.code != script->code() && script->length() >= GSN_CACHE_THRESHOLD) { unsigned nsrcnotes = 0; - for (jssrcnote* sn = script->notes(); !SN_IS_TERMINATOR(sn); - sn = SN_NEXT(sn)) - { + for (jssrcnote* sn = script->notes(); !SN_IS_TERMINATOR(sn); sn = SN_NEXT(sn)) { if (SN_IS_GETTABLE(sn)) ++nsrcnotes; } if (cache.code) { - MOZ_ASSERT(cache.map.initialized()); - cache.map.finish(); + cache.map.clear(); cache.code = nullptr; } - if (cache.map.init(nsrcnotes)) { + if (cache.map.reserve(nsrcnotes)) { pc = script->code(); for (jssrcnote* sn = script->notes(); !SN_IS_TERMINATOR(sn); sn = SN_NEXT(sn)) @@ -3796,11 +3774,6 @@ JSScript::ensureHasDebugScript(JSContext* cx) if (!map) return false; - if (!map->init()) { - ReportOutOfMemory(cx); - return false; - } - realm()->debugScriptMap = std::move(map); } diff --git a/js/src/vm/MemoryMetrics.cpp b/js/src/vm/MemoryMetrics.cpp index 4e9cfaf85108..11bcd8e5f156 100644 --- a/js/src/vm/MemoryMetrics.cpp +++ b/js/src/vm/MemoryMetrics.cpp @@ -270,14 +270,6 @@ struct StatsClosure opv(v), anonymize(anon) {} - - bool init() { - return seenSources.init() && - wasmSeenMetadata.init() && - wasmSeenBytes.init() && - wasmSeenCode.init() && - wasmSeenTables.init(); - } }; static void @@ -626,7 +618,7 @@ ZoneStats::initStrings() { isTotals = false; allStrings = js_new(); - if (!allStrings || !allStrings->init()) { + if (!allStrings) { js_delete(allStrings); allStrings = nullptr; return false; @@ -639,7 +631,7 @@ RealmStats::initClasses() { isTotals = false; allClasses = js_new(); - if (!allClasses || !allClasses->init()) { + if (!allClasses) { js_delete(allClasses); allClasses = nullptr; return false; @@ -772,8 +764,6 @@ CollectRuntimeStatsHelper(JSContext* cx, RuntimeStats* rtStats, ObjectPrivateVis // Take the per-compartment measurements. StatsClosure closure(rtStats, opv, anonymize); - if (!closure.init()) - return false; IterateHeapUnbarriered(cx, &closure, StatsZoneCallback, StatsRealmCallback, @@ -935,8 +925,6 @@ AddSizeOfTab(JSContext* cx, HandleObject obj, MallocSizeOf mallocSizeOf, ObjectP // Take the per-compartment measurements. No need to anonymize because // these measurements will be aggregated. StatsClosure closure(&rtStats, opv, /* anonymize = */ false); - if (!closure.init()) - return false; IterateHeapUnbarrieredForZone(cx, zone, &closure, StatsZoneCallback, StatsRealmCallback, diff --git a/js/src/vm/ObjectGroup.cpp b/js/src/vm/ObjectGroup.cpp index 10bb88ac440f..4bac9ba3b711 100644 --- a/js/src/vm/ObjectGroup.cpp +++ b/js/src/vm/ObjectGroup.cpp @@ -531,13 +531,6 @@ ObjectGroup::defaultNewGroup(JSContext* cx, const Class* clasp, table = cx->new_(cx->zone()); if (!table) return nullptr; - - if (!table->init()) { - js_delete(table); - table = nullptr; - ReportOutOfMemory(cx); - return nullptr; - } } if (proto.isObject() && !proto.toObject()->isDelegate()) { @@ -639,13 +632,6 @@ ObjectGroup::lazySingletonGroup(JSContext* cx, ObjectGroup* oldGroup, const Clas table = cx->new_(cx->zone()); if (!table) return nullptr; - - if (!table->init()) { - ReportOutOfMemory(cx); - js_delete(table); - table = nullptr; - return nullptr; - } } ObjectGroupRealm::NewTable::AddPtr p = @@ -870,13 +856,6 @@ ObjectGroup::newArrayObject(JSContext* cx, table = cx->new_(); if (!table) return nullptr; - - if (!table->init()) { - ReportOutOfMemory(cx); - js_delete(table); - table = nullptr; - return nullptr; - } } ObjectGroupRealm::ArrayObjectKey key(elementType); @@ -1196,13 +1175,6 @@ ObjectGroup::newPlainObject(JSContext* cx, IdValuePair* properties, size_t nprop table = cx->new_(); if (!table) return nullptr; - - if (!table->init()) { - ReportOutOfMemory(cx); - js_delete(table); - table = nullptr; - return nullptr; - } } ObjectGroupRealm::PlainObjectKey::Lookup lookup(properties, nproperties); @@ -1461,13 +1433,6 @@ ObjectGroup::allocationSiteGroup(JSContext* cx, JSScript* scriptArg, jsbytecode* table = cx->new_(cx->zone()); if (!table) return nullptr; - - if (!table->init()) { - ReportOutOfMemory(cx); - js_delete(table); - table = nullptr; - return nullptr; - } } RootedScript script(cx, scriptArg); @@ -1774,11 +1739,11 @@ ObjectGroupRealm::addSizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf, void ObjectGroupRealm::clearTables() { - if (allocationSiteTable && allocationSiteTable->initialized()) + if (allocationSiteTable) allocationSiteTable->clear(); - if (arrayObjectTable && arrayObjectTable->initialized()) + if (arrayObjectTable) arrayObjectTable->clear(); - if (plainObjectTable && plainObjectTable->initialized()) { + if (plainObjectTable) { for (PlainObjectTable::Enum e(*plainObjectTable); !e.empty(); e.popFront()) { const PlainObjectKey& key = e.front().key(); PlainObjectEntry& entry = e.front().value(); @@ -1787,9 +1752,9 @@ ObjectGroupRealm::clearTables() } plainObjectTable->clear(); } - if (defaultNewTable && defaultNewTable->initialized()) + if (defaultNewTable) defaultNewTable->clear(); - if (lazyTable && lazyTable->initialized()) + if (lazyTable) lazyTable->clear(); defaultNewGroupCache.purge(); } @@ -1831,7 +1796,7 @@ ObjectGroupRealm::fixupNewTableAfterMovingGC(NewTable* table) * Each entry's hash depends on the object's prototype and we can't tell * whether that has been moved or not in sweepNewObjectGroupTable(). */ - if (table && table->initialized()) { + if (table) { for (NewTable::Enum e(*table); !e.empty(); e.popFront()) { NewEntry& entry = e.mutableFront(); @@ -1862,7 +1827,7 @@ ObjectGroupRealm::checkNewTableAfterMovingGC(NewTable* table) * Assert that nothing points into the nursery or needs to be relocated, and * that the hash table entries are discoverable. */ - if (!table || !table->initialized()) + if (!table) return; for (auto r = table->all(); !r.empty(); r.popFront()) { diff --git a/js/src/vm/Realm.cpp b/js/src/vm/Realm.cpp index b752a885a0cd..c65c7939d4a6 100644 --- a/js/src/vm/Realm.cpp +++ b/js/src/vm/Realm.cpp @@ -89,11 +89,6 @@ Realm::~Realm() bool ObjectRealm::init(JSContext* cx) { - if (!iteratorCache.init()) { - ReportOutOfMemory(cx); - return false; - } - NativeIteratorSentinel sentinel(NativeIterator::allocateSentinel(cx)); if (!sentinel) return false; @@ -117,13 +112,6 @@ Realm::init(JSContext* cx, JSPrincipals* principals) if (!objects_.init(cx)) return false; - if (!savedStacks_.init() || - !varNames_.init()) - { - ReportOutOfMemory(cx); - return false; - } - if (principals) { // Any realm with the trusted principals -- and there can be // multiple -- is a system realm. @@ -212,11 +200,6 @@ ObjectRealm::getOrCreateNonSyntacticLexicalEnvironment(JSContext* cx, HandleObje if (!map) return nullptr; - if (!map->init()) { - ReportOutOfMemory(cx); - return nullptr; - } - nonSyntacticLexicalEnvironments_ = std::move(map); } @@ -602,7 +585,7 @@ Realm::purge() dtoaCache.purge(); newProxyCache.purge(); objectGroups_.purge(); - objects_.iteratorCache.clearAndShrink(); + objects_.iteratorCache.clearAndCompact(); arraySpeciesLookup.purge(); promiseLookup.purge(); } @@ -620,10 +603,8 @@ Realm::clearTables() MOZ_ASSERT(objects_.enumerators->next() == objects_.enumerators); objectGroups_.clearTables(); - if (savedStacks_.initialized()) - savedStacks_.clear(); - if (varNames_.initialized()) - varNames_.clear(); + savedStacks_.clear(); + varNames_.clear(); } void @@ -662,7 +643,7 @@ Realm::setNewObjectMetadata(JSContext* cx, HandleObject obj) if (!objects_.objectMetadataTable) { auto table = cx->make_unique(cx); - if (!table || !table->init()) + if (!table) oomUnsafe.crash("setNewObjectMetadata"); objects_.objectMetadataTable = std::move(table); diff --git a/js/src/vm/RegExpObject.cpp b/js/src/vm/RegExpObject.cpp index fc94a4553a67..300536c172f4 100644 --- a/js/src/vm/RegExpObject.cpp +++ b/js/src/vm/RegExpObject.cpp @@ -1266,15 +1266,6 @@ RegExpRealm::createMatchResultTemplateObject(JSContext* cx) return matchResultTemplateObject_; } -bool -RegExpZone::init() -{ - if (!set_.init(0)) - return false; - - return true; -} - void RegExpRealm::sweep() { diff --git a/js/src/vm/RegExpShared.h b/js/src/vm/RegExpShared.h index c963a4896464..e077ed3f9bd3 100644 --- a/js/src/vm/RegExpShared.h +++ b/js/src/vm/RegExpShared.h @@ -266,11 +266,9 @@ class RegExpZone explicit RegExpZone(Zone* zone); ~RegExpZone() { - MOZ_ASSERT_IF(set_.initialized(), set_.empty()); + MOZ_ASSERT(set_.empty()); } - bool init(); - bool empty() const { return set_.empty(); } RegExpShared* maybeGet(JSAtom* source, RegExpFlag flags) const { diff --git a/js/src/vm/Runtime.cpp b/js/src/vm/Runtime.cpp index 9210220bee24..46d69d6d51aa 100644 --- a/js/src/vm/Runtime.cpp +++ b/js/src/vm/Runtime.cpp @@ -222,12 +222,6 @@ JSRuntime::init(JSContext* cx, uint32_t maxbytes, uint32_t maxNurseryBytes) gc.atomsZone = atomsZone.release(); - if (!symbolRegistry_.ref().init()) - return false; - - if (!scriptDataTable_.ref().init()) - return false; - /* The garbage collector depends on everything before this point being initialized. */ gcInitialized = true; @@ -240,18 +234,12 @@ JSRuntime::init(JSContext* cx, uint32_t maxbytes, uint32_t maxNurseryBytes) jitSupportsUnalignedAccesses = js::jit::JitSupportsUnalignedAccesses(); jitSupportsSimd = js::jit::JitSupportsSimd(); - if (!geckoProfiler().init()) - return false; - if (!parentRuntime) { sharedImmutableStrings_ = js::SharedImmutableStringsCache::Create(); if (!sharedImmutableStrings_) return false; } - if (!caches().init()) - return false; - return true; } diff --git a/js/src/vm/SavedStacks.cpp b/js/src/vm/SavedStacks.cpp index b157dab1db1f..31ec2260ede2 100644 --- a/js/src/vm/SavedStacks.cpp +++ b/js/src/vm/SavedStacks.cpp @@ -1226,18 +1226,10 @@ SavedFrame::toStringMethod(JSContext* cx, unsigned argc, Value* vp) return true; } -bool -SavedStacks::init() -{ - return frames.init() && - pcLocationMap.init(); -} - bool SavedStacks::saveCurrentStack(JSContext* cx, MutableHandleSavedFrame frame, JS::StackCapture&& capture /* = JS::StackCapture(JS::AllFrames()) */) { - MOZ_ASSERT(initialized()); MOZ_RELEASE_ASSERT(cx->realm()); MOZ_DIAGNOSTIC_ASSERT(&cx->realm()->savedStacks() == this); @@ -1259,7 +1251,6 @@ SavedStacks::copyAsyncStack(JSContext* cx, HandleObject asyncStack, HandleString MutableHandleSavedFrame adoptedStack, const Maybe& maxFrameCount) { - MOZ_ASSERT(initialized()); MOZ_RELEASE_ASSERT(cx->realm()); MOZ_DIAGNOSTIC_ASSERT(&cx->realm()->savedStacks() == this); @@ -1294,7 +1285,6 @@ SavedStacks::trace(JSTracer* trc) uint32_t SavedStacks::count() { - MOZ_ASSERT(initialized()); return frames.count(); } diff --git a/js/src/vm/SavedStacks.h b/js/src/vm/SavedStacks.h index 571dbd65ecfa..647efeb85ac7 100644 --- a/js/src/vm/SavedStacks.h +++ b/js/src/vm/SavedStacks.h @@ -162,8 +162,6 @@ class SavedStacks { creatingSavedFrame(false) { } - MOZ_MUST_USE bool init(); - bool initialized() const { return frames.initialized(); } MOZ_MUST_USE bool saveCurrentStack(JSContext* cx, MutableHandleSavedFrame frame, JS::StackCapture&& capture = JS::StackCapture(JS::AllFrames())); MOZ_MUST_USE bool copyAsyncStack(JSContext* cx, HandleObject asyncStack, diff --git a/js/src/vm/Shape.cpp b/js/src/vm/Shape.cpp index 281186a116b7..4bdf562beac1 100644 --- a/js/src/vm/Shape.cpp +++ b/js/src/vm/Shape.cpp @@ -1445,11 +1445,6 @@ BaseShape::getUnowned(JSContext* cx, StackBaseShape& base) { auto& table = cx->zone()->baseShapes(); - if (!table.initialized() && !table.init()) { - ReportOutOfMemory(cx); - return nullptr; - } - auto p = MakeDependentAddPtr(cx, table, base); if (p) return *p; @@ -1532,9 +1527,6 @@ BaseShape::canSkipMarkingShapeTable(Shape* lastShape) void Zone::checkBaseShapeTableAfterMovingGC() { - if (!baseShapes().initialized()) - return; - for (auto r = baseShapes().all(); !r.empty(); r.popFront()) { UnownedBaseShape* base = r.front().unbarrieredGet(); CheckGCThingAfterMovingGC(base); @@ -1571,9 +1563,6 @@ InitialShapeEntry::InitialShapeEntry(Shape* shape, const Lookup::ShapeProto& pro void Zone::checkInitialShapesTableAfterMovingGC() { - if (!initialShapes().initialized()) - return; - /* * Assert that the postbarriers have worked and that nothing is left in * initialShapes that points into the nursery, and that the hash table @@ -1630,7 +1619,7 @@ static KidsHash* HashChildren(Shape* kid1, Shape* kid2) { auto hash = MakeUnique(); - if (!hash || !hash->init(2)) + if (!hash || !hash->reserve(2)) return nullptr; hash->putNewInfallible(StackShape(kid1), kid1); @@ -2094,11 +2083,6 @@ EmptyShape::getInitialShape(JSContext* cx, const Class* clasp, TaggedProto proto auto& table = cx->zone()->initialShapes(); - if (!table.initialized() && !table.init()) { - ReportOutOfMemory(cx); - return nullptr; - } - using Lookup = InitialShapeEntry::Lookup; auto protoPointer = MakeDependentAddPtr(cx, table, Lookup(clasp, Lookup::ShapeProto(proto), @@ -2248,9 +2232,6 @@ EmptyShape::insertInitialShape(JSContext* cx, HandleShape shape, HandleObject pr void Zone::fixupInitialShapeTable() { - if (!initialShapes().initialized()) - return; - for (InitialShapeSet::Enum e(initialShapes()); !e.empty(); e.popFront()) { // The shape may have been moved, but we can update that in place. Shape* shape = e.front().shape.unbarrieredGet(); diff --git a/js/src/vm/SharedImmutableStringsCache-inl.h b/js/src/vm/SharedImmutableStringsCache-inl.h index ef7e53e46373..a64c2283403d 100644 --- a/js/src/vm/SharedImmutableStringsCache-inl.h +++ b/js/src/vm/SharedImmutableStringsCache-inl.h @@ -21,9 +21,6 @@ SharedImmutableStringsCache::getOrCreate(const char* chars, size_t length, Hasher::Lookup lookup(Hasher::hashLongString(chars, length), chars, length); auto locked = inner_->lock(); - if (!locked->set.initialized() && !locked->set.init()) - return mozilla::Nothing(); - auto entry = locked->set.lookupForAdd(lookup); if (!entry) { OwnedChars ownedChars(intoOwnedChars()); @@ -51,9 +48,6 @@ SharedImmutableStringsCache::getOrCreate(const char16_t* chars, size_t length, Hasher::Lookup lookup(hash, chars, length); auto locked = inner_->lock(); - if (!locked->set.initialized() && !locked->set.init()) - return mozilla::Nothing(); - auto entry = locked->set.lookupForAdd(lookup); if (!entry) { OwnedTwoByteChars ownedTwoByteChars(intoOwnedTwoByteChars()); diff --git a/js/src/vm/SharedImmutableStringsCache.h b/js/src/vm/SharedImmutableStringsCache.h index 4bbef1e2703e..7ee596c7f12b 100644 --- a/js/src/vm/SharedImmutableStringsCache.h +++ b/js/src/vm/SharedImmutableStringsCache.h @@ -139,8 +139,6 @@ class SharedImmutableStringsCache size_t n = mallocSizeOf(inner_); auto locked = inner_->lock(); - if (!locked->set.initialized()) - return n; // Size of the table. n += locked->set.shallowSizeOfExcludingThis(mallocSizeOf); @@ -214,9 +212,6 @@ class SharedImmutableStringsCache auto locked = inner_->lock(); MOZ_ASSERT(locked->refcount > 0); - if (!locked->set.initialized()) - return; - for (Inner::Set::Enum e(locked->set); !e.empty(); e.popFront()) { if (e.front()->refcount == 0) { // The chars should be eagerly freed when refcount reaches zero. diff --git a/js/src/vm/Stack.cpp b/js/src/vm/Stack.cpp index 4450bf9f1abd..8ff311c69b20 100644 --- a/js/src/vm/Stack.cpp +++ b/js/src/vm/Stack.cpp @@ -1662,11 +1662,6 @@ jit::JitActivation::getRematerializedFrame(JSContext* cx, const JSJitFrameIter& rematerializedFrames_ = cx->make_unique(cx); if (!rematerializedFrames_) return nullptr; - if (!rematerializedFrames_->init()) { - rematerializedFrames_.reset(); - ReportOutOfMemory(cx); - return nullptr; - } } uint8_t* top = iter.fp(); diff --git a/js/src/vm/StructuredClone.cpp b/js/src/vm/StructuredClone.cpp index 33d54532a136..1aed060cc738 100644 --- a/js/src/vm/StructuredClone.cpp +++ b/js/src/vm/StructuredClone.cpp @@ -491,10 +491,6 @@ struct JSStructuredCloneWriter { ~JSStructuredCloneWriter(); bool init() { - if (!memory.init()) { - ReportOutOfMemory(context()); - return false; - } return parseTransferable() && writeHeader() && writeTransferMap(); } @@ -1075,11 +1071,11 @@ JSStructuredCloneWriter::parseTransferable() // NOTE: The transferables set is tested for non-emptiness at various // junctures in structured cloning, so this set must be initialized // by this method in all non-error cases. - MOZ_ASSERT(!transferableObjects.initialized(), + MOZ_ASSERT(transferableObjects.empty(), "parseTransferable called with stale data"); if (transferable.isNull() || transferable.isUndefined()) - return transferableObjects.init(0); + return true; if (!transferable.isObject()) return reportDataCloneError(JS_SCERR_TRANSFERABLE); @@ -1097,7 +1093,7 @@ JSStructuredCloneWriter::parseTransferable() return false; // Initialize the set for the provided array's length. - if (!transferableObjects.init(length)) + if (!transferableObjects.reserve(length)) return false; if (length == 0) diff --git a/js/src/vm/TraceLogging.cpp b/js/src/vm/TraceLogging.cpp index c9d963859080..0943bc6611b5 100644 --- a/js/src/vm/TraceLogging.cpp +++ b/js/src/vm/TraceLogging.cpp @@ -356,11 +356,9 @@ TraceLoggerThreadState::sizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf) size_t size = 0; size += pointerMap.shallowSizeOfExcludingThis(mallocSizeOf); - if (textIdPayloads.initialized()) { - size += textIdPayloads.shallowSizeOfExcludingThis(mallocSizeOf); - for (TextIdHashMap::Range r = textIdPayloads.all(); !r.empty(); r.popFront()) - r.front().value()->sizeOfIncludingThis(mallocSizeOf); - } + size += textIdPayloads.shallowSizeOfExcludingThis(mallocSizeOf); + for (TextIdHashMap::Range r = textIdPayloads.all(); !r.empty(); r.popFront()) + r.front().value()->sizeOfIncludingThis(mallocSizeOf); return size; } @@ -692,10 +690,8 @@ TraceLoggerThreadState::~TraceLoggerThreadState() threadLoggers.clear(); - if (textIdPayloads.initialized()) { - for (TextIdHashMap::Range r = textIdPayloads.all(); !r.empty(); r.popFront()) - js_delete(r.front().value()); - } + for (TextIdHashMap::Range r = textIdPayloads.all(); !r.empty(); r.popFront()) + js_delete(r.front().value()); #ifdef DEBUG initialized = false; @@ -875,11 +871,6 @@ TraceLoggerThreadState::init() spewErrors = true; } - if (!pointerMap.init()) - return false; - if (!textIdPayloads.init()) - return false; - startupTime = rdtsc(); #ifdef DEBUG diff --git a/js/src/vm/UbiNode.cpp b/js/src/vm/UbiNode.cpp index 51be8706adba..e564ca9d4881 100644 --- a/js/src/vm/UbiNode.cpp +++ b/js/src/vm/UbiNode.cpp @@ -450,8 +450,6 @@ RootList::init(CompartmentSet& debuggees) EdgeVectorTracer tracer(cx->runtime(), &allRootEdges, wantNames); ZoneSet debuggeeZones; - if (!debuggeeZones.init()) - return false; for (auto range = debuggees.all(); !range.empty(); range.popFront()) { if (!debuggeeZones.put(range.front()->zone())) return false; @@ -490,8 +488,6 @@ RootList::init(HandleObject debuggees) js::Debugger* dbg = js::Debugger::fromJSObject(debuggees.get()); CompartmentSet debuggeeCompartments; - if (!debuggeeCompartments.init()) - return false; for (js::WeakGlobalObjectSet::Range r = dbg->allDebuggees(); !r.empty(); r.popFront()) { if (!debuggeeCompartments.put(r.front()->compartment())) diff --git a/js/src/vm/UbiNodeCensus.cpp b/js/src/vm/UbiNodeCensus.cpp index 5fcf7dd75adf..fef94ecf0846 100644 --- a/js/src/vm/UbiNodeCensus.cpp +++ b/js/src/vm/UbiNodeCensus.cpp @@ -30,12 +30,6 @@ CountDeleter::operator()(CountBase* ptr) js_free(ptr); } -JS_PUBLIC_API(bool) -Census::init() { - return targetZones.init(); -} - - /*** Count Types ***********************************************************************************/ // The simplest type: just count everything. @@ -467,8 +461,6 @@ class ByObjectClass : public CountType { : CountBase(type), other(std::move(other)) { } - - bool init() { return table.init(); } }; CountTypePtr classesType; @@ -500,7 +492,7 @@ ByObjectClass::makeCount() return nullptr; auto count = js::MakeUnique(*this, otherCount); - if (!count || !count->init()) + if (!count) return nullptr; return CountBasePtr(count.release()); @@ -581,8 +573,6 @@ class ByDomObjectClass : public CountType { Table table; explicit Count(CountType& type) : CountBase(type) { } - - bool init() { return table.init(); } }; CountTypePtr classesType; @@ -608,7 +598,7 @@ CountBasePtr ByDomObjectClass::makeCount() { auto count = js::MakeUnique(*this); - if (!count || !count->init()) + if (!count) return nullptr; return CountBasePtr(count.release()); @@ -672,8 +662,6 @@ class ByUbinodeType : public CountType { Table table; explicit Count(CountType& type) : CountBase(type) { } - - bool init() { return table.init(); } }; CountTypePtr entryType; @@ -699,7 +687,7 @@ CountBasePtr ByUbinodeType::makeCount() { auto count = js::MakeUnique(*this); - if (!count || !count->init()) + if (!count) return nullptr; return CountBasePtr(count.release()); @@ -814,7 +802,6 @@ class ByAllocationStack : public CountType { : CountBase(type), noStack(std::move(noStack)) { } - bool init() { return table.init(); } }; CountTypePtr entryType; @@ -846,7 +833,7 @@ ByAllocationStack::makeCount() return nullptr; auto count = js::MakeUnique(*this, noStackCount); - if (!count || !count->init()) + if (!count) return nullptr; return CountBasePtr(count.release()); } @@ -985,8 +972,6 @@ class ByFilename : public CountType { , then(std::move(then)) , noFilename(std::move(noFilename)) { } - - bool init() { return table.init(); } }; CountTypePtr thenType; @@ -1022,7 +1007,7 @@ ByFilename::makeCount() return nullptr; auto count = js::MakeUnique(*this, std::move(thenCount), std::move(noFilenameCount)); - if (!count || !count->init()) + if (!count) return nullptr; return CountBasePtr(count.release()); diff --git a/js/src/vm/UbiNodeShortestPaths.cpp b/js/src/vm/UbiNodeShortestPaths.cpp index 1b2446decd8d..2ea9a9842206 100644 --- a/js/src/vm/UbiNodeShortestPaths.cpp +++ b/js/src/vm/UbiNodeShortestPaths.cpp @@ -54,7 +54,7 @@ dumpPaths(JSContext* cx, Node node, uint32_t maxNumPaths /* = 10 */) MOZ_ASSERT(rootList.init()); NodeSet targets; - bool ok = targets.init() && targets.putNew(node); + bool ok = targets.putNew(node); MOZ_ASSERT(ok); auto paths = ShortestPaths::Create(cx, nogc.ref(), maxNumPaths, &rootList, std::move(targets)); diff --git a/js/src/vm/Xdr.cpp b/js/src/vm/Xdr.cpp index 6da08dae70bc..0e6155a65545 100644 --- a/js/src/vm/Xdr.cpp +++ b/js/src/vm/Xdr.cpp @@ -247,14 +247,6 @@ XDRIncrementalEncoder::getTreeKey(JSFunction* fun) const return AutoXDRTree::noKey; } -bool -XDRIncrementalEncoder::init() -{ - if (!tree_.init()) - return false; - return true; -} - void XDRIncrementalEncoder::createOrReplaceSubTree(AutoXDRTree* child) { @@ -397,7 +389,7 @@ XDRIncrementalEncoder::linearize(JS::TranscodeBuffer& buffer) } } - tree_.finish(); + tree_.clearAndCompact(); slices_.clearAndFree(); return Ok(); } diff --git a/js/src/vm/Xdr.h b/js/src/vm/Xdr.h index 5eed51f1a83d..5e4ff349be21 100644 --- a/js/src/vm/Xdr.h +++ b/js/src/vm/Xdr.h @@ -595,8 +595,6 @@ class XDRIncrementalEncoder : public XDREncoder AutoXDRTree::Key getTopLevelTreeKey() const override; AutoXDRTree::Key getTreeKey(JSFunction* fun) const override; - MOZ_MUST_USE bool init(); - void createOrReplaceSubTree(AutoXDRTree* child) override; void endSubTree() override; diff --git a/js/src/wasm/AsmJS.cpp b/js/src/wasm/AsmJS.cpp index 5acfe3133e22..5cd884a44f19 100644 --- a/js/src/wasm/AsmJS.cpp +++ b/js/src/wasm/AsmJS.cpp @@ -1547,11 +1547,7 @@ class MOZ_STACK_CLASS JS_HAZ_ROOTED ModuleValidator !parser_.pc->sc()->hasExplicitUseStrict(); asmJSMetadata_->scriptSource.reset(parser_.ss); - if (!globalMap_.init() || !sigSet_.init() || !funcImportMap_.init()) - return false; - - if (!standardLibraryMathNames_.init() || - !addStandardLibraryMathName("sin", AsmJSMathBuiltin_sin) || + if (!addStandardLibraryMathName("sin", AsmJSMathBuiltin_sin) || !addStandardLibraryMathName("cos", AsmJSMathBuiltin_cos) || !addStandardLibraryMathName("tan", AsmJSMathBuiltin_tan) || !addStandardLibraryMathName("asin", AsmJSMathBuiltin_asin) || @@ -2343,12 +2339,6 @@ class MOZ_STACK_CLASS FunctionValidator JSContext* cx() const { return m_.cx(); } ParseNode* fn() const { return fn_; } - bool init() { - return locals_.init() && - breakLabels_.init() && - continueLabels_.init(); - } - void define(ModuleValidator::Func* func, unsigned line) { MOZ_ASSERT(!blockDepth_); MOZ_ASSERT(breakableStack_.empty()); @@ -5416,8 +5406,6 @@ CheckFunction(ModuleValidator& m) return false; FunctionValidator f(m, fn); - if (!f.init()) - return m.fail(fn, "internal compiler failure (probably out of memory)"); ParseNode* stmtIter = ListHead(FunctionStatementList(fn)); diff --git a/js/src/wasm/WasmAST.h b/js/src/wasm/WasmAST.h index 199f7133c7b7..b30e0e0bc9ba 100644 --- a/js/src/wasm/WasmAST.h +++ b/js/src/wasm/WasmAST.h @@ -1258,9 +1258,6 @@ class AstModule : public AstNode globals_(lifo), numGlobalImports_(0) {} - bool init() { - return funcTypeMap_.init(); - } bool addMemory(AstName name, const Limits& memory) { return memories_.append(AstResizable(memory, false, name)); } diff --git a/js/src/wasm/WasmBuiltins.cpp b/js/src/wasm/WasmBuiltins.cpp index 567525437301..4c413d00d233 100644 --- a/js/src/wasm/WasmBuiltins.cpp +++ b/js/src/wasm/WasmBuiltins.cpp @@ -837,9 +837,6 @@ using TypedNativeToFuncPtrMap = static bool PopulateTypedNatives(TypedNativeToFuncPtrMap* typedNatives) { - if (!typedNatives->init()) - return false; - #define ADD_OVERLOAD(funcName, native, abiType) \ if (!typedNatives->putNew(TypedNative(InlinableNative::native, abiType), \ FuncCast(funcName, abiType))) \ @@ -956,9 +953,6 @@ wasm::EnsureBuiltinThunksInitialized() if (!PopulateTypedNatives(&typedNatives)) return false; - if (!thunks->typedNativeToCodeRange.init()) - return false; - for (TypedNativeToFuncPtrMap::Range r = typedNatives.all(); !r.empty(); r.popFront()) { TypedNative typedNative = r.front().key(); diff --git a/js/src/wasm/WasmDebug.cpp b/js/src/wasm/WasmDebug.cpp index 355c6e8932d3..d06376b54864 100644 --- a/js/src/wasm/WasmDebug.cpp +++ b/js/src/wasm/WasmDebug.cpp @@ -147,7 +147,7 @@ DebugState::totalSourceLines(JSContext* cx, uint32_t* count) bool DebugState::stepModeEnabled(uint32_t funcIndex) const { - return stepModeCounters_.initialized() && stepModeCounters_.lookup(funcIndex); + return stepModeCounters_.lookup(funcIndex).found(); } bool @@ -157,11 +157,6 @@ DebugState::incrementStepModeCount(JSContext* cx, uint32_t funcIndex) const CodeRange& codeRange = codeRanges(Tier::Debug)[debugFuncToCodeRangeIndex(funcIndex)]; MOZ_ASSERT(codeRange.isFunction()); - if (!stepModeCounters_.initialized() && !stepModeCounters_.init()) { - ReportOutOfMemory(cx); - return false; - } - StepModeCounters::AddPtr p = stepModeCounters_.lookupForAdd(funcIndex); if (p) { MOZ_ASSERT(p->value() > 0); @@ -194,7 +189,7 @@ DebugState::decrementStepModeCount(FreeOp* fop, uint32_t funcIndex) const CodeRange& codeRange = codeRanges(Tier::Debug)[debugFuncToCodeRangeIndex(funcIndex)]; MOZ_ASSERT(codeRange.isFunction()); - MOZ_ASSERT(stepModeCounters_.initialized() && !stepModeCounters_.empty()); + MOZ_ASSERT(!stepModeCounters_.empty()); StepModeCounters::Ptr p = stepModeCounters_.lookup(funcIndex); MOZ_ASSERT(p); if (--p->value()) @@ -211,7 +206,7 @@ DebugState::decrementStepModeCount(FreeOp* fop, uint32_t funcIndex) continue; uint32_t offset = callSite.returnAddressOffset(); if (codeRange.begin() <= offset && offset <= codeRange.end()) { - bool enabled = breakpointSites_.initialized() && breakpointSites_.has(offset); + bool enabled = breakpointSites_.has(offset); toggleDebugTrap(offset, enabled); } } @@ -239,7 +234,7 @@ DebugState::toggleBreakpointTrap(JSRuntime* rt, uint32_t offset, bool enabled) const CodeRange* codeRange = code_->lookupFuncRange(codeSegment.base() + debugTrapOffset); MOZ_ASSERT(codeRange); - if (stepModeCounters_.initialized() && stepModeCounters_.lookup(codeRange->funcIndex())) + if (stepModeCounters_.lookup(codeRange->funcIndex())) return; // no need to toggle when step mode is enabled AutoWritableJitCode awjc(rt, codeSegment.base(), codeSegment.length()); @@ -252,10 +247,6 @@ WasmBreakpointSite* DebugState::getOrCreateBreakpointSite(JSContext* cx, uint32_t offset) { WasmBreakpointSite* site; - if (!breakpointSites_.initialized() && !breakpointSites_.init()) { - ReportOutOfMemory(cx); - return nullptr; - } WasmBreakpointSiteMap::AddPtr p = breakpointSites_.lookupForAdd(offset); if (!p) { @@ -277,13 +268,12 @@ DebugState::getOrCreateBreakpointSite(JSContext* cx, uint32_t offset) bool DebugState::hasBreakpointSite(uint32_t offset) { - return breakpointSites_.initialized() && breakpointSites_.has(offset); + return breakpointSites_.has(offset); } void DebugState::destroyBreakpointSite(FreeOp* fop, uint32_t offset) { - MOZ_ASSERT(breakpointSites_.initialized()); WasmBreakpointSiteMap::Ptr p = breakpointSites_.lookup(offset); MOZ_ASSERT(p); fop->delete_(p->value()); @@ -294,7 +284,7 @@ bool DebugState::clearBreakpointsIn(JSContext* cx, WasmInstanceObject* instance, js::Debugger* dbg, JSObject* handler) { MOZ_ASSERT(instance); - if (!breakpointSites_.initialized()) + if (breakpointSites_.empty()) return true; // Make copy of all sites list, so breakpointSites_ can be modified by diff --git a/js/src/wasm/WasmGenerator.cpp b/js/src/wasm/WasmGenerator.cpp index 1a4ab9e70c31..2e80b5fe8629 100644 --- a/js/src/wasm/WasmGenerator.cpp +++ b/js/src/wasm/WasmGenerator.cpp @@ -420,8 +420,6 @@ ModuleGenerator::linkCallSites() // all possible calls/traps have been emitted. OffsetMap existingCallFarJumps; - if (!existingCallFarJumps.init()) - return false; TrapMaybeOffsetArray existingTrapFarJumps; diff --git a/js/src/wasm/WasmInstance.cpp b/js/src/wasm/WasmInstance.cpp index 45fe114d6bc6..49871f133236 100644 --- a/js/src/wasm/WasmInstance.cpp +++ b/js/src/wasm/WasmInstance.cpp @@ -42,16 +42,7 @@ class FuncTypeIdSet public: ~FuncTypeIdSet() { - MOZ_ASSERT_IF(!JSRuntime::hasLiveRuntimes(), !map_.initialized() || map_.empty()); - } - - bool ensureInitialized(JSContext* cx) { - if (!map_.initialized() && !map_.init()) { - ReportOutOfMemory(cx); - return false; - } - - return true; + MOZ_ASSERT_IF(!JSRuntime::hasLiveRuntimes(), map_.empty()); } bool allocateFuncTypeId(JSContext* cx, const FuncType& funcType, const void** funcTypeId) { @@ -619,9 +610,6 @@ Instance::init(JSContext* cx) if (!metadata().funcTypeIds.empty()) { ExclusiveData::Guard lockedFuncTypeIdSet = funcTypeIdSet.lock(); - if (!lockedFuncTypeIdSet->ensureInitialized(cx)) - return false; - for (const FuncTypeWithId& funcType : metadata().funcTypeIds) { const void* funcTypeId; if (!lockedFuncTypeIdSet->allocateFuncTypeId(cx, funcType, &funcTypeId)) diff --git a/js/src/wasm/WasmIonCompile.cpp b/js/src/wasm/WasmIonCompile.cpp index 1fcca19059a5..9a40a9133dad 100644 --- a/js/src/wasm/WasmIonCompile.cpp +++ b/js/src/wasm/WasmIonCompile.cpp @@ -1479,7 +1479,7 @@ class FunctionCompiler IndexToCaseMap; IndexToCaseMap indexToCase; - if (!indexToCase.init() || !indexToCase.put(defaultDepth, defaultIndex)) + if (!indexToCase.put(defaultDepth, defaultIndex)) return false; for (size_t i = 0; i < numCases; i++) { diff --git a/js/src/wasm/WasmJS.cpp b/js/src/wasm/WasmJS.cpp index b9ee2102f53c..9c3d2d374380 100644 --- a/js/src/wasm/WasmJS.cpp +++ b/js/src/wasm/WasmJS.cpp @@ -1081,13 +1081,13 @@ WasmInstanceObject::create(JSContext* cx, HandleObject proto) { UniquePtr exports = js::MakeUnique(); - if (!exports || !exports->init()) { + if (!exports) { ReportOutOfMemory(cx); return nullptr; } UniquePtr scopes = js::MakeUnique(cx->zone()); - if (!scopes || !scopes->init()) { + if (!scopes) { ReportOutOfMemory(cx); return nullptr; } @@ -1689,7 +1689,7 @@ WasmMemoryObject::getOrCreateObservers(JSContext* cx) { if (!hasObservers()) { auto observers = MakeUnique(cx->zone()); - if (!observers || !observers->init()) { + if (!observers) { ReportOutOfMemory(cx); return nullptr; } diff --git a/js/src/wasm/WasmTable.cpp b/js/src/wasm/WasmTable.cpp index dc230805d332..a21b51ee9297 100644 --- a/js/src/wasm/WasmTable.cpp +++ b/js/src/wasm/WasmTable.cpp @@ -172,10 +172,8 @@ Table::grow(uint32_t delta, JSContext* cx) PodZero(newArray + length_, delta); length_ = newLength.value(); - if (observers_.initialized()) { - for (InstanceSet::Range r = observers_.all(); !r.empty(); r.popFront()) - r.front()->instance().onMovingGrowTable(); - } + for (InstanceSet::Range r = observers_.all(); !r.empty(); r.popFront()) + r.front()->instance().onMovingGrowTable(); return oldLength; } @@ -191,11 +189,6 @@ Table::addMovingGrowObserver(JSContext* cx, WasmInstanceObject* instance) { MOZ_ASSERT(movingGrowable()); - if (!observers_.initialized() && !observers_.init()) { - ReportOutOfMemory(cx); - return false; - } - if (!observers_.putNew(instance)) { ReportOutOfMemory(cx); return false; diff --git a/js/src/wasm/WasmTextToBinary.cpp b/js/src/wasm/WasmTextToBinary.cpp index ac080790d2aa..8d4b41c15a52 100644 --- a/js/src/wasm/WasmTextToBinary.cpp +++ b/js/src/wasm/WasmTextToBinary.cpp @@ -4030,7 +4030,7 @@ ParseModule(const char16_t* text, uintptr_t stackLimit, LifoAlloc& lifo, UniqueC return nullptr; auto* module = new(c.lifo) AstModule(c.lifo); - if (!module || !module->init()) + if (!module) return nullptr; if (c.ts.peek().kind() == WasmToken::Text) { @@ -4172,16 +4172,6 @@ class Resolver typeMap_(lifo), targetStack_(lifo) {} - bool init() { - return funcTypeMap_.init() && - funcMap_.init() && - importMap_.init() && - tableMap_.init() && - memoryMap_.init() && - typeMap_.init() && - varMap_.init() && - globalMap_.init(); - } void beginFunc() { varMap_.clear(); MOZ_ASSERT(targetStack_.empty()); @@ -4722,9 +4712,6 @@ ResolveModule(LifoAlloc& lifo, AstModule* module, UniqueChars* error) { Resolver r(lifo, error); - if (!r.init()) - return false; - size_t numTypes = module->types().length(); for (size_t i = 0; i < numTypes; i++) { AstTypeDef* td = module->types()[i]; diff --git a/js/src/wasm/WasmValidate.cpp b/js/src/wasm/WasmValidate.cpp index 0ac987645df7..59a53738d6e1 100644 --- a/js/src/wasm/WasmValidate.cpp +++ b/js/src/wasm/WasmValidate.cpp @@ -1863,8 +1863,6 @@ DecodeExportSection(Decoder& d, ModuleEnvironment* env) return true; CStringSet dupSet; - if (!dupSet.init()) - return false; uint32_t numExports; if (!d.readVarU32(&numExports)) diff --git a/js/xpconnect/src/XPCMaps.h b/js/xpconnect/src/XPCMaps.h index 69d0f189ba5d..6f1cc7065bc6 100644 --- a/js/xpconnect/src/XPCMaps.h +++ b/js/xpconnect/src/XPCMaps.h @@ -34,14 +34,7 @@ class JSObject2WrappedJSMap public: static JSObject2WrappedJSMap* newMap(int length) { - auto* map = new JSObject2WrappedJSMap(); - if (!map->mTable.init(length)) { - // This is a decent estimate of the size of the hash table's - // entry storage. The |2| is because on average the capacity is - // twice the requested length. - NS_ABORT_OOM(length * 2 * sizeof(Map::Entry)); - } - return map; + return new JSObject2WrappedJSMap(length); } inline nsXPCWrappedJS* Find(JSObject* Obj) { @@ -94,7 +87,7 @@ public: size_t SizeOfWrappedJS(mozilla::MallocSizeOf mallocSizeOf) const; private: - JSObject2WrappedJSMap() {} + explicit JSObject2WrappedJSMap(size_t length) : mTable(length) {} Map mTable; }; @@ -506,14 +499,7 @@ class JSObject2JSObjectMap public: static JSObject2JSObjectMap* newMap(int length) { - auto* map = new JSObject2JSObjectMap(); - if (!map->mTable.init(length)) { - // This is a decent estimate of the size of the hash table's - // entry storage. The |2| is because on average the capacity is - // twice the requested length. - NS_ABORT_OOM(length * 2 * sizeof(Map::Entry)); - } - return map; + return new JSObject2JSObjectMap(length); } inline JSObject* Find(JSObject* key) { @@ -547,7 +533,7 @@ public: } private: - JSObject2JSObjectMap() {} + explicit JSObject2JSObjectMap(size_t length) : mTable(length) {} Map mTable; }; diff --git a/memory/replace/dmd/DMD.cpp b/memory/replace/dmd/DMD.cpp index a441dbbb6bef..28927f373d7b 100644 --- a/memory/replace/dmd/DMD.cpp +++ b/memory/replace/dmd/DMD.cpp @@ -585,8 +585,8 @@ class StringTable { public: StringTable() + : mSet(64) { - MOZ_ALWAYS_TRUE(mSet.init(64)); } const char* @@ -1131,8 +1131,8 @@ GatherUsedStackTraces(StackTraceSet& aStackTraces) MOZ_ASSERT(gStateLock->IsLocked()); MOZ_ASSERT(Thread::Fetch()->InterceptsAreBlocked()); - aStackTraces.finish(); - MOZ_ALWAYS_TRUE(aStackTraces.init(512)); + aStackTraces.clear(); + MOZ_ALWAYS_TRUE(aStackTraces.reserve(512)); for (auto iter = gLiveBlockTable->iter(); !iter.done(); iter.next()) { iter.get().AddStackTracesToTable(aStackTraces); @@ -1576,18 +1576,14 @@ Init(malloc_table_t* aMallocTable) { AutoLockState lock; - gStackTraceTable = InfallibleAllocPolicy::new_(); - MOZ_ALWAYS_TRUE(gStackTraceTable->init(8192)); - - gLiveBlockTable = InfallibleAllocPolicy::new_(); - MOZ_ALWAYS_TRUE(gLiveBlockTable->init(8192)); + gStackTraceTable = InfallibleAllocPolicy::new_(8192); + gLiveBlockTable = InfallibleAllocPolicy::new_(8192); // Create this even if the mode isn't Cumulative (albeit with a small // size), in case the mode is changed later on (as is done by SmokeDMD.cpp, // for example). - gDeadBlockTable = InfallibleAllocPolicy::new_(); size_t tableSize = gOptions->IsCumulativeMode() ? 8192 : 4; - MOZ_ALWAYS_TRUE(gDeadBlockTable->init(tableSize)); + gDeadBlockTable = InfallibleAllocPolicy::new_(tableSize); } return true; @@ -1712,9 +1708,9 @@ class ToIdStringConverter final { public: ToIdStringConverter() - : mNextId(0) + : mIdMap(512) + , mNextId(0) { - MOZ_ALWAYS_TRUE(mIdMap.init(512)); } // Converts a pointer to a unique ID. Reuses the existing ID for the pointer @@ -1829,11 +1825,8 @@ AnalyzeImpl(UniquePtr aWriter) // Allocate this on the heap instead of the stack because it's fairly large. auto locService = InfallibleAllocPolicy::new_(); - StackTraceSet usedStackTraces; - MOZ_ALWAYS_TRUE(usedStackTraces.init(512)); - - PointerSet usedPcs; - MOZ_ALWAYS_TRUE(usedPcs.init(512)); + StackTraceSet usedStackTraces(512); + PointerSet usedPcs(512); size_t iscSize; @@ -1910,8 +1903,7 @@ AnalyzeImpl(UniquePtr aWriter) if (!gOptions->IsScanMode()) { // At this point we typically have many LiveBlocks that differ only in // their address. Aggregate them to reduce the size of the output file. - AggregatedLiveBlockTable agg; - MOZ_ALWAYS_TRUE(agg.init(8192)); + AggregatedLiveBlockTable agg(8192); for (auto iter = gLiveBlockTable->iter(); !iter.done(); iter.next()) { const LiveBlock& b = iter.get(); b.AddStackTracesToTable(usedStackTraces); diff --git a/mfbt/HashTable.h b/mfbt/HashTable.h index 6d16a8a3c83c..ec4620a93d53 100644 --- a/mfbt/HashTable.h +++ b/mfbt/HashTable.h @@ -1,6 +1,6 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sts=4 et sw=4 tw=99: - * This Source Code Form is subject to the terms of the Mozilla Public +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ @@ -37,6 +37,9 @@ // - |InfallibleAllocPolicy| is another possibility; it allows the // abovementioned OOM checks to be done with MOZ_ALWAYS_TRUE(). // +// Note that entry storage allocation is lazy, and not done until the first +// lookupForAdd(), put(), or putNew() is performed. +// // See AllocPolicy.h for more details. // // Documentation on how to use HashMap and HashSet, including examples, is @@ -67,9 +70,6 @@ // - mozilla::HashTable has a default capacity on creation of 32 and a minimum // capacity of 4. PLDHashTable has a default capacity on creation of 8 and a // minimum capacity of 8. -// -// - mozilla::HashTable allocates memory eagerly. PLDHashTable delays -// allocating until the first element is inserted. #ifndef mozilla_HashTable_h #define mozilla_HashTable_h @@ -133,7 +133,6 @@ using Generation = Opaque; // Note: // - HashMap is not reentrant: Key/Value/HashPolicy/AllocPolicy members // called by HashMap must not call back into the same HashMap object. -// - Due to the lack of exception handling, the user must call |init()|. // templatevalue(); // using AddPtr = typename Impl::AddPtr; - MOZ_ALWAYS_INLINE AddPtr lookupForAdd(const Lookup& aLookup) const + MOZ_ALWAYS_INLINE AddPtr lookupForAdd(const Lookup& aLookup) { return mImpl.lookupForAdd(aLookup); } @@ -375,6 +379,12 @@ public: // not have been mutated in the interim. void remove(Ptr aPtr) { mImpl.remove(aPtr); } + // Remove all keys/values without changing the capacity. + void clear() { mImpl.clear(); } + + // Like clear() followed by compact(). + void clearAndCompact() { mImpl.clearAndCompact(); } + // -- Rekeying ------------------------------------------------------------- // Infallibly rekey one entry, if necessary. Requires that template @@ -428,18 +438,6 @@ public: using Range = typename Impl::Range; using Enum = typename Impl::Enum; Range all() const { return mImpl.all(); } - - // -- Clearing ------------------------------------------------------------- - - // Remove all keys/values without changing the capacity. - void clear() { mImpl.clear(); } - - // Remove all keys/values and attempt to minimize the capacity. - void clearAndShrink() { mImpl.clearAndShrink(); } - - // Remove all keys/values and release entry storage. The map must be - // initialized via init() again before further use. - void finish() { mImpl.finish(); } }; //--------------------------------------------------------------------------- @@ -456,7 +454,6 @@ public: // Note: // - HashSet is not reentrant: T/HashPolicy/AllocPolicy members called by // HashSet must not call back into the same HashSet object. -// - Due to the lack of exception handling, the user must call |init()|. // template, @@ -490,10 +487,14 @@ public: // -- Initialization ------------------------------------------------------- - // HashSet construction is fallible (due to possible OOM). The user must call - // init() after construction and check the return value. - explicit HashSet(AllocPolicy a = AllocPolicy()) - : mImpl(a) + explicit HashSet(AllocPolicy aAllocPolicy = AllocPolicy(), + uint32_t aLen = Impl::sDefaultLen) + : mImpl(aAllocPolicy, aLen) + { + } + + explicit HashSet(uint32_t aLen) + : mImpl(AllocPolicy(), aLen) { } @@ -508,15 +509,8 @@ public: mImpl = std::move(aRhs.mImpl); } - // Initialize the set for use. Must be called after construction, before - // any other operations (other than initialized()). - MOZ_MUST_USE bool init(uint32_t aLen = 16) { return mImpl.init(aLen); } - // -- Status and sizing ---------------------------------------------------- - // Has the set been initialized? - bool initialized() const { return mImpl.initialized(); } - // The set's current generation. Generation generation() const { return mImpl.generation(); } @@ -528,7 +522,7 @@ public: // Number of element slots in the set. Note: resize will happen well before // count() == capacity(). - size_t capacity() const { return mImpl.capacity(); } + uint32_t capacity() const { return mImpl.capacity(); } // The size of the set's entry storage, in bytes. If the elements contain // pointers to other heap blocks, you must iterate over the set and measure @@ -543,6 +537,14 @@ public: mImpl.shallowSizeOfExcludingThis(aMallocSizeOf); } + // Attempt to minimize the capacity(). If the table is empty, this will free + // the empty storage and upon regrowth it will be given the minimum capacity. + void compact() { mImpl.compact(); } + + // Attempt to reserve enough space to fit at least |aLen| elements. Does + // nothing if the map already has sufficient capacity. + MOZ_MUST_USE bool reserve(uint32_t aLen) { return mImpl.reserve(aLen); } + // -- Lookups -------------------------------------------------------------- // Does the set contain an element matching |aLookup|? @@ -651,7 +653,7 @@ public: // Note that relookupOrAdd(p,l,t) performs Lookup using |l| and adds the // entry |t|, where the caller ensures match(l,t). using AddPtr = typename Impl::AddPtr; - MOZ_ALWAYS_INLINE AddPtr lookupForAdd(const Lookup& aLookup) const + MOZ_ALWAYS_INLINE AddPtr lookupForAdd(const Lookup& aLookup) { return mImpl.lookupForAdd(aLookup); } @@ -684,6 +686,12 @@ public: // not have been mutated in the interim. void remove(Ptr aPtr) { mImpl.remove(aPtr); } + // Remove all keys/values without changing the capacity. + void clear() { mImpl.clear(); } + + // Like clear() followed by compact(). + void clearAndCompact() { mImpl.clearAndCompact(); } + // -- Rekeying ------------------------------------------------------------- // Infallibly rekey one entry, if present. Requires that template parameters @@ -750,18 +758,6 @@ public: using Range = typename Impl::Range; using Enum = typename Impl::Enum; Range all() const { return mImpl.all(); } - - // -- Clearing ------------------------------------------------------------- - - // Remove all elements without changing the capacity. - void clear() { mImpl.clear(); } - - // Remove all elements and attempt to minimize the capacity. - void clearAndShrink() { mImpl.clearAndShrink(); } - - // Remove all keys/values and release entry storage. The set must be - // initialized via init() again before further use. - void finish() { mImpl.finish(); } }; //--------------------------------------------------------------------------- @@ -1452,7 +1448,7 @@ public: } if (mRemoved) { - mTable.compactIfUnderloaded(); + mTable.compact(); } } }; @@ -1539,7 +1535,7 @@ private: HashTable(const HashTable&) = delete; void operator=(const HashTable&) = delete; - static const size_t CAP_BITS = 30; + static const uint32_t CAP_BITS = 30; public: uint64_t mGen : 56; // entry storage generation number @@ -1555,6 +1551,7 @@ public: // The default initial capacity is 32 (enough to hold 16 elements), but it // can be as low as 4. + static const uint32_t sDefaultLen = 16; static const uint32_t sMinCapacity = 4; static const uint32_t sMaxInit = 1u << (CAP_BITS - 1); static const uint32_t sMaxCapacity = 1u << CAP_BITS; @@ -1569,9 +1566,40 @@ public: static const HashNumber sRemovedKey = Entry::sRemovedKey; static const HashNumber sCollisionBit = Entry::sCollisionBit; - void setTableSizeLog2(uint32_t aSizeLog2) + static uint32_t bestCapacity(uint32_t aLen) { - mHashShift = kHashNumberBits - aSizeLog2; + static_assert((sMaxInit * sAlphaDenominator) / sAlphaDenominator == + sMaxInit, + "multiplication in numerator below could overflow"); + static_assert(sMaxInit * sAlphaDenominator <= + UINT32_MAX - sMaxAlphaNumerator, + "numerator calculation below could potentially overflow"); + + // Compute the smallest capacity allowing |aLen| elements to be + // inserted without rehashing: ceil(aLen / max-alpha). (Ceiling + // integral division: .) + uint32_t capacity = + (aLen * sAlphaDenominator + sMaxAlphaNumerator - 1) / sMaxAlphaNumerator; + capacity = (capacity < sMinCapacity) + ? sMinCapacity + : RoundUpPow2(capacity); + + MOZ_ASSERT(capacity >= aLen); + MOZ_ASSERT(capacity <= sMaxCapacity); + + return capacity; + } + + static uint32_t hashShift(uint32_t aLen) + { + // Reject all lengths whose initial computed capacity would exceed + // sMaxCapacity. Round that maximum aLen down to the nearest power of two + // for speedier code. + if (MOZ_UNLIKELY(aLen > sMaxInit)) { + MOZ_CRASH("initial length is too large"); + } + + return kHashNumberBits - mozilla::CeilingLog2(bestCapacity(aLen)); } static bool isLiveHash(HashNumber aHash) { return Entry::isLiveHash(aHash); } @@ -1631,10 +1659,10 @@ public: } public: - explicit HashTable(AllocPolicy aAllocPolicy) + HashTable(AllocPolicy aAllocPolicy, uint32_t aLen) : AllocPolicy(aAllocPolicy) , mGen(0) - , mHashShift(kHashNumberBits) + , mHashShift(hashShift(aLen)) , mTable(nullptr) , mEntryCount(0) , mRemovedCount(0) @@ -1645,51 +1673,11 @@ public: { } - MOZ_MUST_USE bool init(uint32_t aLen) + explicit HashTable(AllocPolicy aAllocPolicy) + : HashTable(aAllocPolicy, sDefaultLen) { - MOZ_ASSERT(!initialized()); - - // Reject all lengths whose initial computed capacity would exceed - // sMaxCapacity. Round that maximum aLen down to the nearest power of two - // for speedier code. - if (MOZ_UNLIKELY(aLen > sMaxInit)) { - this->reportAllocOverflow(); - return false; - } - - static_assert((sMaxInit * sAlphaDenominator) / sAlphaDenominator == - sMaxInit, - "multiplication in numerator below could overflow"); - static_assert(sMaxInit * sAlphaDenominator <= - UINT32_MAX - sMaxAlphaNumerator, - "numerator calculation below could potentially overflow"); - - // Compute the smallest capacity allowing |aLen| elements to be - // inserted without rehashing: ceil(aLen / max-alpha). (Ceiling - // integral division: .) - uint32_t newCapacity = - (aLen * sAlphaDenominator + sMaxAlphaNumerator - 1) / sMaxAlphaNumerator; - if (newCapacity < sMinCapacity) { - newCapacity = sMinCapacity; - } - - // Round up capacity to next power-of-two. - uint32_t log2 = mozilla::CeilingLog2(newCapacity); - newCapacity = 1u << log2; - - MOZ_ASSERT(newCapacity >= aLen); - MOZ_ASSERT(newCapacity <= sMaxCapacity); - - mTable = createTable(*this, newCapacity); - if (!mTable) { - return false; - } - setTableSizeLog2(log2); - return true; } - bool initialized() const { return !!mTable; } - ~HashTable() { if (mTable) { @@ -1720,10 +1708,14 @@ private: return (aHash1 - aDoubleHash.mHash2) & aDoubleHash.mSizeMask; } + // True if the current load is equal to or exceeds the maximum. bool overloaded() { static_assert(sMaxCapacity <= UINT32_MAX / sMaxAlphaNumerator, "multiplication below could overflow"); + + // Note: if capacity() is zero, this will always succeed, which is + // what we want. return mEntryCount + mRemovedCount >= capacity() * sMaxAlphaNumerator / sAlphaDenominator; } @@ -1843,14 +1835,17 @@ private: RehashFailed }; - RebuildStatus changeTableSize(int aDeltaLog2, + RebuildStatus changeTableSize(uint32_t newCapacity, FailureBehavior aReportFailure = ReportFailure) { + MOZ_ASSERT(IsPowerOfTwo(newCapacity)); + MOZ_ASSERT(!!mTable == !!capacity()); + // Look, but don't touch, until we succeed in getting new entry store. Entry* oldTable = mTable; - uint32_t oldCap = capacity(); - uint32_t newLog2 = kHashNumberBits - mHashShift + aDeltaLog2; - uint32_t newCapacity = 1u << newLog2; + uint32_t oldCapacity = capacity(); + uint32_t newLog2 = mozilla::CeilingLog2(newCapacity); + if (MOZ_UNLIKELY(newCapacity > sMaxCapacity)) { if (aReportFailure) { this->reportAllocOverflow(); @@ -1864,13 +1859,13 @@ private: } // We can't fail from here on, so update table parameters. - setTableSizeLog2(newLog2); + mHashShift = kHashNumberBits - newLog2; mRemovedCount = 0; mGen++; mTable = newTable; // Copy only live entries, leaving removed ones behind. - Entry* end = oldTable + oldCap; + Entry* end = oldTable + oldCapacity; for (Entry* src = oldTable; src < end; ++src) { if (src->isLive()) { HashNumber hn = src->getKeyHash(); @@ -1882,13 +1877,16 @@ private: } // All entries have been destroyed, no need to destroyTable. - this->free_(oldTable, oldCap); + this->free_(oldTable, oldCapacity); return Rehashed; } bool shouldCompressTable() { - // Compress if a quarter or more of all entries are removed. + // Succeed if a quarter or more of all entries are removed. Note that this + // always succeeds if capacity() == 0 (i.e. entry storage has not been + // allocated), which is what we want, because it means changeTableSize() + // will allocate the requested capacity rather than doubling it. return mRemovedCount >= (capacity() >> 2); } @@ -1898,8 +1896,10 @@ private: return NotOverloaded; } - int deltaLog2 = shouldCompressTable() ? 0 : 1; - return changeTableSize(deltaLog2, aReportFailure); + uint32_t newCapacity = shouldCompressTable() + ? rawCapacity() + : rawCapacity() * 2; + return changeTableSize(newCapacity, aReportFailure); } // Infallibly rehash the table if we are overloaded with removals. @@ -1931,24 +1931,7 @@ private: void checkUnderloaded() { if (underloaded()) { - (void)changeTableSize(-1, DontReportFailure); - } - } - - // Resize the table down to the largest capacity which doesn't underload the - // table. Since we call checkUnderloaded() on every remove, you only need - // to call this after a bulk removal of items done without calling remove(). - void compactIfUnderloaded() - { - int32_t resizeLog2 = 0; - uint32_t newCapacity = capacity(); - while (wouldBeUnderloaded(newCapacity, mEntryCount)) { - newCapacity = newCapacity >> 1; - resizeLog2--; - } - - if (resizeLog2 != 0) { - (void)changeTableSize(resizeLog2, DontReportFailure); + (void)changeTableSize(capacity() / 2, DontReportFailure); } } @@ -1961,10 +1944,10 @@ private: { mRemovedCount = 0; mGen++; - for (size_t i = 0; i < capacity(); ++i) { + for (uint32_t i = 0; i < capacity(); ++i) { mTable[i].unsetCollision(); } - for (size_t i = 0; i < capacity();) { + for (uint32_t i = 0; i < capacity();) { Entry* src = &mTable[i]; if (!src->isLive() || src->hasCollision()) { @@ -2035,70 +2018,88 @@ public: #endif } - void clearAndShrink() + // Resize the table down to the smallest capacity that doesn't overload the + // table. Since we call checkUnderloaded() on every remove, you only need + // to call this after a bulk removal of items done without calling remove(). + void compact() { - clear(); - compactIfUnderloaded(); - } - - void finish() - { -#ifdef DEBUG - MOZ_ASSERT(!mEntered); -#endif - if (!mTable) { + if (empty()) { + // Free the entry storage. + this->free_(mTable, capacity()); + mGen++; + mHashShift = hashShift(0); // gives minimum capacity on regrowth + mTable = nullptr; + mRemovedCount = 0; return; } - destroyTable(*this, mTable, capacity()); - mTable = nullptr; - mGen++; - mEntryCount = 0; - mRemovedCount = 0; -#ifdef DEBUG - mMutationCount++; -#endif + uint32_t bestCapacity = this->bestCapacity(mEntryCount); + MOZ_ASSERT(bestCapacity <= capacity()); + + if (bestCapacity < capacity()) { + (void)changeTableSize(bestCapacity, DontReportFailure); + } + } + + void clearAndCompact() + { + clear(); + compact(); + } + + MOZ_MUST_USE bool reserve(uint32_t aLen) + { + if (aLen == 0) { + return true; + } + + uint32_t bestCapacity = this->bestCapacity(aLen); + if (bestCapacity <= capacity()) { + return true; // Capacity is already sufficient. + } + + RebuildStatus status = changeTableSize(bestCapacity, DontReportFailure); + MOZ_ASSERT(status != NotOverloaded); + return status != RehashFailed; } Iterator iter() const { - MOZ_ASSERT(mTable); return Iterator(*this); } ModIterator modIter() { - MOZ_ASSERT(mTable); return ModIterator(*this); } Range all() const { - MOZ_ASSERT(mTable); return Range(*this); } bool empty() const { - MOZ_ASSERT(mTable); - return !mEntryCount; + return mEntryCount == 0; } uint32_t count() const { - MOZ_ASSERT(mTable); return mEntryCount; } + uint32_t rawCapacity() const + { + return 1u << (kHashNumberBits - mHashShift); + } + uint32_t capacity() const { - MOZ_ASSERT(mTable); - return 1u << (kHashNumberBits - mHashShift); + return mTable ? rawCapacity() : 0; } Generation generation() const { - MOZ_ASSERT(mTable); return Generation(mGen); } @@ -2112,31 +2113,37 @@ public: return aMallocSizeOf(this) + shallowSizeOfExcludingThis(aMallocSizeOf); } + MOZ_ALWAYS_INLINE Ptr readonlyThreadsafeLookup(const Lookup& aLookup) const + { + if (!mTable || !HasHash(aLookup)) { + return Ptr(); + } + HashNumber keyHash = prepareHash(aLookup); + return Ptr(lookup(aLookup, keyHash), *this); + } + MOZ_ALWAYS_INLINE Ptr lookup(const Lookup& aLookup) const { ReentrancyGuard g(*this); - if (!HasHash(aLookup)) { - return Ptr(); - } - HashNumber keyHash = prepareHash(aLookup); - return Ptr(lookup(aLookup, keyHash), *this); + return readonlyThreadsafeLookup(aLookup); } - MOZ_ALWAYS_INLINE Ptr readonlyThreadsafeLookup(const Lookup& aLookup) const - { - if (!HasHash(aLookup)) { - return Ptr(); - } - HashNumber keyHash = prepareHash(aLookup); - return Ptr(lookup(aLookup, keyHash), *this); - } - - MOZ_ALWAYS_INLINE AddPtr lookupForAdd(const Lookup& aLookup) const + MOZ_ALWAYS_INLINE AddPtr lookupForAdd(const Lookup& aLookup) { ReentrancyGuard g(*this); if (!EnsureHash(aLookup)) { return AddPtr(); } + + if (!mTable) { + uint32_t newCapacity = rawCapacity(); + RebuildStatus status = changeTableSize(newCapacity, ReportFailure); + MOZ_ASSERT(status != NotOverloaded); + if (status == RehashFailed) { + return AddPtr(); + } + } + HashNumber keyHash = prepareHash(aLookup); // Directly call the constructor in the return statement to avoid // excess copying when building with Visual Studio 2017. @@ -2148,7 +2155,7 @@ public: MOZ_MUST_USE bool add(AddPtr& aPtr, Args&&... aArgs) { ReentrancyGuard g(*this); - MOZ_ASSERT(mTable); + MOZ_ASSERT_IF(aPtr.isValid(), mTable); MOZ_ASSERT_IF(aPtr.isValid(), aPtr.mTable == this); MOZ_ASSERT(!aPtr.found()); MOZ_ASSERT(!(aPtr.mKeyHash & sCollisionBit)); diff --git a/security/manager/ssl/security-prefs.js b/security/manager/ssl/security-prefs.js index 377f55c8a3b4..b35f2aedca78 100644 --- a/security/manager/ssl/security-prefs.js +++ b/security/manager/ssl/security-prefs.js @@ -4,7 +4,7 @@ pref("security.tls.version.min", 1); pref("security.tls.version.max", 4); -pref("security.tls.version.fallback-limit", 3); +pref("security.tls.version.fallback-limit", 4); pref("security.tls.insecure_fallback_hosts", ""); pref("security.tls.enable_0rtt_data", false); diff --git a/xpcom/rust/gtest/bench-collections/Bench.cpp b/xpcom/rust/gtest/bench-collections/Bench.cpp index 4bddf61c9bb7..221fea8e826a 100644 --- a/xpcom/rust/gtest/bench-collections/Bench.cpp +++ b/xpcom/rust/gtest/bench-collections/Bench.cpp @@ -174,7 +174,6 @@ void Bench_Cpp_MozHashSet(const Params* aParams, void** aVals, size_t aLen) { mozilla::HashSet, MallocAllocPolicy> hs; - MOZ_RELEASE_ASSERT(hs.init()); for (size_t j = 0; j < aParams->mNumInserts; j++) { auto p = hs.lookupForAdd(aVals[j]);