This commit is contained in:
Ryan VanderMeulen 2017-05-24 16:32:59 -04:00
Родитель 41511c5371 dfcc5830e0
Коммит 30caacbb11
689 изменённых файлов: 16630 добавлений и 15161 удалений

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

@ -7112,7 +7112,8 @@ var gIdentityHandler = {
this._sharingState = tab._sharingState;
if (this._identityPopup.state == "open") {
this._handleHeightChange(() => this.updateSitePermissions());
this.updateSitePermissions();
this._identityPopupMultiView.descriptionHeightWorkaround();
}
},
@ -7623,20 +7624,6 @@ var gIdentityHandler = {
}
},
_handleHeightChange(aFunction, aWillShowReloadHint) {
let heightBefore = getComputedStyle(this._permissionList).height;
aFunction();
let heightAfter = getComputedStyle(this._permissionList).height;
// Showing the reload hint increases the height, we need to account for it.
if (aWillShowReloadHint) {
heightAfter = parseInt(heightAfter) +
parseInt(getComputedStyle(this._permissionList.nextSibling).height);
}
let heightChange = parseInt(heightAfter) - parseInt(heightBefore);
if (heightChange)
this._identityPopupMultiView.setHeightToFit(heightChange);
},
_createPermissionItem(aPermission) {
let container = document.createElement("hbox");
container.setAttribute("class", "identity-popup-permission-item");
@ -7673,9 +7660,7 @@ var gIdentityHandler = {
button.setAttribute("tooltiptext", tooltiptext);
button.addEventListener("command", () => {
let browser = gBrowser.selectedBrowser;
// Only resize the window if the reload hint was previously hidden.
this._handleHeightChange(() => this._permissionList.removeChild(container),
this._permissionReloadHint.hasAttribute("hidden"));
this._permissionList.removeChild(container);
if (aPermission.inUse &&
["camera", "microphone", "screen"].includes(aPermission.id)) {
let windowId = this._sharingState.windowId;
@ -7706,6 +7691,7 @@ var gIdentityHandler = {
SitePermissions.remove(gBrowser.currentURI, aPermission.id, browser);
this._permissionReloadHint.removeAttribute("hidden");
this._identityPopupMultiView.descriptionHeightWorkaround();
// Set telemetry values for clearing a permission
let histogram = Services.telemetry.getKeyedHistogramById("WEB_PERMISSION_CLEARED");

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

@ -16,7 +16,8 @@
</broadcasterset>
<panelmultiview id="identity-popup-multiView"
mainViewId="identity-popup-mainView">
mainViewId="identity-popup-mainView"
descriptionheightworkaround="true">
<panelview id="identity-popup-mainView" flex="1">
<!-- Security Section -->
@ -96,7 +97,7 @@
</panelview>
<!-- Security SubView -->
<panelview id="identity-popup-securityView" flex="1">
<panelview id="identity-popup-securityView">
<vbox id="identity-popup-securityView-header">
<label class="plain">
<label class="identity-popup-headline identity-popup-host"></label>
@ -108,7 +109,7 @@
when-connection="secure secure-ev">&identity.connectionSecure;</description>
</vbox>
<vbox id="identity-popup-securityView-body" flex="1">
<vbox id="identity-popup-securityView-body" class="panel-view-body-unscrollable">
<!-- (EV) Certificate Information -->
<description id="identity-popup-content-verified-by"
when-connection="secure-ev">&identity.connectionVerified2;</description>

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

@ -171,20 +171,6 @@ this.PanelMultiView = class {
return this.node.getAttribute("mainViewIsSubView") == "true";
}
get ignoreMutations() {
return this._ignoreMutations;
}
set ignoreMutations(val) {
this._ignoreMutations = val;
if (!val && this._panel.state == "open") {
if (this.showingSubView) {
this._syncContainerWithSubView();
} else {
this._syncContainerWithMainView();
}
}
}
get _transitioning() {
return this.__transitioning;
}
@ -264,13 +250,6 @@ this.PanelMultiView = class {
} else {
this._panel.addEventListener("popupshown", this);
this._clickCapturer.addEventListener("click", this);
this._subViews.addEventListener("overflow", this);
this._mainViewContainer.addEventListener("overflow", this);
// Get a MutationObserver ready to react to subview size changes. We
// only attach this MutationObserver when a subview is being displayed.
this._subViewObserver = new window.MutationObserver(this._syncContainerWithSubView.bind(this));
this._mainViewObserver = new window.MutationObserver(this._syncContainerWithMainView.bind(this));
this._mainViewContainer.setAttribute("panelid", this._panel.id);
@ -290,7 +269,8 @@ this.PanelMultiView = class {
set: (val) => this[property] = val
});
});
["goBack", "setHeightToFit", "setMainView", "showMainView", "showSubView"].forEach(method => {
["goBack", "descriptionHeightWorkaround", "setMainView", "showMainView",
"showSubView"].forEach(method => {
Object.defineProperty(this.node, method, {
enumerable: true,
value: (...args) => this[method](...args)
@ -305,10 +285,6 @@ this.PanelMultiView = class {
if (this.panelViews) {
this.panelViews.clear();
} else {
this._mainViewObserver.disconnect();
this._subViewObserver.disconnect();
this._subViews.removeEventListener("overflow", this);
this._mainViewContainer.removeEventListener("overflow", this);
this._clickCapturer.removeEventListener("click", this);
}
this._panel.removeEventListener("popupshowing", this);
@ -345,7 +321,6 @@ this.PanelMultiView = class {
}
} else {
if (this._mainView) {
this._mainViewObserver.disconnect();
this._subViews.appendChild(this._mainView);
this._mainView.removeAttribute("mainview");
}
@ -364,14 +339,11 @@ this.PanelMultiView = class {
let evt = new this.window.CustomEvent("ViewHiding", { bubbles: true, cancelable: true });
viewNode.dispatchEvent(evt);
viewNode.removeAttribute("current");
this._currentSubView = null;
this._subViewObserver.disconnect();
this._setViewContainerHeight(this._mainViewHeight);
this.node.setAttribute("viewtype", "main");
this._transitionHeight(() => {
viewNode.removeAttribute("current");
this._currentSubView = null;
this.node.setAttribute("viewtype", "main");
});
}
this._shiftMainView();
@ -479,9 +451,9 @@ this.PanelMultiView = class {
//
// All three of these actions make use of CSS transformations, so they
// should all occur simultaneously.
this.node.setAttribute("viewtype", "subview");
if (this.panelViews && playTransition) {
this.node.setAttribute("viewtype", "subview");
// Sliding the next subview in means that the previous panelview stays
// where it is and the active panelview slides in from the left in LTR
// mode, right in RTL mode.
@ -604,34 +576,86 @@ this.PanelMultiView = class {
});
}, { once: true });
} else if (!this.panelViews) {
this._shiftMainView(aAnchor);
this._mainViewHeight = this._viewStack.clientHeight;
let newHeight = this._heightOfSubview(viewNode, this._subViews);
this._setViewContainerHeight(newHeight);
this._subViewObserver.observe(viewNode, {
attributes: true,
characterData: true,
childList: true,
subtree: true
this._transitionHeight(() => {
viewNode.setAttribute("current", true);
this.node.setAttribute("viewtype", "subview");
// Now that the subview is visible, we can check the height of the
// description elements it contains.
this.descriptionHeightWorkaround(viewNode);
});
this._shiftMainView(aAnchor);
}
})();
}
_setViewContainerHeight(aHeight) {
let container = this._viewContainer;
this._transitioning = true;
/**
* Applies the height transition for which <panelmultiview> is designed.
*
* The height transition involves two elements, the viewContainer and its only
* immediate child the viewStack. In order for this to work correctly, the
* viewContainer must have "overflow: hidden;" and the two elements must have
* no margins or padding. This means that the height of the viewStack is never
* limited by the viewContainer, but when the height of the container is not
* constrained it matches the height of the viewStack.
*
* @param changeFn
* This synchronous function is called to make the DOM changes
* that will result in a new height of the viewStack.
*/
_transitionHeight(changeFn) {
if (this._panel.state != "open") {
changeFn();
return;
}
let onTransitionEnd = () => {
container.removeEventListener("transitionend", onTransitionEnd);
this._transitioning = false;
};
// Lock the dimensions of the window that hosts the popup panel. This
// in turn constrains the height of the viewContainer.
let rect = this._panel.popupBoxObject.getOuterScreenRect();
this._panel.setAttribute("width", rect.width);
this._panel.setAttribute("height", rect.height);
container.addEventListener("transitionend", onTransitionEnd);
container.style.height = `${aHeight}px`;
// Read the current height of the viewStack. If we are in the middle
// of a transition, this is the actual height of the element at this
// point in time.
let oldHeight = this._dwu.getBoundsWithoutFlushing(this._viewStack).height;
// Make the necessary DOM changes, and remove the "height" property of the
// viewStack to ensure that we read its final value even if we are in the
// middle of a transition. To avoid flickering, we have to prevent the panel
// from being painted in this temporary state, which requires a synchronous
// layout when reading the new height.
this._viewStack.style.removeProperty("height");
changeFn();
let newHeight = this._viewStack.getBoundingClientRect().height;
// Now we can allow the popup panel to resize again. This must occur
// in the same tick as the code below, but we can do this before
// setting the starting height in case the transition is not needed.
this._panel.removeAttribute("width");
this._panel.removeAttribute("height");
if (oldHeight != newHeight) {
// Height transitions can only occur between two numeric values, and
// cannot start if the height is not set. In case a transition is
// needed, we have to set the height to the old value, then force a
// synchronous layout so the panel won't resize unexpectedly.
this._viewStack.style.height = oldHeight + "px";
this._viewStack.getBoundingClientRect().height;
// We can now set the new height to start the transition, but
// before doing that we set up a listener to reset the height to
// "auto" at the end, so that DOM changes made after the
// transition ends are still reflected by the height of the panel.
let onTransitionEnd = event => {
if (event.target != this._viewStack) {
return;
}
this._viewStack.removeEventListener("transitionend", onTransitionEnd);
this._viewStack.style.removeProperty("height");
};
this._viewStack.addEventListener("transitionend", onTransitionEnd);
this._viewStack.style.height = newHeight + "px";
}
}
_shiftMainView(aAnchor) {
@ -687,16 +711,6 @@ this.PanelMultiView = class {
case "mousemove":
this._resetKeyNavigation();
break;
case "overflow":
if (!this.panelViews && aEvent.target.localName == "vbox") {
// Resize the right view on the next tick.
if (this.showingSubView) {
this.window.setTimeout(this._syncContainerWithSubView.bind(this), 0);
} else if (!this.transitioning) {
this.window.setTimeout(this._syncContainerWithMainView.bind(this), 0);
}
}
break;
case "popupshowing":
this.node.setAttribute("panelopen", "true");
// Bug 941196 - The panel can get taller when opening a subview. Disabling
@ -705,30 +719,46 @@ this.PanelMultiView = class {
// direction that the panel originally opened in. This property resets
// every time the popup closes, which is why we have to set it each time.
this._panel.autoPosition = false;
if (!this.panelViews) {
this._syncContainerWithMainView();
this._mainViewObserver.observe(this._mainView, {
attributes: true,
characterData: true,
childList: true,
subtree: true
});
} else {
if (this.panelViews) {
this.window.addEventListener("keydown", this);
this._panel.addEventListener("mousemove", this);
}
break;
case "popupshown":
this._setMaxHeight();
// Now that the main view is visible, we can check the height of the
// description elements it contains.
this.descriptionHeightWorkaround();
// Now that the panel has opened, we can compute the distance from its
// anchor to the available margin of the screen, based on whether the
// panel actually opened towards the top or the bottom. We use this to
// limit its maximum height, which is relevant when opening a subview.
let maxHeight;
if (this._panel.alignmentPosition.startsWith("before_")) {
maxHeight = this._panel.getOuterScreenRect().bottom -
this.window.screen.availTop;
} else {
maxHeight = this.window.screen.availTop +
this.window.screen.availHeight -
this._panel.getOuterScreenRect().top;
}
// To go from the maximum height of the panel to the maximum height of
// the view stack, we start by subtracting the height of the arrow box.
// We don't need to trigger a new layout because this does not change.
let arrowBox = this.document.getAnonymousElementByAttribute(
this._panel, "anonid", "arrowbox");
maxHeight -= this._dwu.getBoundsWithoutFlushing(arrowBox).height;
// We subtract a fixed margin to account for variable borders. We don't
// try to measure this accurately so it's faster, we don't depend on
// the arrowpanel structure, and we don't hit rounding errors. Instead,
// we use a value that is much greater than the typical borders and
// makes sense visually.
const EXTRA_MARGIN_PX = 8;
this._viewStack.style.maxHeight = (maxHeight - EXTRA_MARGIN_PX) + "px";
break;
case "popuphidden":
this.node.removeAttribute("panelopen");
this._mainView.style.removeProperty("height");
this.showMainView();
if (!this.panelViews) {
this._mainViewObserver.disconnect();
} else {
if (this.panelViews) {
this.window.removeEventListener("keydown", this);
this._panel.removeEventListener("mousemove", this);
this._resetKeyNavigation();
@ -872,133 +902,47 @@ this.PanelMultiView = class {
return buttons;
}
_shouldSetPosition() {
return this.node.getAttribute("nosubviews") == "true";
}
_shouldSetHeight() {
return this.node.getAttribute("nosubviews") != "true";
}
_setMaxHeight() {
if (!this._shouldSetHeight())
return;
// Ignore the mutation that'll fire when we set the height of
// the main view.
this.ignoreMutations = true;
this._mainView.style.height = this.node.getBoundingClientRect().height + "px";
this.ignoreMutations = false;
}
_adjustContainerHeight() {
if (!this.ignoreMutations && !this.showingSubView && !this._transitioning) {
let height;
if (this.showingSubViewAsMainView) {
height = this._heightOfSubview(this._mainView);
} else {
height = this._mainView.scrollHeight;
}
this._viewContainer.style.height = height + "px";
}
}
_syncContainerWithSubView() {
// Check that this panel is still alive:
if (!this._panel || !this._panel.parentNode) {
return;
}
if (!this.ignoreMutations && this.showingSubView) {
let newHeight = this._heightOfSubview(this._currentSubView, this._subViews);
this._viewContainer.style.height = newHeight + "px";
}
}
_syncContainerWithMainView() {
// Check that this panel is still alive:
if (!this._panel || !this._panel.parentNode) {
return;
}
if (this._shouldSetPosition()) {
this._panel.adjustArrowPosition();
}
if (this._shouldSetHeight()) {
this._adjustContainerHeight();
}
}
/**
* Call this when the height of one of your views (the main view or a
* subview) changes and you want the heights of the multiview and panel
* to be the same as the view's height.
* If the caller can give a hint of the expected height change with the
* optional aExpectedChange parameter, it prevents flicker.
* If the main view or a subview contains wrapping elements, the attribute
* "descriptionheightworkaround" should be set on the view to force all the
* "description" elements to a fixed height. If the attribute is set and the
* visibility, contents, or width of any of these elements changes, this
* function should be called to refresh the calculated heights.
*
* @note While both "label" and "description" elements may contain wrapping
* text, only "description" elements are used that way in panels.
*
* @param viewNode
* Indicates the node to scan for descendant elements. This is the main
* view if omitted.
*/
setHeightToFit(aExpectedChange) {
// Set the max-height to zero, wait until the height is actually
// updated, and then remove it. If it's not removed, weird things can
// happen, like widgets in the panel won't respond to clicks even
// though they're visible.
const {window} = this;
let count = 5;
let height = window.getComputedStyle(this.node).height;
if (aExpectedChange)
this.node.style.maxHeight = (parseInt(height, 10) + aExpectedChange) + "px";
else
this.node.style.maxHeight = "0";
let interval = window.setInterval(() => {
if (height != window.getComputedStyle(this.node).height || --count == 0) {
window.clearInterval(interval);
this.node.style.removeProperty("max-height");
}
}, 0);
}
descriptionHeightWorkaround(viewNode = this._mainView) {
if (!this.node.hasAttribute("descriptionheightworkaround")) {
// This view does not require the workaround.
return;
}
_heightOfSubview(aSubview, aContainerToCheck) {
function getFullHeight(element) {
// XXXgijs: unfortunately, scrollHeight rounds values, and there's no alternative
// that works with overflow: auto elements. Fortunately for us,
// we have exactly 1 (potentially) scrolling element in here (the subview body),
// and rounding 1 value is OK - rounding more than 1 and adding them means we get
// off-by-1 errors. Now we might be off by a subpixel, but we care less about that.
// So, use scrollHeight *only* if the element is vertically scrollable.
let height;
let elementCS;
if (element.scrollTopMax) {
height = element.scrollHeight;
// Bounding client rects include borders, scrollHeight doesn't:
elementCS = win.getComputedStyle(element);
height += parseFloat(elementCS.borderTopWidth) +
parseFloat(elementCS.borderBottomWidth);
} else {
height = element.getBoundingClientRect().height;
if (height > 0) {
elementCS = win.getComputedStyle(element);
}
// We batch DOM changes together in order to reduce synchronous layouts.
// First we reset any change we may have made previously. The first time
// this is called, and in the best case scenario, this has no effect.
let items = [];
for (let element of viewNode.getElementsByTagName("description")) {
element.style.removeProperty("height");
items.push({ element });
}
// We now read the computed style to store the height of any element that
// may contain wrapping text, which will be zero if the element is hidden.
// This might trigger a synchronous layout, but if this function was called
// from a _transitionHeight callback and there are no description elements
// visible, then _transitionHeight will not trigger a layout again.
for (let item of items) {
item.height = item.element.getBoundingClientRect().height;
}
// Now we can make all the necessary DOM changes at once.
for (let item of items) {
if (item.height) {
item.element.style.height = item.height + "px";
}
if (elementCS) {
// Include margins - but not borders or paddings because they
// were dealt with above.
height += parseFloat(elementCS.marginTop) + parseFloat(elementCS.marginBottom);
}
return height;
}
let win = aSubview.ownerGlobal;
let body = aSubview.querySelector(".panel-subview-body");
let height = getFullHeight(body || aSubview);
if (body) {
let header = aSubview.querySelector(".panel-subview-header");
let footer = aSubview.querySelector(".panel-subview-footer");
height += (header ? getFullHeight(header) : 0) +
(footer ? getFullHeight(footer) : 0);
}
if (aContainerToCheck) {
let containerCS = win.getComputedStyle(aContainerToCheck);
height += parseFloat(containerCS.paddingTop) + parseFloat(containerCS.paddingBottom);
}
return Math.ceil(height);
}
}

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

@ -6,20 +6,21 @@
pointer-events: none;
}
.panel-mainview,
.panel-viewcontainer,
.panel-viewstack {
.panel-viewcontainer {
overflow: hidden;
}
.panel-viewstack {
position: relative;
transition: height var(--panelui-subview-transition-duration);
}
.panel-subviews {
-moz-stack-sizing: ignore;
-moz-stack-sizing: ignore-horizontal;
transform: translateX(0);
overflow-y: auto;
}
.panel-viewstack[viewtype="main"] > .panel-subviews {
-moz-stack-sizing: ignore;
}
.panel-subviews[panelopen] {

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

@ -18,7 +18,7 @@
<stylesheet src="chrome://browser/content/customizableui/panelUI.css"/>
</resources>
<content>
<xul:box anonid="viewContainer" class="panel-viewcontainer" xbl:inherits="panelopen,viewtype,transitioning">
<xul:vbox anonid="viewContainer" class="panel-viewcontainer" xbl:inherits="panelopen,viewtype,transitioning">
<xul:stack anonid="viewStack" xbl:inherits="viewtype,transitioning" class="panel-viewstack">
<xul:vbox anonid="mainViewContainer" class="panel-mainview" xbl:inherits="viewtype"/>
@ -37,18 +37,18 @@
<children includes="panelview"/>
</xul:vbox>
</xul:stack>
</xul:box>
</xul:vbox>
</content>
<implementation>
<constructor><![CDATA[
const {PanelMultiView} = Components.utils.import("resource:///modules/PanelMultiView.jsm", {});
this.instance = new PanelMultiView(this);
]]></constructor>
<destructor><![CDATA[
]]></constructor>
<destructor><![CDATA[
this.instance.destructor();
]]></destructor>
</implementation>
]]></destructor>
</implementation>
</binding>
<binding id="photonpanelmultiview" extends="chrome://browser/content/customizableui/panelUI.xml#panelmultiview">

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

@ -303,20 +303,6 @@ const DownloadsPanel = {
case "keypress":
this._onKeyPress(aEvent);
break;
case "popupshown":
if (this.setHeightToFitOnShow) {
this.setHeightToFitOnShow = false;
this.setHeightToFit();
}
break;
}
},
setHeightToFit() {
if (this._state == this.kStateShown) {
DownloadsBlockedSubview.view.setHeightToFit();
} else {
this.setHeightToFitOnShow = true;
}
},
@ -406,8 +392,6 @@ const DownloadsPanel = {
// Handle keypress to be able to preventDefault() events before they reach
// the richlistbox, for keyboard navigation.
this.panel.addEventListener("keypress", this);
// Handle height adjustment on show.
this.panel.addEventListener("popupshown", this);
},
/**
@ -417,7 +401,6 @@ const DownloadsPanel = {
_unattachEventListeners() {
this.panel.removeEventListener("keydown", this);
this.panel.removeEventListener("keypress", this);
this.panel.removeEventListener("popupshown", this);
},
_onKeyPress(aEvent) {
@ -858,9 +841,6 @@ const DownloadsView = {
}
this._itemCountChanged();
// Adjust the panel height if we removed items.
DownloadsPanel.setHeightToFit();
},
/**
@ -1545,10 +1525,6 @@ const DownloadsFooter = {
} else {
this._footerNode.removeAttribute("showingsummary");
}
if (!aValue && this._showingSummary) {
// Make sure the panel's height shrinks when the summary is hidden.
DownloadsPanel.setHeightToFit();
}
this._showingSummary = aValue;
}
return aValue;

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

@ -108,22 +108,20 @@
<panelmultiview id="downloadsPanel-multiView"
mainViewId="downloadsPanel-mainView"
align="stretch">
descriptionheightworkaround="true">
<panelview id="downloadsPanel-mainView"
flex="1"
align="stretch">
<richlistbox id="downloadsListBox"
context="downloadsContextMenu"
onmouseover="DownloadsView.onDownloadMouseOver(event);"
onmouseout="DownloadsView.onDownloadMouseOut(event);"
oncontextmenu="DownloadsView.onDownloadContextMenu(event);"
ondragstart="DownloadsView.onDownloadDragStart(event);"/>
<description id="emptyDownloads"
mousethrough="always">
&downloadsPanelEmpty.label;
</description>
<spacer flex="1"/>
<panelview id="downloadsPanel-mainView">
<vbox class="panel-view-body-unscrollable">
<richlistbox id="downloadsListBox"
context="downloadsContextMenu"
onmouseover="DownloadsView.onDownloadMouseOver(event);"
onmouseout="DownloadsView.onDownloadMouseOut(event);"
oncontextmenu="DownloadsView.onDownloadContextMenu(event);"
ondragstart="DownloadsView.onDownloadDragStart(event);"/>
<description id="emptyDownloads"
mousethrough="always"
value="&downloadsPanelEmpty.label;"/>
</vbox>
<vbox id="downloadsFooter"
class="downloadsPanelFooter">
<stack>
@ -159,13 +157,12 @@
</vbox>
</panelview>
<panelview id="downloadsPanel-blockedSubview"
orient="vertical"
flex="1">
<description id="downloadsPanel-blockedSubview-title"/>
<description id="downloadsPanel-blockedSubview-details1"/>
<description id="downloadsPanel-blockedSubview-details2"/>
<spacer flex="1"/>
<panelview id="downloadsPanel-blockedSubview">
<vbox class="panel-view-body-unscrollable">
<description id="downloadsPanel-blockedSubview-title"/>
<description id="downloadsPanel-blockedSubview-details1"/>
<description id="downloadsPanel-blockedSubview-details2"/>
</vbox>
<hbox id="downloadsPanel-blockedSubview-buttons"
class="downloadsPanelFooter"
align="stretch">

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

@ -198,7 +198,8 @@ panelmultiview[nosubviews=true] > .panel-viewcontainer > .panel-viewstack > .pan
display: none;
}
.panel-viewstack:not([viewtype="main"]) > .panel-mainview > #PanelUI-mainView {
panelview {
-moz-box-orient: vertical;
-moz-box-flex: 1;
}
@ -208,6 +209,11 @@ panelmultiview[nosubviews=true] > .panel-viewcontainer > .panel-viewstack > .pan
-moz-box-flex: 1;
}
.panel-view-body-unscrollable {
overflow: hidden;
-moz-box-flex: 1;
}
#PanelUI-popup .panel-subview-body {
margin: -4px;
padding: 4px 4px;
@ -225,6 +231,8 @@ panelmultiview[nosubviews=true] > .panel-viewcontainer > .panel-viewstack > .pan
border-bottom: 1px solid var(--panel-separator-color);
color: GrayText;
font-variant: small-caps;
/* Workaround for min-height not being accounted for in vertical layout. */
height: 41px;
}
.cui-widget-panelview .panel-subview-header,

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

@ -15,7 +15,6 @@
#downloadsPanel > .panel-arrowcontainer > .panel-arrowcontent {
overflow: hidden;
display: block;
}
#downloadsPanel > .panel-arrowcontainer > .panel-arrowcontent,

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

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

@ -121,9 +121,9 @@ extern "C" {
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
** [sqlite_version()] and [sqlite_source_id()].
*/
#define SQLITE_VERSION "3.18.0"
#define SQLITE_VERSION_NUMBER 3018000
#define SQLITE_SOURCE_ID "2017-03-28 18:48:43 424a0d380332858ee55bdebc4af3789f74e70a2b3ba1cf29d84b9b4bcf3e2e37"
#define SQLITE_VERSION "3.19.1"
#define SQLITE_VERSION_NUMBER 3019001
#define SQLITE_SOURCE_ID "2017-05-24 13:08:33 f6d7b988f40217821a382bc298180e9e6794f3ed79a83c6ef5cae048989b3f86"
/*
** CAPI3REF: Run-Time Library Version Numbers
@ -857,7 +857,7 @@ struct sqlite3_io_methods {
** opcode allows these two values (10 retries and 25 milliseconds of delay)
** to be adjusted. The values are changed for all database connections
** within the same process. The argument is a pointer to an array of two
** integers where the first integer i the new retry count and the second
** integers where the first integer is the new retry count and the second
** integer is the delay. If either integer is negative, then the setting
** is not changed but instead the prior value of that setting is written
** into the array entry, allowing the current retry settings to be
@ -2211,9 +2211,6 @@ SQLITE_API int sqlite3_total_changes(sqlite3*);
** ^A call to sqlite3_interrupt(D) that occurs when there are no running
** SQL statements is a no-op and has no effect on SQL statements
** that are started after the sqlite3_interrupt() call returns.
**
** If the database connection closes while [sqlite3_interrupt()]
** is running then bad things will likely happen.
*/
SQLITE_API void sqlite3_interrupt(sqlite3*);
@ -2676,6 +2673,7 @@ SQLITE_API void sqlite3_randomness(int N, void *P);
/*
** CAPI3REF: Compile-Time Authorization Callbacks
** METHOD: sqlite3
** KEYWORDS: {authorizer callback}
**
** ^This routine registers an authorizer callback with a particular
** [database connection], supplied in the first argument.
@ -2703,8 +2701,10 @@ SQLITE_API void sqlite3_randomness(int N, void *P);
** parameter to the sqlite3_set_authorizer() interface. ^The second parameter
** to the callback is an integer [SQLITE_COPY | action code] that specifies
** the particular action to be authorized. ^The third through sixth parameters
** to the callback are zero-terminated strings that contain additional
** details about the action to be authorized.
** to the callback are either NULL pointers or zero-terminated strings
** that contain additional details about the action to be authorized.
** Applications must always be prepared to encounter a NULL pointer in any
** of the third through the sixth parameters of the authorization callback.
**
** ^If the action code is [SQLITE_READ]
** and the callback returns [SQLITE_IGNORE] then the
@ -2713,6 +2713,10 @@ SQLITE_API void sqlite3_randomness(int N, void *P);
** been read if [SQLITE_OK] had been returned. The [SQLITE_IGNORE]
** return can be used to deny an untrusted user access to individual
** columns of a table.
** ^When a table is referenced by a [SELECT] but no column values are
** extracted from that table (for example in a query like
** "SELECT count(*) FROM tab") then the [SQLITE_READ] authorizer callback
** is invoked once for that table with a column name that is an empty string.
** ^If the action code is [SQLITE_DELETE] and the callback returns
** [SQLITE_IGNORE] then the [DELETE] operation proceeds but the
** [truncate optimization] is disabled and all rows are deleted individually.
@ -3705,7 +3709,7 @@ SQLITE_API int sqlite3_stmt_busy(sqlite3_stmt*);
** The [sqlite3_value_blob | sqlite3_value_type()] family of
** interfaces require protected sqlite3_value objects.
*/
typedef struct Mem sqlite3_value;
typedef struct sqlite3_value sqlite3_value;
/*
** CAPI3REF: SQL Function Context Object
@ -4759,10 +4763,11 @@ SQLITE_API sqlite3 *sqlite3_context_db_handle(sqlite3_context*);
** the compiled regular expression can be reused on multiple
** invocations of the same function.
**
** ^The sqlite3_get_auxdata() interface returns a pointer to the metadata
** associated by the sqlite3_set_auxdata() function with the Nth argument
** value to the application-defined function. ^If there is no metadata
** associated with the function argument, this sqlite3_get_auxdata() interface
** ^The sqlite3_get_auxdata(C,N) interface returns a pointer to the metadata
** associated by the sqlite3_set_auxdata(C,N,P,X) function with the Nth argument
** value to the application-defined function. ^N is zero for the left-most
** function argument. ^If there is no metadata
** associated with the function argument, the sqlite3_get_auxdata(C,N) interface
** returns a NULL pointer.
**
** ^The sqlite3_set_auxdata(C,N,P,X) interface saves P as metadata for the N-th
@ -4793,6 +4798,10 @@ SQLITE_API sqlite3 *sqlite3_context_db_handle(sqlite3_context*);
** function parameters that are compile-time constants, including literal
** values and [parameters] and expressions composed from the same.)^
**
** The value of the N parameter to these interfaces should be non-negative.
** Future enhancements may make use of negative N values to define new
** kinds of function caching behavior.
**
** These routines must be called from the same thread in which
** the SQL function is running.
*/
@ -9387,7 +9396,7 @@ typedef struct sqlite3_changegroup sqlite3_changegroup;
** sqlite3changegroup_output() functions, also available are the streaming
** versions sqlite3changegroup_add_strm() and sqlite3changegroup_output_strm().
*/
int sqlite3changegroup_new(sqlite3_changegroup **pp);
SQLITE_API int sqlite3changegroup_new(sqlite3_changegroup **pp);
/*
** CAPI3REF: Add A Changeset To A Changegroup
@ -9464,7 +9473,7 @@ int sqlite3changegroup_new(sqlite3_changegroup **pp);
**
** If no error occurs, SQLITE_OK is returned.
*/
int sqlite3changegroup_add(sqlite3_changegroup*, int nData, void *pData);
SQLITE_API int sqlite3changegroup_add(sqlite3_changegroup*, int nData, void *pData);
/*
** CAPI3REF: Obtain A Composite Changeset From A Changegroup
@ -9490,7 +9499,7 @@ int sqlite3changegroup_add(sqlite3_changegroup*, int nData, void *pData);
** responsibility of the caller to eventually free the buffer using a
** call to sqlite3_free().
*/
int sqlite3changegroup_output(
SQLITE_API int sqlite3changegroup_output(
sqlite3_changegroup*,
int *pnData, /* OUT: Size of output buffer in bytes */
void **ppData /* OUT: Pointer to output buffer */
@ -9499,7 +9508,7 @@ int sqlite3changegroup_output(
/*
** CAPI3REF: Delete A Changegroup Object
*/
void sqlite3changegroup_delete(sqlite3_changegroup*);
SQLITE_API void sqlite3changegroup_delete(sqlite3_changegroup*);
/*
** CAPI3REF: Apply A Changeset To A Database
@ -9888,11 +9897,11 @@ SQLITE_API int sqlite3session_patchset_strm(
int (*xOutput)(void *pOut, const void *pData, int nData),
void *pOut
);
int sqlite3changegroup_add_strm(sqlite3_changegroup*,
SQLITE_API int sqlite3changegroup_add_strm(sqlite3_changegroup*,
int (*xInput)(void *pIn, void *pData, int *pnData),
void *pIn
);
int sqlite3changegroup_output_strm(sqlite3_changegroup*,
SQLITE_API int sqlite3changegroup_output_strm(sqlite3_changegroup*,
int (*xOutput)(void *pOut, const void *pData, int nData),
void *pOut
);

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

@ -82,12 +82,6 @@ private:
const bool mActive;
};
bool
IsParentProcess()
{
return XRE_GetProcessType() == GeckoProcessType_Default;
}
class AudioPlaybackRunnable final : public Runnable
{
public:
@ -285,10 +279,6 @@ AudioChannelService::Shutdown()
if (obs) {
obs->RemoveObserver(gAudioChannelService, "xpcom-shutdown");
obs->RemoveObserver(gAudioChannelService, "outer-window-destroyed");
if (IsParentProcess()) {
obs->RemoveObserver(gAudioChannelService, "ipc:content-shutdown");
}
}
gAudioChannelService->mWindows.Clear();

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

@ -20,7 +20,6 @@
#include "mozilla/dom/ImageBitmapBinding.h"
#include "mozilla/dom/ImageData.h"
#include "mozilla/dom/ImageDataBinding.h"
#include "mozilla/dom/ipc/BlobChild.h"
#include "mozilla/dom/StructuredClone.h"
#include "mozilla/dom/MessagePort.h"
#include "mozilla/dom/MessagePortBinding.h"

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

@ -42,8 +42,6 @@
#include "mozilla/dom/ProcessGlobal.h"
#include "mozilla/dom/SameProcessMessageQueue.h"
#include "mozilla/dom/ScriptSettings.h"
#include "mozilla/dom/ipc/BlobChild.h"
#include "mozilla/dom/ipc/BlobParent.h"
#include "mozilla/dom/ipc/StructuredCloneData.h"
#include "mozilla/dom/DOMStringList.h"
#include "mozilla/jsipc/CrossProcessObjectWrappers.h"

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

@ -7,7 +7,6 @@
#include "BroadcastChannelChild.h"
#include "BroadcastChannel.h"
#include "jsapi.h"
#include "mozilla/dom/ipc/BlobChild.h"
#include "mozilla/dom/File.h"
#include "mozilla/dom/MessageEvent.h"
#include "mozilla/dom/MessageEventBinding.h"

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

@ -9,7 +9,6 @@
#include "MemoryBlobImpl.h"
#include "mozilla/dom/BlobBinding.h"
#include "MultipartBlobImpl.h"
#include "ipc/nsIRemoteBlob.h"
#include "nsIInputStream.h"
#include "nsPIDOMWindow.h"
#include "TemporaryBlobImpl.h"
@ -35,9 +34,6 @@ NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(Blob)
NS_IMPL_CYCLE_COLLECTION_TRACE_END
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(Blob)
// This class should not receive any nsIRemoteBlob QI!
MOZ_ASSERT(!aIID.Equals(NS_GET_IID(nsIRemoteBlob)));
NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDOMBlob)
NS_INTERFACE_MAP_ENTRY(nsIDOMBlob)

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

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

@ -1,246 +0,0 @@
/* -*- 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/. */
#ifndef mozilla_dom_ipc_BlobChild_h
#define mozilla_dom_ipc_BlobChild_h
#include "mozilla/Attributes.h"
#include "mozilla/dom/PBlobChild.h"
#include "nsCOMPtr.h"
#include "nsID.h"
class nsIEventTarget;
class nsIRemoteBlob;
class nsString;
namespace mozilla {
namespace ipc {
class PBackgroundChild;
} // namespace ipc
namespace dom {
class Blob;
class BlobImpl;
class ContentChild;
class nsIContentChild;
class PBlobStreamChild;
class BlobChild final
: public PBlobChild
{
typedef mozilla::ipc::PBackgroundChild PBackgroundChild;
class RemoteBlobImpl;
friend class RemoteBlobImpl;
class RemoteBlobSliceImpl;
friend class RemoteBlobSliceImpl;
BlobImpl* mBlobImpl;
RemoteBlobImpl* mRemoteBlobImpl;
// One of these will be null and the other non-null.
PBackgroundChild* mBackgroundManager;
nsCOMPtr<nsIContentChild> mContentManager;
nsCOMPtr<nsIEventTarget> mEventTarget;
nsID mParentID;
bool mOwnsBlobImpl;
public:
class FriendKey;
static void
Startup(const FriendKey& aKey);
// These create functions are called on the sending side.
static BlobChild*
GetOrCreate(nsIContentChild* aManager, BlobImpl* aBlobImpl);
static BlobChild*
GetOrCreate(PBackgroundChild* aManager, BlobImpl* aBlobImpl);
// These create functions are called on the receiving side.
static BlobChild*
Create(nsIContentChild* aManager, const ChildBlobConstructorParams& aParams);
static BlobChild*
Create(PBackgroundChild* aManager,
const ChildBlobConstructorParams& aParams);
static void
Destroy(PBlobChild* aActor)
{
delete static_cast<BlobChild*>(aActor);
}
bool
HasManager() const
{
return mBackgroundManager || mContentManager;
}
PBackgroundChild*
GetBackgroundManager() const
{
return mBackgroundManager;
}
nsIContentChild*
GetContentManager() const
{
return mContentManager;
}
const nsID&
ParentID() const;
// Get the BlobImpl associated with this actor. This may always be called
// on the sending side. It may also be called on the receiving side unless
// this is a "mystery" blob that has not yet received a SetMysteryBlobInfo()
// call.
already_AddRefed<BlobImpl>
GetBlobImpl();
// Use this for files.
bool
SetMysteryBlobInfo(const nsString& aName,
const nsString& aContentType,
uint64_t aLength,
int64_t aLastModifiedDate);
// Use this for non-file blobs.
bool
SetMysteryBlobInfo(const nsString& aContentType, uint64_t aLength);
void
AssertIsOnOwningThread() const
#ifdef DEBUG
;
#else
{ }
#endif
private:
// These constructors are called on the sending side.
BlobChild(nsIContentChild* aManager, BlobImpl* aBlobImpl);
BlobChild(PBackgroundChild* aManager, BlobImpl* aBlobImpl);
BlobChild(nsIContentChild* aManager, BlobChild* aOther);
BlobChild(PBackgroundChild* aManager, BlobChild* aOther, BlobImpl* aBlobImpl);
// These constructors are called on the receiving side.
BlobChild(nsIContentChild* aManager,
const ChildBlobConstructorParams& aParams);
BlobChild(PBackgroundChild* aManager,
const ChildBlobConstructorParams& aParams);
// These constructors are called for slices.
BlobChild(nsIContentChild* aManager,
const nsID& aParentID,
RemoteBlobSliceImpl* aRemoteBlobSliceImpl);
BlobChild(PBackgroundChild* aManager,
const nsID& aParentID,
RemoteBlobSliceImpl* aRemoteBlobSliceImpl);
// Only called by Destroy().
~BlobChild();
void
CommonInit(BlobImpl* aBlobImpl);
void
CommonInit(BlobChild* aOther, BlobImpl* aBlobImpl);
void
CommonInit(const ChildBlobConstructorParams& aParams);
void
CommonInit(const nsID& aParentID, RemoteBlobImpl* aRemoteBlobImpl);
template <class ChildManagerType>
static BlobChild*
GetOrCreateFromImpl(ChildManagerType* aManager, BlobImpl* aBlobImpl);
template <class ChildManagerType>
static BlobChild*
CreateFromParams(ChildManagerType* aManager,
const ChildBlobConstructorParams& aParams);
template <class ChildManagerType>
static BlobChild*
SendSliceConstructor(ChildManagerType* aManager,
RemoteBlobSliceImpl* aRemoteBlobSliceImpl,
const ParentBlobConstructorParams& aParams);
static BlobChild*
MaybeGetActorFromRemoteBlob(nsIRemoteBlob* aRemoteBlob,
nsIContentChild* aManager,
BlobImpl* aBlobImpl);
static BlobChild*
MaybeGetActorFromRemoteBlob(nsIRemoteBlob* aRemoteBlob,
PBackgroundChild* aManager,
BlobImpl* aBlobImpl);
void
NoteDyingRemoteBlobImpl();
nsIEventTarget*
EventTarget() const
{
return mEventTarget;
}
bool
IsOnOwningThread() const;
// These methods are only called by the IPDL message machinery.
virtual void
ActorDestroy(ActorDestroyReason aWhy) override;
virtual PBlobStreamChild*
AllocPBlobStreamChild(const uint64_t& aStart,
const uint64_t& aLength) override;
virtual bool
DeallocPBlobStreamChild(PBlobStreamChild* aActor) override;
virtual mozilla::ipc::IPCResult
RecvCreatedFromKnownBlob() override;
};
// Only let ContentChild call BlobChild::Startup() and ensure that
// ContentChild can't access any other BlobChild internals.
class BlobChild::FriendKey final
{
friend class ContentChild;
private:
FriendKey()
{ }
FriendKey(const FriendKey& /* aOther */)
{ }
public:
~FriendKey()
{ }
};
} // namespace dom
} // namespace mozilla
#endif // mozilla_dom_ipc_BlobChild_h

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

@ -1,260 +0,0 @@
/* -*- 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/. */
#ifndef mozilla_dom_ipc_BlobParent_h
#define mozilla_dom_ipc_BlobParent_h
#include "mozilla/Attributes.h"
#include "mozilla/StaticPtr.h"
#include "mozilla/dom/PBlobParent.h"
#include "nsCOMPtr.h"
#include "nsTArray.h"
template <class, class> class nsDataHashtable;
class nsIDHashKey;
class nsIEventTarget;
class nsIRemoteBlob;
template <class> class nsRevocableEventPtr;
class nsString;
namespace mozilla {
class Mutex;
namespace ipc {
class PBackgroundParent;
} // namespace ipc
namespace dom {
class ContentParent;
class BlobImpl;
class nsIContentParent;
class PBlobStreamParent;
class BlobParent final
: public PBlobParent
{
typedef mozilla::ipc::PBackgroundParent PBackgroundParent;
class IDTableEntry;
typedef nsDataHashtable<nsIDHashKey, IDTableEntry*> IDTable;
class OpenStreamRunnable;
friend class OpenStreamRunnable;
class RemoteBlobImpl;
struct CreateBlobImplMetadata;
static StaticAutoPtr<IDTable> sIDTable;
static StaticAutoPtr<Mutex> sIDTableMutex;
BlobImpl* mBlobImpl;
RemoteBlobImpl* mRemoteBlobImpl;
// One of these will be null and the other non-null.
PBackgroundParent* mBackgroundManager;
nsCOMPtr<nsIContentParent> mContentManager;
nsCOMPtr<nsIEventTarget> mEventTarget;
// nsIInputStreams backed by files must ensure that the files are actually
// opened and closed on a background thread before we can send their file
// handles across to the child. The child process could crash during this
// process so we need to make sure we cancel the intended response in such a
// case. We do that by holding an array of nsRevocableEventPtr. If the child
// crashes then this actor will be destroyed and the nsRevocableEventPtr
// destructor will cancel any stream events that are currently in flight.
nsTArray<nsRevocableEventPtr<OpenStreamRunnable>> mOpenStreamRunnables;
RefPtr<IDTableEntry> mIDTableEntry;
bool mOwnsBlobImpl;
public:
class FriendKey;
static void
Startup(const FriendKey& aKey);
// These create functions are called on the sending side.
static BlobParent*
GetOrCreate(nsIContentParent* aManager, BlobImpl* aBlobImpl);
static BlobParent*
GetOrCreate(PBackgroundParent* aManager, BlobImpl* aBlobImpl);
// These create functions are called on the receiving side.
static BlobParent*
Create(nsIContentParent* aManager,
const ParentBlobConstructorParams& aParams);
static BlobParent*
Create(PBackgroundParent* aManager,
const ParentBlobConstructorParams& aParams);
static void
Destroy(PBlobParent* aActor)
{
delete static_cast<BlobParent*>(aActor);
}
static already_AddRefed<BlobImpl>
GetBlobImplForID(const nsID& aID);
bool
HasManager() const
{
return mBackgroundManager || mContentManager;
}
PBackgroundParent*
GetBackgroundManager() const
{
return mBackgroundManager;
}
nsIContentParent*
GetContentManager() const
{
return mContentManager;
}
// Get the BlobImpl associated with this actor.
already_AddRefed<BlobImpl>
GetBlobImpl();
void
AssertIsOnOwningThread() const
#ifdef DEBUG
;
#else
{ }
#endif
private:
// These constructors are called on the sending side.
BlobParent(nsIContentParent* aManager, IDTableEntry* aIDTableEntry);
BlobParent(PBackgroundParent* aManager, IDTableEntry* aIDTableEntry);
// These constructors are called on the receiving side.
BlobParent(nsIContentParent* aManager,
BlobImpl* aBlobImpl,
IDTableEntry* aIDTableEntry);
BlobParent(PBackgroundParent* aManager,
BlobImpl* aBlobImpl,
IDTableEntry* aIDTableEntry);
// Only destroyed by BackgroundParentImpl and ContentParent.
~BlobParent();
void
CommonInit(IDTableEntry* aIDTableEntry);
void
CommonInit(BlobImpl* aBlobImpl, IDTableEntry* aIDTableEntry);
template <class ParentManagerType>
static BlobParent*
GetOrCreateFromImpl(ParentManagerType* aManager,
BlobImpl* aBlobImpl);
template <class ParentManagerType>
static BlobParent*
CreateFromParams(ParentManagerType* aManager,
const ParentBlobConstructorParams& aParams);
template <class ParentManagerType>
static BlobParent*
SendSliceConstructor(ParentManagerType* aManager,
const ParentBlobConstructorParams& aParams,
const ChildBlobConstructorParams& aOtherSideParams);
static BlobParent*
MaybeGetActorFromRemoteBlob(nsIRemoteBlob* aRemoteBlob,
nsIContentParent* aManager);
static BlobParent*
MaybeGetActorFromRemoteBlob(nsIRemoteBlob* aRemoteBlob,
PBackgroundParent* aManager);
void
NoteDyingRemoteBlobImpl();
void
NoteRunnableCompleted(OpenStreamRunnable* aRunnable);
nsIEventTarget*
EventTarget() const
{
return mEventTarget;
}
bool
IsOnOwningThread() const;
// These methods are only called by the IPDL message machinery.
virtual void
ActorDestroy(ActorDestroyReason aWhy) override;
virtual PBlobStreamParent*
AllocPBlobStreamParent(const uint64_t& aStart,
const uint64_t& aLength) override;
virtual mozilla::ipc::IPCResult
RecvPBlobStreamConstructor(PBlobStreamParent* aActor,
const uint64_t& aStart,
const uint64_t& aLength) override;
virtual bool
DeallocPBlobStreamParent(PBlobStreamParent* aActor) override;
virtual mozilla::ipc::IPCResult
RecvResolveMystery(const ResolveMysteryParams& aParams) override;
virtual mozilla::ipc::IPCResult
RecvBlobStreamSync(const uint64_t& aStart,
const uint64_t& aLength,
InputStreamParams* aParams,
OptionalFileDescriptorSet* aFDs) override;
virtual mozilla::ipc::IPCResult
RecvWaitForSliceCreation() override;
virtual mozilla::ipc::IPCResult
RecvGetFileId(int64_t* aFileId) override;
virtual mozilla::ipc::IPCResult
RecvGetFilePath(nsString* aFilePath) override;
};
// Only let ContentParent call BlobParent::Startup() and ensure that
// ContentParent can't access any other BlobParent internals.
class BlobParent::FriendKey final
{
friend class ContentParent;
private:
FriendKey()
{ }
FriendKey(const FriendKey& /* aOther */)
{ }
public:
~FriendKey()
{ }
};
} // namespace dom
} // namespace mozilla
#endif // mozilla_dom_ipc_BlobParent_h

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

@ -7,8 +7,8 @@
#include "IPCBlobInputStream.h"
#include "IPCBlobInputStreamChild.h"
#include "IPCBlobInputStreamStorage.h"
#include "mozilla/ipc/InputStreamParams.h"
#include "nsIAsyncInputStream.h"
#include "mozilla/SystemGroup.h"
namespace mozilla {
namespace dom {
@ -350,7 +350,7 @@ void
IPCBlobInputStream::Serialize(mozilla::ipc::InputStreamParams& aParams,
FileDescriptorArray& aFileDescriptors)
{
IPCBlobInputStreamParams params;
mozilla::ipc::IPCBlobInputStreamParams params;
params.id() = mActor->ID();
aParams = params;

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

@ -12,6 +12,7 @@
#include "nsIFileStreams.h"
#include "nsIIPCSerializableInputStream.h"
#include "nsISeekableStream.h"
#include "nsCOMPtr.h"
namespace mozilla {
namespace dom {

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

@ -5,11 +5,16 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "IPCBlobInputStreamChild.h"
#include "mozilla/ipc/IPCStreamUtils.h"
#include "WorkerPrivate.h"
#include "WorkerHolder.h"
namespace mozilla {
namespace dom {
using namespace workers;
namespace {
// This runnable is used in case the last stream is forgotten on the 'wrong'
@ -229,7 +234,7 @@ IPCBlobInputStreamChild::StreamNeeded(IPCBlobInputStream* aStream,
mozilla::ipc::IPCResult
IPCBlobInputStreamChild::RecvStreamReady(const OptionalIPCStream& aStream)
{
nsCOMPtr<nsIInputStream> stream = DeserializeIPCStream(aStream);
nsCOMPtr<nsIInputStream> stream = mozilla::ipc::DeserializeIPCStream(aStream);
RefPtr<IPCBlobInputStream> pendingStream;
nsCOMPtr<nsIEventTarget> eventTarget;

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

@ -6,6 +6,7 @@
#include "IPCBlobInputStreamParent.h"
#include "IPCBlobInputStreamStorage.h"
#include "mozilla/ipc/IPCStreamUtils.h"
#include "nsContentUtils.h"
namespace mozilla {
@ -91,7 +92,7 @@ IPCBlobInputStreamParent::RecvStreamNeeded()
return IPC_OK();
}
AutoIPCStream ipcStream;
mozilla::ipc::AutoIPCStream ipcStream;
bool ok = false;
if (mContentManager) {

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

@ -10,9 +10,15 @@
#include "IPCBlobInputStreamParent.h"
#include "IPCBlobInputStreamStorage.h"
#include "mozilla/dom/IPCBlob.h"
#include "mozilla/dom/nsIContentParent.h"
#include "mozilla/ipc/IPCStreamUtils.h"
#include "StreamBlobImpl.h"
#include "prtime.h"
namespace mozilla {
using namespace ipc;
namespace dom {
namespace IPCBlobUtils {

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

@ -140,6 +140,7 @@ class PBackgroundParent;
namespace dom {
class IPCBlob;
class nsIContentChild;
class nsIContentParent;

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

@ -1,22 +0,0 @@
/* -*- 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/. */
#ifndef mozilla_dom_ipc_MemoryStreamChild_h
#define mozilla_dom_ipc_MemoryStreamChild_h
#include "mozilla/ipc/PMemoryStreamChild.h"
namespace mozilla {
namespace dom {
class MemoryStreamChild final : public mozilla::ipc::PMemoryStreamChild
{
};
} // namespace dom
} // namespace mozilla
#endif // mozilla_dom_ipc_MemoryStreamChild_h

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

@ -1,78 +0,0 @@
/* -*- 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/. */
#include "MemoryStreamParent.h"
#include "nsIInputStream.h"
namespace mozilla {
namespace dom {
MemoryStreamParent::MemoryStreamParent(uint64_t aSize)
: mSize(aSize)
, mCurSize(0)
{}
mozilla::ipc::IPCResult
MemoryStreamParent::RecvAddChunk(nsTArray<unsigned char>&& aData)
{
MOZ_ASSERT(mSize);
uint64_t dataLength = aData.Length();
if (!dataLength || mSize < (mCurSize + dataLength)) {
return IPC_FAIL_NO_REASON(this);
}
void* buffer = malloc(dataLength);
if (NS_WARN_IF(!buffer)) {
return IPC_FAIL_NO_REASON(this);
}
memcpy(buffer, aData.Elements(), dataLength);
mData.AppendElement(new MemoryBlobImpl::DataOwner(buffer, dataLength));
mCurSize += dataLength;
return IPC_OK();
}
void
MemoryStreamParent::ActorDestroy(IProtocol::ActorDestroyReason)
{
}
void
MemoryStreamParent::GetStream(nsIInputStream** aInputStream)
{
if (mCurSize != mSize) {
*aInputStream = nullptr;
return;
}
nsCOMPtr<nsIMultiplexInputStream> stream =
do_CreateInstance("@mozilla.org/io/multiplex-input-stream;1");
if (NS_WARN_IF(!stream)) {
*aInputStream = nullptr;
return;
}
for (uint32_t i = 0; i < mData.Length(); ++i) {
nsCOMPtr<nsIInputStream> dataStream;
nsresult rv =
MemoryBlobImpl::DataOwnerAdapter::Create(mData[i], 0, mData[i]->mLength,
getter_AddRefs(dataStream));
if (NS_WARN_IF(NS_FAILED(rv))) {
*aInputStream = nullptr;
return;
}
stream->AppendStream(dataStream);
}
stream.forget(aInputStream);
}
} // namespace dom
} // namespace mozilla

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

@ -1,40 +0,0 @@
/* -*- 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/. */
#ifndef mozilla_dom_ipc_MemoryStreamParent_h
#define mozilla_dom_ipc_MemoryStreamParent_h
#include "mozilla/ipc/PMemoryStreamParent.h"
#include "mozilla/dom/MemoryBlobImpl.h"
namespace mozilla {
namespace dom {
class MemoryStreamParent final : public mozilla::ipc::PMemoryStreamParent
{
public:
explicit MemoryStreamParent(uint64_t aSize);
mozilla::ipc::IPCResult
RecvAddChunk(nsTArray<unsigned char>&& aData) override;
void
ActorDestroy(IProtocol::ActorDestroyReason) override;
void
GetStream(nsIInputStream** aInputStream);
private:
uint64_t mSize;
uint64_t mCurSize;
nsTArray<RefPtr<MemoryBlobImpl::DataOwner>> mData;
};
} // namespace dom
} // namespace mozilla
#endif // mozilla_dom_ipc_MemoryStreamParent_h

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

@ -1,59 +0,0 @@
/* 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/. */
include protocol PBackground;
include protocol PBlobStream;
include protocol PContent;
include protocol PContentBridge;
include protocol PFileDescriptorSet;
include protocol PChildToParentStream;
include protocol PParentToChildStream;
include protocol PMemoryStream;
include BlobTypes;
include DOMTypes;
include InputStreamParams;
namespace mozilla {
namespace dom {
union ResolveMysteryParams
{
NormalBlobConstructorParams;
FileBlobConstructorParams;
};
sync protocol PBlob
{
manager PBackground or PContent or PContentBridge;
manages PBlobStream;
both:
async __delete__();
parent:
async PBlobStream(uint64_t begin, uint64_t length);
async ResolveMystery(ResolveMysteryParams params);
sync BlobStreamSync(uint64_t begin, uint64_t length)
returns (InputStreamParams params, OptionalFileDescriptorSet fds);
sync WaitForSliceCreation();
// Use only for testing!
sync GetFileId()
returns (int64_t fileId);
sync GetFilePath()
returns (nsString filePath);
child:
// This method must be called by the parent when the PBlobParent is fully
// created in order to release the known blob.
async CreatedFromKnownBlob();
};
} // namespace dom
} // namespace mozilla

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

@ -1,22 +0,0 @@
/* 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/. */
include protocol PBlob;
include protocol PFileDescriptorSet;
include BlobTypes;
include InputStreamParams;
namespace mozilla {
namespace dom {
protocol PBlobStream
{
manager PBlob;
child:
async __delete__(InputStreamParams params, OptionalFileDescriptorSet fds);
};
} // namespace dom
} // namespace mozilla

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

@ -1,23 +0,0 @@
/* 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/. */
include protocol PBackground;
include protocol PContent;
include protocol PContentBridge;
namespace mozilla {
namespace ipc {
protocol PMemoryStream
{
manager PBackground or PContent or PContentBridge;
parent:
async AddChunk(uint8_t[] data);
async __delete__();
};
} // namespace dom
} // namespace mozilla

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

@ -5,6 +5,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "PendingIPCBlobParent.h"
#include "mozilla/ipc/PBackgroundParent.h"
namespace mozilla {

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

@ -5,15 +5,10 @@
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
EXPORTS.mozilla.dom.ipc += [
'BlobChild.h',
'BlobParent.h',
'IPCBlobInputStream.h',
'IPCBlobInputStreamChild.h',
'IPCBlobInputStreamParent.h',
'IPCBlobInputStreamStorage.h',
'MemoryStreamChild.h',
'MemoryStreamParent.h',
'nsIRemoteBlob.h',
'PendingIPCBlobChild.h',
'PendingIPCBlobParent.h',
]
@ -23,13 +18,11 @@ EXPORTS.mozilla.dom += [
]
UNIFIED_SOURCES += [
'Blob.cpp',
'IPCBlobInputStream.cpp',
'IPCBlobInputStreamChild.cpp',
'IPCBlobInputStreamParent.cpp',
'IPCBlobInputStreamStorage.cpp',
'IPCBlobUtils.cpp',
'MemoryStreamParent.cpp',
'PendingIPCBlobChild.cpp',
'PendingIPCBlobParent.cpp',
]
@ -37,10 +30,7 @@ UNIFIED_SOURCES += [
IPDL_SOURCES += [
'BlobTypes.ipdlh',
'IPCBlob.ipdlh',
'PBlob.ipdl',
'PBlobStream.ipdl',
'PIPCBlobInputStream.ipdl',
'PMemoryStream.ipdl',
'PPendingIPCBlob.ipdl',
]

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

@ -1,45 +0,0 @@
/* -*- 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/. */
#ifndef mozilla_dom_ipc_nsIRemoteBlob_h
#define mozilla_dom_ipc_nsIRemoteBlob_h
#include "nsISupports.h"
#ifndef NS_NO_VTABLE
#define NS_NO_VTABLE
#endif
#define NS_IREMOTEBLOB_IID \
{0x0b8b0091, 0xb315, 0x48a2, {0x90, 0xf1, 0x60, 0x0e, 0x78, 0x35, 0xf7, 0x2d}}
namespace mozilla {
namespace dom {
class BlobChild;
class BlobParent;
} // namespace dom
} // namespace mozilla
class NS_NO_VTABLE nsIRemoteBlob : public nsISupports
{
public:
typedef mozilla::dom::BlobChild BlobChild;
typedef mozilla::dom::BlobParent BlobParent;
NS_DECLARE_STATIC_IID_ACCESSOR(NS_IREMOTEBLOB_IID)
virtual BlobChild*
GetBlobChild() = 0;
virtual BlobParent*
GetBlobParent() = 0;
};
NS_DEFINE_STATIC_IID_ACCESSOR(nsIRemoteBlob, NS_IREMOTEBLOB_IID)
#endif // mozilla_dom_ipc_nsIRemoteBlob_h

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

@ -19911,8 +19911,7 @@ DatabaseOperationBase::GetStructuredCloneReadInfoFromSource(
} else {
const uint8_t* blobData;
uint32_t blobDataLength;
nsresult rv =
aSource->GetSharedBlob(aDataIndex, &blobDataLength, &blobData);
rv = aSource->GetSharedBlob(aDataIndex, &blobDataLength, &blobData);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}

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

@ -38,7 +38,6 @@
#include "mozilla/dom/StructuredCloneHolder.h"
#include "mozilla/dom/StructuredCloneTags.h"
#include "mozilla/dom/indexedDB/PBackgroundIDBSharedTypes.h"
#include "mozilla/dom/ipc/BlobChild.h"
#include "mozilla/ipc/BackgroundChild.h"
#include "mozilla/ipc/PBackgroundSharedTypes.h"
#include "nsCOMPtr.h"

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

@ -8,7 +8,6 @@
#include "mozilla/dom/ContentChild.h"
#include "mozilla/dom/File.h"
#include "mozilla/dom/TabChild.h"
#include "mozilla/dom/ipc/BlobChild.h"
#include "mozilla/jsipc/CrossProcessObjectWrappers.h"
#include "mozilla/ipc/InputStreamUtils.h"
#include "base/task.h"
@ -61,19 +60,6 @@ ContentBridgeChild::RecvAsyncMessage(const nsString& aMsg,
return nsIContentChild::RecvAsyncMessage(aMsg, Move(aCpows), aPrincipal, aData);
}
PBlobChild*
ContentBridgeChild::SendPBlobConstructor(PBlobChild* actor,
const BlobConstructorParams& params)
{
return PContentBridgeChild::SendPBlobConstructor(actor, params);
}
PMemoryStreamChild*
ContentBridgeChild::SendPMemoryStreamConstructor(const uint64_t& aSize)
{
return PContentBridgeChild::SendPMemoryStreamConstructor(aSize);
}
bool
ContentBridgeChild::SendPBrowserConstructor(PBrowserChild* aActor,
const TabId& aTabId,
@ -168,30 +154,6 @@ ContentBridgeChild::RecvPBrowserConstructor(PBrowserChild* aActor,
aIsForBrowser);
}
PBlobChild*
ContentBridgeChild::AllocPBlobChild(const BlobConstructorParams& aParams)
{
return nsIContentChild::AllocPBlobChild(aParams);
}
bool
ContentBridgeChild::DeallocPBlobChild(PBlobChild* aActor)
{
return nsIContentChild::DeallocPBlobChild(aActor);
}
PMemoryStreamChild*
ContentBridgeChild::AllocPMemoryStreamChild(const uint64_t& aSize)
{
return nsIContentChild::AllocPMemoryStreamChild(aSize);
}
bool
ContentBridgeChild::DeallocPMemoryStreamChild(PMemoryStreamChild* aActor)
{
return nsIContentChild::DeallocPMemoryStreamChild(aActor);
}
PIPCBlobInputStreamChild*
ContentBridgeChild::AllocPIPCBlobInputStreamChild(const nsID& aID,
const uint64_t& aSize)

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

@ -32,13 +32,6 @@ public:
const IPC::Principal& aPrincipal,
const ClonedMessageData& aData) override;
virtual PBlobChild*
SendPBlobConstructor(PBlobChild* actor,
const BlobConstructorParams& aParams) override;
virtual PMemoryStreamChild*
SendPMemoryStreamConstructor(const uint64_t& aSize) override;
jsipc::CPOWManager* GetCPOWManager() override;
virtual bool SendPBrowserConstructor(PBrowserChild* aActor,
@ -85,13 +78,6 @@ protected:
virtual mozilla::jsipc::PJavaScriptChild* AllocPJavaScriptChild() override;
virtual bool DeallocPJavaScriptChild(mozilla::jsipc::PJavaScriptChild*) override;
virtual PBlobChild* AllocPBlobChild(const BlobConstructorParams& aParams) override;
virtual bool DeallocPBlobChild(PBlobChild*) override;
virtual PMemoryStreamChild*
AllocPMemoryStreamChild(const uint64_t& aSize) override;
virtual bool DeallocPMemoryStreamChild(PMemoryStreamChild*) override;
virtual PIPCBlobInputStreamChild*
AllocPIPCBlobInputStreamChild(const nsID& aID,
const uint64_t& aSize) override;

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

@ -7,7 +7,6 @@
#include "mozilla/dom/ContentBridgeParent.h"
#include "mozilla/dom/TabParent.h"
#include "mozilla/jsipc/CrossProcessObjectWrappers.h"
#include "mozilla/dom/ipc/MemoryStreamParent.h"
#include "nsXULAppAPI.h"
#include "nsIObserverService.h"
#include "base/task.h"
@ -88,13 +87,6 @@ ContentBridgeParent::RecvAsyncMessage(const nsString& aMsg,
aPrincipal, aData);
}
PBlobParent*
ContentBridgeParent::SendPBlobConstructor(PBlobParent* actor,
const BlobConstructorParams& params)
{
return PContentBridgeParent::SendPBlobConstructor(actor, params);
}
PBrowserParent*
ContentBridgeParent::SendPBrowserConstructor(PBrowserParent* aActor,
const TabId& aTabId,
@ -119,18 +111,6 @@ ContentBridgeParent::SendPParentToChildStreamConstructor(PParentToChildStreamPar
return PContentBridgeParent::SendPParentToChildStreamConstructor(aActor);
}
PBlobParent*
ContentBridgeParent::AllocPBlobParent(const BlobConstructorParams& aParams)
{
return nsIContentParent::AllocPBlobParent(aParams);
}
bool
ContentBridgeParent::DeallocPBlobParent(PBlobParent* aActor)
{
return nsIContentParent::DeallocPBlobParent(aActor);
}
PIPCBlobInputStreamParent*
ContentBridgeParent::SendPIPCBlobInputStreamConstructor(PIPCBlobInputStreamParent* aActor,
const nsID& aID,
@ -140,18 +120,6 @@ ContentBridgeParent::SendPIPCBlobInputStreamConstructor(PIPCBlobInputStreamParen
PContentBridgeParent::SendPIPCBlobInputStreamConstructor(aActor, aID, aSize);
}
PMemoryStreamParent*
ContentBridgeParent::AllocPMemoryStreamParent(const uint64_t& aSize)
{
return nsIContentParent::AllocPMemoryStreamParent(aSize);
}
bool
ContentBridgeParent::DeallocPMemoryStreamParent(PMemoryStreamParent* aActor)
{
return nsIContentParent::DeallocPMemoryStreamParent(aActor);
}
PIPCBlobInputStreamParent*
ContentBridgeParent::AllocPIPCBlobInputStreamParent(const nsID& aID,
const uint64_t& aSize)

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

@ -33,10 +33,6 @@ public:
static ContentBridgeParent*
Create(Endpoint<PContentBridgeParent>&& aEndpoint);
virtual PBlobParent*
SendPBlobConstructor(PBlobParent* actor,
const BlobConstructorParams& params) override;
virtual PBrowserParent*
SendPBrowserConstructor(PBrowserParent* aActor,
const TabId& aTabId,
@ -133,16 +129,6 @@ protected:
virtual bool DeallocPBrowserParent(PBrowserParent*) override;
virtual PBlobParent*
AllocPBlobParent(const BlobConstructorParams& aParams) override;
virtual bool DeallocPBlobParent(PBlobParent*) override;
virtual PMemoryStreamParent*
AllocPMemoryStreamParent(const uint64_t& aSize) override;
virtual bool DeallocPMemoryStreamParent(PMemoryStreamParent*) override;
virtual PIPCBlobInputStreamParent*
SendPIPCBlobInputStreamConstructor(PIPCBlobInputStreamParent* aActor,
const nsID& aID,

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

@ -41,7 +41,6 @@
#include "mozilla/dom/workers/ServiceWorkerManager.h"
#include "mozilla/dom/nsIContentChild.h"
#include "mozilla/dom/URLClassifierChild.h"
#include "mozilla/dom/ipc/BlobChild.h"
#include "mozilla/gfx/gfxVars.h"
#include "mozilla/psm/PSMContentListener.h"
#include "mozilla/hal_sandbox/PHalChild.h"
@ -993,8 +992,6 @@ ContentChild::InitXPCOM(const XPCOMInitData& aXPCOMInit,
MOZ_CRASH("Failed to create PBackgroundChild!");
}
BlobChild::Startup(BlobChild::FriendKey());
nsCOMPtr<nsIConsoleService> svc(do_GetService(NS_CONSOLESERVICE_CONTRACTID));
if (!svc) {
NS_WARNING("Couldn't acquire console service");
@ -1637,18 +1634,6 @@ ContentChild::DeallocPBrowserChild(PBrowserChild* aIframe)
return nsIContentChild::DeallocPBrowserChild(aIframe);
}
PMemoryStreamChild*
ContentChild::AllocPMemoryStreamChild(const uint64_t& aSize)
{
return nsIContentChild::AllocPMemoryStreamChild(aSize);
}
bool
ContentChild::DeallocPMemoryStreamChild(PMemoryStreamChild* aActor)
{
return nsIContentChild::DeallocPMemoryStreamChild(aActor);
}
PIPCBlobInputStreamChild*
ContentChild::AllocPIPCBlobInputStreamChild(const nsID& aID,
const uint64_t& aSize)
@ -1662,12 +1647,6 @@ ContentChild::DeallocPIPCBlobInputStreamChild(PIPCBlobInputStreamChild* aActor)
return nsIContentChild::DeallocPIPCBlobInputStreamChild(aActor);
}
PBlobChild*
ContentChild::AllocPBlobChild(const BlobConstructorParams& aParams)
{
return nsIContentChild::AllocPBlobChild(aParams);
}
mozilla::PRemoteSpellcheckEngineChild *
ContentChild::AllocPRemoteSpellcheckEngineChild()
{
@ -1682,33 +1661,6 @@ ContentChild::DeallocPRemoteSpellcheckEngineChild(PRemoteSpellcheckEngineChild *
return true;
}
bool
ContentChild::DeallocPBlobChild(PBlobChild* aActor)
{
return nsIContentChild::DeallocPBlobChild(aActor);
}
PBlobChild*
ContentChild::SendPBlobConstructor(PBlobChild* aActor,
const BlobConstructorParams& aParams)
{
if (IsShuttingDown()) {
return nullptr;
}
return PContentChild::SendPBlobConstructor(aActor, aParams);
}
PMemoryStreamChild*
ContentChild::SendPMemoryStreamConstructor(const uint64_t& aSize)
{
if (IsShuttingDown()) {
return nullptr;
}
return PContentChild::SendPMemoryStreamConstructor(aSize);
}
PPresentationChild*
ContentChild::AllocPPresentationChild()
{

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

@ -184,17 +184,6 @@ public:
virtual bool DeallocPBrowserChild(PBrowserChild*) override;
virtual PBlobChild*
AllocPBlobChild(const BlobConstructorParams& aParams) override;
virtual bool DeallocPBlobChild(PBlobChild* aActor) override;
virtual PMemoryStreamChild*
AllocPMemoryStreamChild(const uint64_t& aSize) override;
virtual bool
DeallocPMemoryStreamChild(PMemoryStreamChild* aActor) override;
virtual PIPCBlobInputStreamChild*
AllocPIPCBlobInputStreamChild(const nsID& aID,
const uint64_t& aSize) override;
@ -519,13 +508,6 @@ public:
bool IsForBrowser() const { return mIsForBrowser; }
virtual PBlobChild*
SendPBlobConstructor(PBlobChild* actor,
const BlobConstructorParams& params) override;
virtual PMemoryStreamChild*
SendPMemoryStreamConstructor(const uint64_t& aSize) override;
virtual PFileDescriptorSetChild*
SendPFileDescriptorSetConstructor(const FileDescriptor&) override;

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

@ -66,7 +66,6 @@
#include "mozilla/dom/quota/QuotaManagerService.h"
#include "mozilla/dom/time/DateCacheCleaner.h"
#include "mozilla/dom/URLClassifierParent.h"
#include "mozilla/dom/ipc/BlobParent.h"
#include "mozilla/embedding/printingui/PrintingParent.h"
#include "mozilla/gfx/gfxVars.h"
#include "mozilla/gfx/GPUProcessManager.h"
@ -631,8 +630,6 @@ ContentParent::StartUp()
mozilla::dom::time::InitializeDateCacheCleaner();
BlobParent::Startup(BlobParent::FriendKey());
BackgroundChild::Startup();
sDisableUnsafeCPOWWarnings = PR_GetEnv("DISABLE_UNSAFE_CPOW_WARNINGS");
@ -2838,30 +2835,6 @@ ContentParent::DeallocPBrowserParent(PBrowserParent* frame)
return nsIContentParent::DeallocPBrowserParent(frame);
}
PBlobParent*
ContentParent::AllocPBlobParent(const BlobConstructorParams& aParams)
{
return nsIContentParent::AllocPBlobParent(aParams);
}
bool
ContentParent::DeallocPBlobParent(PBlobParent* aActor)
{
return nsIContentParent::DeallocPBlobParent(aActor);
}
PMemoryStreamParent*
ContentParent::AllocPMemoryStreamParent(const uint64_t& aSize)
{
return nsIContentParent::AllocPMemoryStreamParent(aSize);
}
bool
ContentParent::DeallocPMemoryStreamParent(PMemoryStreamParent* aActor)
{
return nsIContentParent::DeallocPMemoryStreamParent(aActor);
}
PIPCBlobInputStreamParent*
ContentParent::AllocPIPCBlobInputStreamParent(const nsID& aID,
const uint64_t& aSize)
@ -2875,21 +2848,6 @@ ContentParent::DeallocPIPCBlobInputStreamParent(PIPCBlobInputStreamParent* aActo
return nsIContentParent::DeallocPIPCBlobInputStreamParent(aActor);
}
mozilla::ipc::IPCResult
ContentParent::RecvPBlobConstructor(PBlobParent* aActor,
const BlobConstructorParams& aParams)
{
const ParentBlobConstructorParams& params = aParams.get_ParentBlobConstructorParams();
if (params.blobParams().type() == AnyBlobConstructorParams::TKnownBlobConstructorParams) {
if (!aActor->SendCreatedFromKnownBlob()) {
return IPC_FAIL_NO_REASON(this);
}
return IPC_OK();
}
return IPC_OK();
}
mozilla::PRemoteSpellcheckEngineParent *
ContentParent::AllocPRemoteSpellcheckEngineParent()
{
@ -3878,13 +3836,6 @@ ContentParent::DoSendAsyncMessage(JSContext* aCx,
return NS_OK;
}
PBlobParent*
ContentParent::SendPBlobConstructor(PBlobParent* aActor,
const BlobConstructorParams& aParams)
{
return PContentParent::SendPBlobConstructor(aActor, aParams);
}
PIPCBlobInputStreamParent*
ContentParent::SendPIPCBlobInputStreamConstructor(PIPCBlobInputStreamParent* aActor,
const nsID& aID,

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

@ -482,10 +482,6 @@ public:
nsICycleCollectorLogSink* aSink,
nsIDumpGCAndCCLogsCallback* aCallback);
virtual PBlobParent*
SendPBlobConstructor(PBlobParent* aActor,
const BlobConstructorParams& aParams) override;
virtual mozilla::ipc::IPCResult RecvUnregisterRemoteFrame(const TabId& aTabId,
const ContentParentId& aCpId,
const bool& aMarkedDestroying) override;
@ -843,16 +839,6 @@ private:
virtual bool DeallocPBrowserParent(PBrowserParent* frame) override;
virtual PBlobParent*
AllocPBlobParent(const BlobConstructorParams& aParams) override;
virtual bool DeallocPBlobParent(PBlobParent* aActor) override;
virtual PMemoryStreamParent*
AllocPMemoryStreamParent(const uint64_t& aSize) override;
virtual bool DeallocPMemoryStreamParent(PMemoryStreamParent* aActor) override;
virtual PIPCBlobInputStreamParent*
SendPIPCBlobInputStreamConstructor(PIPCBlobInputStreamParent* aActor,
const nsID& aID,
@ -865,10 +851,6 @@ private:
virtual bool
DeallocPIPCBlobInputStreamParent(PIPCBlobInputStreamParent* aActor) override;
virtual mozilla::ipc::IPCResult
RecvPBlobConstructor(PBlobParent* aActor,
const BlobConstructorParams& params) override;
virtual mozilla::ipc::IPCResult RecvNSSU2FTokenIsCompatibleVersion(const nsString& aVersion,
bool* aIsCompatible) override;

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

@ -4,9 +4,6 @@
* 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/. */
include protocol PBlob;
include protocol PMemoryStream;
include IPCBlob;
include IPCStream;
include ProtocolTypes;
@ -47,125 +44,6 @@ struct ClonedMessageData
MessagePortIdentifier[] identfiers;
};
struct MemoryBlobDataStream
{
PMemoryStream stream;
uint64_t length;
};
union BlobDataStream
{
MemoryBlobDataStream;
// InputStreamParams is used only when we are _sure_ that the serialized size
// is lower than 1 Mb. Otherwise we use MemoryBlobDataStream.
IPCStream;
};
union BlobData
{
// For remote blobs.
nsID;
// For memory-backed blobs.
BlobDataStream;
// For multiplex blobs.
BlobData[];
};
union OptionalBlobData
{
BlobData;
void_t;
};
struct NormalBlobConstructorParams
{
nsString contentType;
uint64_t length;
// This must be of type BlobData in a child->parent message, and will always
// be of type void_t in a parent->child message.
OptionalBlobData optionalBlobData;
};
struct FileBlobConstructorParams
{
nsString name;
nsString contentType;
nsString path;
uint64_t length;
int64_t modDate;
bool isDirectory;
// This must be of type BlobData in a child->parent message, and will always
// be of type void_t in a parent->child message.
OptionalBlobData optionalBlobData;
};
struct SlicedBlobConstructorParams
{
PBlob source;
nsID id;
uint64_t begin;
uint64_t end;
nsString contentType;
};
struct MysteryBlobConstructorParams
{
// Nothing is known about this type of blob.
};
struct KnownBlobConstructorParams
{
nsID id;
};
// This may only be used for same-process inter-thread communication!
struct SameProcessBlobConstructorParams
{
// This member should be reinterpret_cast'd to mozilla::dom::BlobImpl. It
// carries a reference.
intptr_t addRefedBlobImpl;
};
union AnyBlobConstructorParams
{
// These types may be sent to/from parent and child.
NormalBlobConstructorParams;
FileBlobConstructorParams;
SameProcessBlobConstructorParams;
// This type may only be sent from parent to child.
MysteryBlobConstructorParams;
// These types may only be sent from child to parent.
SlicedBlobConstructorParams;
KnownBlobConstructorParams;
};
struct ChildBlobConstructorParams
{
nsID id;
// May not be SlicedBlobConstructorParams or KnownBlobConstructorParams.
AnyBlobConstructorParams blobParams;
};
struct ParentBlobConstructorParams
{
// May not be MysteryBlobConstructorParams.
AnyBlobConstructorParams blobParams;
};
union BlobConstructorParams
{
ChildBlobConstructorParams;
ParentBlobConstructorParams;
};
union IPCDataTransferData
{
nsString; // text

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

@ -5,7 +5,6 @@
* 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/. */
include protocol PBlob;
include protocol PColorPicker;
include protocol PContent;
include protocol PContentBridge;

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

@ -5,7 +5,6 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
include protocol PBackground;
include protocol PBlob;
include protocol PBrowser;
include protocol PCompositorBridge;
include protocol PContentBridge;
@ -21,7 +20,6 @@ include protocol PProcessHangMonitor;
include protocol PImageBridge;
include protocol PIPCBlobInputStream;
include protocol PMedia;
include protocol PMemoryStream;
include protocol PNecko;
include protocol PGMPContent;
include protocol PGMPService;
@ -283,7 +281,6 @@ struct XPCOMInitData
*/
nested(upto inside_cpow) sync protocol PContent
{
manages PBlob;
manages PBrowser;
manages PContentPermissionRequest;
manages PCycleCollectWithLogs;
@ -295,7 +292,6 @@ nested(upto inside_cpow) sync protocol PContent
manages PHeapSnapshotTempFileHelper;
manages PIPCBlobInputStream;
manages PMedia;
manages PMemoryStream;
manages PNecko;
manages POfflineCacheUpdate;
manages PPrinting;
@ -341,8 +337,6 @@ both:
IPCTabContext context, uint32_t chromeFlags,
ContentParentId cpId, bool isForBrowser);
async PBlob(BlobConstructorParams params);
async PFileDescriptorSet(FileDescriptor fd);
// For parent->child, aBrowser must be non-null; aOuterWindowID can
@ -680,8 +674,6 @@ parent:
async PRemoteSpellcheckEngine();
async PMemoryStream(uint64_t aSize);
async InitCrashReporter(Shmem shmem, NativeThreadId tid);
/**

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

@ -4,13 +4,11 @@
* 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/. */
include protocol PBlob;
include protocol PBrowser;
include protocol PContent;
include protocol PJavaScript;
include protocol PFileDescriptorSet;
include protocol PChildToParentStream;
include protocol PMemoryStream;
include protocol PParentToChildStream;
include protocol PIPCBlobInputStream;
@ -38,12 +36,10 @@ namespace dom {
*/
nested(upto inside_cpow) sync protocol PContentBridge
{
manages PBlob;
manages PBrowser;
manages PFileDescriptorSet;
manages PJavaScript;
manages PChildToParentStream;
manages PMemoryStream;
manages PParentToChildStream;
manages PIPCBlobInputStream;
@ -71,8 +67,6 @@ parent:
async PChildToParentStream();
async PMemoryStream(uint64_t aSize);
both:
// Both the parent and the child can construct the PBrowser.
// See the comment in PContent::PBrowser().
@ -80,8 +74,6 @@ both:
IPCTabContext context, uint32_t chromeFlags,
ContentParentId cpId, bool isForBrowser);
async PBlob(BlobConstructorParams params);
async PFileDescriptorSet(FileDescriptor fd);
async AsyncMessage(nsString aMessage, CpowEntry[] aCpows,

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

@ -11,7 +11,6 @@
#include "mozilla/dom/File.h"
#include "mozilla/dom/PermissionMessageUtils.h"
#include "mozilla/dom/TabChild.h"
#include "mozilla/dom/ipc/BlobChild.h"
#include "mozilla/dom/ipc/StructuredCloneData.h"
#include "mozilla/ipc/FileDescriptorSetChild.h"
#include "mozilla/ipc/InputStreamUtils.h"
@ -20,7 +19,6 @@
#include "mozilla/ipc/IPCStreamSource.h"
#include "mozilla/ipc/PChildToParentStreamChild.h"
#include "mozilla/ipc/PParentToChildStreamChild.h"
#include "mozilla/dom/ipc/MemoryStreamChild.h"
#include "mozilla/dom/ipc/IPCBlobInputStreamChild.h"
#include "nsPrintfCString.h"
@ -107,19 +105,6 @@ nsIContentChild::RecvPBrowserConstructor(PBrowserChild* aActor,
return IPC_OK();
}
PMemoryStreamChild*
nsIContentChild::AllocPMemoryStreamChild(const uint64_t& aSize)
{
return new MemoryStreamChild();
}
bool
nsIContentChild::DeallocPMemoryStreamChild(PMemoryStreamChild* aActor)
{
delete aActor;
return true;
}
PIPCBlobInputStreamChild*
nsIContentChild::AllocPIPCBlobInputStreamChild(const nsID& aID,
const uint64_t& aSize)
@ -140,43 +125,6 @@ nsIContentChild::DeallocPIPCBlobInputStreamChild(PIPCBlobInputStreamChild* aActo
return true;
}
PBlobChild*
nsIContentChild::AllocPBlobChild(const BlobConstructorParams& aParams)
{
return BlobChild::Create(this, aParams);
}
bool
nsIContentChild::DeallocPBlobChild(PBlobChild* aActor)
{
BlobChild::Destroy(aActor);
return true;
}
BlobChild*
nsIContentChild::GetOrCreateActorForBlob(Blob* aBlob)
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(aBlob);
RefPtr<BlobImpl> blobImpl = aBlob->Impl();
MOZ_ASSERT(blobImpl);
return GetOrCreateActorForBlobImpl(blobImpl);
}
BlobChild*
nsIContentChild::GetOrCreateActorForBlobImpl(BlobImpl* aImpl)
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(aImpl);
BlobChild* actor = BlobChild::GetOrCreate(this, aImpl);
NS_ENSURE_TRUE(actor, nullptr);
return actor;
}
PChildToParentStreamChild*
nsIContentChild::AllocPChildToParentStreamChild()
{

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

@ -42,12 +42,10 @@ class CpowEntry;
namespace dom {
class Blob;
class BlobChild;
class BlobImpl;
class BlobConstructorParams;
class ClonedMessageData;
class IPCTabContext;
class PBlobChild;
class PBrowserChild;
class nsIContentChild : public nsISupports
@ -57,16 +55,6 @@ class nsIContentChild : public nsISupports
public:
NS_DECLARE_STATIC_IID_ACCESSOR(NS_ICONTENTCHILD_IID)
BlobChild* GetOrCreateActorForBlob(Blob* aBlob);
BlobChild* GetOrCreateActorForBlobImpl(BlobImpl* aImpl);
virtual PBlobChild*
SendPBlobConstructor(PBlobChild* aActor,
const BlobConstructorParams& aParams) = 0;
virtual mozilla::ipc::PMemoryStreamChild*
SendPMemoryStreamConstructor(const uint64_t& aSize) = 0;
virtual bool
SendPBrowserConstructor(PBrowserChild* aActor,
const TabId& aTabId,
@ -102,15 +90,6 @@ protected:
const ContentParentId& aCpID,
const bool& aIsForBrowse);
virtual PBlobChild* AllocPBlobChild(const BlobConstructorParams& aParams);
virtual bool DeallocPBlobChild(PBlobChild* aActor);
virtual mozilla::ipc::PMemoryStreamChild*
AllocPMemoryStreamChild(const uint64_t& aSize);
virtual bool DeallocPMemoryStreamChild(mozilla::ipc::PMemoryStreamChild* aActor);
virtual mozilla::ipc::PIPCBlobInputStreamChild*
AllocPIPCBlobInputStreamChild(const nsID& aID, const uint64_t& aSize);

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

@ -14,9 +14,7 @@
#include "mozilla/dom/PTabContext.h"
#include "mozilla/dom/PermissionMessageUtils.h"
#include "mozilla/dom/TabParent.h"
#include "mozilla/dom/ipc/BlobParent.h"
#include "mozilla/dom/ipc/IPCBlobInputStreamParent.h"
#include "mozilla/dom/ipc/MemoryStreamParent.h"
#include "mozilla/dom/ipc/StructuredCloneData.h"
#include "mozilla/jsipc/CrossProcessObjectWrappers.h"
#include "mozilla/ipc/FileDescriptorSetParent.h"
@ -206,32 +204,6 @@ nsIContentParent::DeallocPBrowserParent(PBrowserParent* aFrame)
return true;
}
PBlobParent*
nsIContentParent::AllocPBlobParent(const BlobConstructorParams& aParams)
{
return BlobParent::Create(this, aParams);
}
bool
nsIContentParent::DeallocPBlobParent(PBlobParent* aActor)
{
BlobParent::Destroy(aActor);
return true;
}
PMemoryStreamParent*
nsIContentParent::AllocPMemoryStreamParent(const uint64_t& aSize)
{
return new MemoryStreamParent(aSize);
}
bool
nsIContentParent::DeallocPMemoryStreamParent(PMemoryStreamParent* aActor)
{
delete aActor;
return true;
}
PIPCBlobInputStreamParent*
nsIContentParent::AllocPIPCBlobInputStreamParent(const nsID& aID,
const uint64_t& aSize)
@ -247,30 +219,6 @@ nsIContentParent::DeallocPIPCBlobInputStreamParent(PIPCBlobInputStreamParent* aA
return true;
}
BlobParent*
nsIContentParent::GetOrCreateActorForBlob(Blob* aBlob)
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(aBlob);
RefPtr<BlobImpl> blobImpl = aBlob->Impl();
MOZ_ASSERT(blobImpl);
return GetOrCreateActorForBlobImpl(blobImpl);
}
BlobParent*
nsIContentParent::GetOrCreateActorForBlobImpl(BlobImpl* aImpl)
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(aImpl);
BlobParent* actor = BlobParent::GetOrCreate(this, aImpl);
NS_ENSURE_TRUE(actor, nullptr);
return actor;
}
mozilla::ipc::IPCResult
nsIContentParent::RecvSyncMessage(const nsString& aMsg,
const ClonedMessageData& aData,

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

@ -36,7 +36,6 @@ namespace ipc {
class PFileDescriptorSetParent;
class PChildToParentStreamParent;
class PParentToChildStreamParent;
class PMemoryStreamParent;
class PIPCBlobInputStreamParent;
}
@ -45,11 +44,9 @@ namespace dom {
class Blob;
class BlobConstructorParams;
class BlobImpl;
class BlobParent;
class ContentParent;
class ContentBridgeParent;
class IPCTabContext;
class PBlobParent;
class PBrowserParent;
class nsIContentParent : public nsISupports
@ -62,16 +59,9 @@ public:
nsIContentParent();
BlobParent* GetOrCreateActorForBlob(Blob* aBlob);
BlobParent* GetOrCreateActorForBlobImpl(BlobImpl* aImpl);
virtual ContentParentId ChildID() const = 0;
virtual bool IsForBrowser() const = 0;
MOZ_MUST_USE virtual PBlobParent*
SendPBlobConstructor(PBlobParent* aActor,
const BlobConstructorParams& aParams) = 0;
virtual mozilla::ipc::PIPCBlobInputStreamParent*
SendPIPCBlobInputStreamConstructor(mozilla::ipc::PIPCBlobInputStreamParent* aActor,
const nsID& aID,
@ -126,15 +116,6 @@ protected: // IPDL methods
const bool& aIsForBrowser);
virtual bool DeallocPBrowserParent(PBrowserParent* frame);
virtual PBlobParent* AllocPBlobParent(const BlobConstructorParams& aParams);
virtual bool DeallocPBlobParent(PBlobParent* aActor);
virtual mozilla::ipc::PMemoryStreamParent*
AllocPMemoryStreamParent(const uint64_t& aSize);
virtual bool DeallocPMemoryStreamParent(mozilla::ipc::PMemoryStreamParent* aActor);
virtual mozilla::ipc::PIPCBlobInputStreamParent*
AllocPIPCBlobInputStreamParent(const nsID& aID, const uint64_t& aSize);

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

@ -580,8 +580,19 @@ AudioStream::GetTimeStretched(AudioBufferWriter& aWriter)
} else {
// Write silence if invalid format.
AutoTArray<AudioDataValue, 1000> buf;
buf.SetLength(mOutChannels * c->Frames());
memset(buf.Elements(), 0, buf.Length() * sizeof(AudioDataValue));
auto size = CheckedUint32(mOutChannels) * c->Frames();
if (!size.isValid()) {
// The overflow should not happen in normal case.
LOGW("Invalid member data: %d channels, %d frames", mOutChannels, c->Frames());
return;
}
buf.SetLength(size.value());
size = size * sizeof(AudioDataValue);
if (!size.isValid()) {
LOGW("The required memory size is too large.");
return;
}
memset(buf.Elements(), 0, size.value());
mTimeStretcher->putSamples(buf.Elements(), c->Frames());
}
}

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

@ -7,8 +7,6 @@
#include "MessagePort.h"
#include "MessagePortChild.h"
#include "MessagePortParent.h"
#include "mozilla/dom/ipc/BlobChild.h"
#include "mozilla/dom/ipc/BlobParent.h"
#include "mozilla/dom/File.h"
#include "mozilla/dom/PMessagePort.h"
#include "mozilla/ipc/BackgroundChild.h"

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

@ -366,7 +366,7 @@ WifiGeoPositionProvider.prototype = {
if (useCached) {
gCachedRequest.location.timestamp = Date.now();
this.notifyListener("update", [gCachedRequest.location]);
this.listener.update(gCachedRequest.location);
return;
}
@ -377,14 +377,11 @@ WifiGeoPositionProvider.prototype = {
let xhr = Components.classes["@mozilla.org/xmlextras/xmlhttprequest;1"]
.createInstance(Ci.nsIXMLHttpRequest);
this.notifyListener("locationUpdatePending");
try {
xhr.open("POST", url, true);
xhr.channel.loadFlags = Ci.nsIChannel.LOAD_ANONYMOUS;
} catch (e) {
this.notifyListener("notifyError",
[POSITION_UNAVAILABLE]);
this.listener.notifyError(POSITION_UNAVAILABLE);
return;
}
xhr.setRequestHeader("Content-Type", "application/json; charset=UTF-8");
@ -393,19 +390,16 @@ WifiGeoPositionProvider.prototype = {
xhr.timeout = Services.prefs.getIntPref("geo.wifi.xhr.timeout");
xhr.ontimeout = () => {
LOG("Location request XHR timed out.")
this.notifyListener("notifyError",
[POSITION_UNAVAILABLE]);
this.listener.notifyError(POSITION_UNAVAILABLE);
};
xhr.onerror = () => {
this.notifyListener("notifyError",
[POSITION_UNAVAILABLE]);
this.listener.notifyError(POSITION_UNAVAILABLE);
};
xhr.onload = () => {
LOG("server returned status: " + xhr.status + " --> " + JSON.stringify(xhr.response));
if ((xhr.channel instanceof Ci.nsIHttpChannel && xhr.status != 200) ||
!xhr.response || !xhr.response.location) {
this.notifyListener("notifyError",
[POSITION_UNAVAILABLE]);
this.listener.notifyError(POSITION_UNAVAILABLE);
return;
}
@ -413,22 +407,13 @@ WifiGeoPositionProvider.prototype = {
xhr.response.location.lng,
xhr.response.accuracy);
this.notifyListener("update", [newLocation]);
this.listener.update(newLocation);
gCachedRequest = new CachedRequest(newLocation, data.cellTowers, data.wifiAccessPoints);
};
var requestData = JSON.stringify(data);
LOG("sending " + requestData);
xhr.send(requestData);
},
notifyListener: function(listenerFunc, args) {
args = args || [];
try {
this.listener[listenerFunc].apply(this.listener, args);
} catch(e) {
Cu.reportError(e);
}
}
};

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

@ -20,7 +20,6 @@ namespace dom {
class BlobImpl;
class ContentChild;
class ContentParent;
class PBlobChild;
} // namespace dom
@ -71,14 +70,6 @@ public:
static PBackgroundChild*
SynchronouslyCreateForCurrentThread();
static mozilla::dom::PBlobChild*
GetOrCreateActorForBlob(PBackgroundChild* aBackgroundActor,
nsIDOMBlob* aBlob);
static mozilla::dom::PBlobChild*
GetOrCreateActorForBlobImpl(PBackgroundChild* aBackgroundActor,
mozilla::dom::BlobImpl* aBlobImpl);
// See above.
static void
CloseForCurrentThread();

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

@ -16,16 +16,13 @@
#include "mozilla/media/MediaChild.h"
#include "mozilla/Assertions.h"
#include "mozilla/SchedulerGroup.h"
#include "mozilla/dom/PBlobChild.h"
#include "mozilla/dom/PFileSystemRequestChild.h"
#include "mozilla/dom/FileSystemTaskBase.h"
#include "mozilla/dom/asmjscache/AsmJSCache.h"
#include "mozilla/dom/cache/ActorUtils.h"
#include "mozilla/dom/indexedDB/PBackgroundIDBFactoryChild.h"
#include "mozilla/dom/indexedDB/PBackgroundIndexedDBUtilsChild.h"
#include "mozilla/dom/ipc/BlobChild.h"
#include "mozilla/dom/ipc/IPCBlobInputStreamChild.h"
#include "mozilla/dom/ipc/MemoryStreamChild.h"
#include "mozilla/dom/ipc/PendingIPCBlobChild.h"
#include "mozilla/dom/quota/PQuotaChild.h"
#include "mozilla/dom/GamepadEventChannelChild.h"
@ -204,37 +201,6 @@ BackgroundChildImpl::DeallocPBackgroundIndexedDBUtilsChild(
return true;
}
auto
BackgroundChildImpl::AllocPBlobChild(const BlobConstructorParams& aParams)
-> PBlobChild*
{
MOZ_ASSERT(aParams.type() != BlobConstructorParams::T__None);
return mozilla::dom::BlobChild::Create(this, aParams);
}
bool
BackgroundChildImpl::DeallocPBlobChild(PBlobChild* aActor)
{
MOZ_ASSERT(aActor);
mozilla::dom::BlobChild::Destroy(aActor);
return true;
}
PMemoryStreamChild*
BackgroundChildImpl::AllocPMemoryStreamChild(const uint64_t& aSize)
{
return new mozilla::dom::MemoryStreamChild();
}
bool
BackgroundChildImpl::DeallocPMemoryStreamChild(PMemoryStreamChild* aActor)
{
delete aActor;
return true;
}
PPendingIPCBlobChild*
BackgroundChildImpl::AllocPPendingIPCBlobChild(const IPCBlob& aBlob)
{
@ -569,14 +535,11 @@ BackgroundChildImpl::DeallocPGamepadTestChannelChild(PGamepadTestChannelChild* a
void
BackgroundChildImpl::OnChannelReceivedMessage(const Message& aMsg)
{
// Telemetry collection temporarily disabled in bug 1366156.
#if 0
if (aMsg.type() == layout::PVsync::MessageType::Msg_Notify__ID) {
// Not really necessary to look at the message payload, it will be
// <0.5ms away from TimeStamp::Now()
SchedulerGroup::MarkVsyncReceived();
}
#endif
}
#endif

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

@ -70,18 +70,6 @@ protected:
DeallocPBackgroundIndexedDBUtilsChild(PBackgroundIndexedDBUtilsChild* aActor)
override;
virtual PBlobChild*
AllocPBlobChild(const BlobConstructorParams& aParams) override;
virtual bool
DeallocPBlobChild(PBlobChild* aActor) override;
virtual PMemoryStreamChild*
AllocPMemoryStreamChild(const uint64_t& aSize) override;
virtual bool
DeallocPMemoryStreamChild(PMemoryStreamChild* aActor) override;
virtual PPendingIPCBlobChild*
AllocPPendingIPCBlobChild(const IPCBlob& aBlob) override;

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

@ -24,8 +24,6 @@
#include "mozilla/dom/ContentChild.h"
#include "mozilla/dom/ContentParent.h"
#include "mozilla/dom/File.h"
#include "mozilla/dom/ipc/BlobChild.h"
#include "mozilla/dom/ipc/BlobParent.h"
#include "mozilla/ipc/ProtocolTypes.h"
#include "nsAutoPtr.h"
#include "nsCOMPtr.h"
@ -810,24 +808,6 @@ BackgroundParent::GetContentParent(PBackgroundParent* aBackgroundActor)
return ParentImpl::GetContentParent(aBackgroundActor);
}
// static
PBlobParent*
BackgroundParent::GetOrCreateActorForBlobImpl(
PBackgroundParent* aBackgroundActor,
BlobImpl* aBlobImpl)
{
AssertIsOnBackgroundThread();
MOZ_ASSERT(aBackgroundActor);
MOZ_ASSERT(aBlobImpl);
BlobParent* actor = BlobParent::GetOrCreate(aBackgroundActor, aBlobImpl);
if (NS_WARN_IF(!actor)) {
return nullptr;
}
return actor;
}
// static
intptr_t
BackgroundParent::GetRawContentParentForComparison(
@ -877,39 +857,6 @@ BackgroundChild::SynchronouslyCreateForCurrentThread()
return ChildImpl::SynchronouslyCreateForCurrentThread();
}
// static
PBlobChild*
BackgroundChild::GetOrCreateActorForBlob(PBackgroundChild* aBackgroundActor,
nsIDOMBlob* aBlob)
{
MOZ_ASSERT(aBlob);
RefPtr<BlobImpl> blobImpl = static_cast<Blob*>(aBlob)->Impl();
MOZ_ASSERT(blobImpl);
return GetOrCreateActorForBlobImpl(aBackgroundActor, blobImpl);
}
// static
PBlobChild*
BackgroundChild::GetOrCreateActorForBlobImpl(PBackgroundChild* aBackgroundActor,
BlobImpl* aBlobImpl)
{
MOZ_ASSERT(aBackgroundActor);
MOZ_ASSERT(aBlobImpl);
MOZ_ASSERT(GetForCurrentThread(),
"BackgroundChild not created on this thread yet!");
MOZ_ASSERT(aBackgroundActor == GetForCurrentThread(),
"BackgroundChild is bound to a different thread!");
BlobChild* actor = BlobChild::GetOrCreate(aBackgroundActor, aBlobImpl);
if (NS_WARN_IF(!actor)) {
return nullptr;
}
return actor;
}
// static
void
BackgroundChild::CloseForCurrentThread()

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

@ -18,7 +18,6 @@ namespace dom {
class BlobImpl;
class ContentParent;
class PBlobParent;
} // namespace dom
@ -58,10 +57,6 @@ public:
static already_AddRefed<ContentParent>
GetContentParent(PBackgroundParent* aBackgroundActor);
static mozilla::dom::PBlobParent*
GetOrCreateActorForBlobImpl(PBackgroundParent* aBackgroundActor,
BlobImpl* aBlobImpl);
// Get a value that represents the ContentParent associated with the parent
// actor for comparison. The value is not guaranteed to uniquely identify the
// ContentParent after the ContentParent has died. This function may only be

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

@ -19,7 +19,6 @@
#include "mozilla/dom/FileSystemRequestParent.h"
#include "mozilla/dom/GamepadEventChannelParent.h"
#include "mozilla/dom/GamepadTestChannelParent.h"
#include "mozilla/dom/PBlobParent.h"
#include "mozilla/dom/PGamepadEventChannelParent.h"
#include "mozilla/dom/PGamepadTestChannelParent.h"
#include "mozilla/dom/MessagePortParent.h"
@ -27,9 +26,7 @@
#include "mozilla/dom/asmjscache/AsmJSCache.h"
#include "mozilla/dom/cache/ActorUtils.h"
#include "mozilla/dom/indexedDB/ActorsParent.h"
#include "mozilla/dom/ipc/BlobParent.h"
#include "mozilla/dom/ipc/IPCBlobInputStreamParent.h"
#include "mozilla/dom/ipc/MemoryStreamParent.h"
#include "mozilla/dom/ipc/PendingIPCBlobParent.h"
#include "mozilla/dom/quota/ActorsParent.h"
#include "mozilla/ipc/BackgroundParent.h"
@ -244,53 +241,6 @@ BackgroundParentImpl::RecvFlushPendingFileDeletions()
return IPC_OK();
}
auto
BackgroundParentImpl::AllocPBlobParent(const BlobConstructorParams& aParams)
-> PBlobParent*
{
AssertIsInMainProcess();
AssertIsOnBackgroundThread();
if (NS_WARN_IF(aParams.type() !=
BlobConstructorParams::TParentBlobConstructorParams)) {
ASSERT_UNLESS_FUZZING();
return nullptr;
}
return mozilla::dom::BlobParent::Create(this, aParams);
}
bool
BackgroundParentImpl::DeallocPBlobParent(PBlobParent* aActor)
{
AssertIsInMainProcess();
AssertIsOnBackgroundThread();
MOZ_ASSERT(aActor);
mozilla::dom::BlobParent::Destroy(aActor);
return true;
}
PMemoryStreamParent*
BackgroundParentImpl::AllocPMemoryStreamParent(const uint64_t& aSize)
{
AssertIsInMainProcess();
AssertIsOnBackgroundThread();
return new mozilla::dom::MemoryStreamParent(aSize);
}
bool
BackgroundParentImpl::DeallocPMemoryStreamParent(PMemoryStreamParent* aActor)
{
AssertIsInMainProcess();
AssertIsOnBackgroundThread();
MOZ_ASSERT(aActor);
delete aActor;
return true;
}
PPendingIPCBlobParent*
BackgroundParentImpl::AllocPPendingIPCBlobParent(const IPCBlob& aBlob)
{
@ -326,21 +276,6 @@ BackgroundParentImpl::DeallocPIPCBlobInputStreamParent(PIPCBlobInputStreamParent
return true;
}
mozilla::ipc::IPCResult
BackgroundParentImpl::RecvPBlobConstructor(PBlobParent* aActor,
const BlobConstructorParams& aParams)
{
const ParentBlobConstructorParams& params = aParams;
if (params.blobParams().type() == AnyBlobConstructorParams::TKnownBlobConstructorParams) {
if (!aActor->SendCreatedFromKnownBlob()) {
return IPC_FAIL_NO_REASON(this);
}
return IPC_OK();
}
return IPC_OK();
}
PFileDescriptorSetParent*
BackgroundParentImpl::AllocPFileDescriptorSetParent(
const FileDescriptor& aFileDescriptor)

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

@ -63,18 +63,6 @@ protected:
virtual mozilla::ipc::IPCResult
RecvFlushPendingFileDeletions() override;
virtual PBlobParent*
AllocPBlobParent(const BlobConstructorParams& aParams) override;
virtual bool
DeallocPBlobParent(PBlobParent* aActor) override;
virtual PMemoryStreamParent*
AllocPMemoryStreamParent(const uint64_t& aSize) override;
virtual bool
DeallocPMemoryStreamParent(PMemoryStreamParent* aActor) override;
virtual PPendingIPCBlobParent*
AllocPPendingIPCBlobParent(const IPCBlob& aBlob) override;
@ -88,10 +76,6 @@ protected:
virtual bool
DeallocPIPCBlobInputStreamParent(PIPCBlobInputStreamParent* aActor) override;
virtual mozilla::ipc::IPCResult
RecvPBlobConstructor(PBlobParent* aActor,
const BlobConstructorParams& params) override;
virtual PFileDescriptorSetParent*
AllocPFileDescriptorSetParent(const FileDescriptor& aFileDescriptor)
override;

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

@ -43,19 +43,6 @@ struct MultiplexInputStreamParams
bool startedReadingCurrent;
};
struct RemoteInputStreamParams
{
nsID id;
};
// XXX This may only be used for same-process inter-thread communication! The
// value should be reinterpret_cast'd to nsIInputStream. It carries a
// reference.
struct SameProcessInputStreamParams
{
intptr_t addRefedInputStream;
};
struct SlicedInputStreamParams
{
InputStreamParams stream;
@ -78,8 +65,6 @@ union InputStreamParams
BufferedInputStreamParams;
MIMEInputStreamParams;
MultiplexInputStreamParams;
RemoteInputStreamParams;
SameProcessInputStreamParams;
SlicedInputStreamParams;
IPCBlobInputStreamParams;
};

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

@ -10,8 +10,6 @@
#include "mozilla/Assertions.h"
#include "mozilla/dom/File.h"
#include "mozilla/dom/ipc/BlobChild.h"
#include "mozilla/dom/ipc/BlobParent.h"
#include "mozilla/dom/ipc/IPCBlobInputStream.h"
#include "mozilla/dom/ipc/IPCBlobInputStreamStorage.h"
#include "nsComponentManagerUtils.h"
@ -101,44 +99,6 @@ InputStreamHelper::DeserializeInputStream(const InputStreamParams& aParams,
serializable = do_CreateInstance(kMultiplexInputStreamCID);
break;
// When the input stream already exists in this process, all we need to do
// is retrieve the original instead of sending any data over the wire.
case InputStreamParams::TRemoteInputStreamParams: {
if (NS_WARN_IF(!XRE_IsParentProcess())) {
return nullptr;
}
const nsID& id = aParams.get_RemoteInputStreamParams().id();
RefPtr<BlobImpl> blobImpl = BlobParent::GetBlobImplForID(id);
MOZ_ASSERT(blobImpl, "Invalid blob contents");
// If fetching the internal stream fails, we ignore it and return a
// null stream.
ErrorResult rv;
nsCOMPtr<nsIInputStream> stream;
blobImpl->GetInternalStream(getter_AddRefs(stream), rv);
if (NS_WARN_IF(rv.Failed()) || !stream) {
NS_WARNING("Couldn't obtain a valid stream from the blob");
rv.SuppressException();
}
return stream.forget();
}
case InputStreamParams::TSameProcessInputStreamParams: {
MOZ_ASSERT(aFileDescriptors.IsEmpty());
const SameProcessInputStreamParams& params =
aParams.get_SameProcessInputStreamParams();
stream = dont_AddRef(
reinterpret_cast<nsIInputStream*>(params.addRefedInputStream()));
MOZ_ASSERT(stream);
return stream.forget();
}
case InputStreamParams::TSlicedInputStreamParams:
serializable = new SlicedInputStream();
break;

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

@ -6,7 +6,6 @@ include protocol PAsmJSCacheEntry;
include protocol PBackgroundIDBFactory;
include protocol PBackgroundIndexedDBUtils;
include protocol PBackgroundTest;
include protocol PBlob;
include protocol PBroadcastChannel;
include protocol PCache;
include protocol PCacheStorage;
@ -17,7 +16,6 @@ include protocol PGamepadEventChannel;
include protocol PGamepadTestChannel;
include protocol PIPCBlobInputStream;
include protocol PPendingIPCBlob;
include protocol PMemoryStream;
include protocol PMessagePort;
include protocol PCameras;
include protocol PQuota;
@ -55,7 +53,6 @@ sync protocol PBackground
manages PBackgroundIDBFactory;
manages PBackgroundIndexedDBUtils;
manages PBackgroundTest;
manages PBlob;
manages PBroadcastChannel;
manages PCache;
manages PCacheStorage;
@ -65,7 +62,6 @@ sync protocol PBackground
manages PGamepadEventChannel;
manages PGamepadTestChannel;
manages PIPCBlobInputStream;
manages PMemoryStream;
manages PPendingIPCBlob;
manages PMessagePort;
manages PCameras;
@ -119,8 +115,6 @@ parent:
async PGamepadTestChannel();
async PMemoryStream(uint64_t aSize);
async PWebAuthnTransaction();
child:
@ -134,8 +128,6 @@ child:
async PPendingIPCBlob(IPCBlob blob);
both:
async PBlob(BlobConstructorParams params);
async PFileDescriptorSet(FileDescriptor fd);
};

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

@ -807,14 +807,6 @@ description =
# The rest
[PHeapSnapshotTempFileHelper::OpenHeapSnapshotTempFile]
description =
[PBlob::BlobStreamSync]
description =
[PBlob::WaitForSliceCreation]
description =
[PBlob::GetFileId]
description =
[PBlob::GetFilePath]
description =
[PBackgroundMutableFile::GetFileId]
description =
[PBackgroundIndexedDBUtils::GetFileReferences]

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

@ -2607,7 +2607,7 @@ GCMarker::stackContainsCrossZonePointerTo(const Cell* target) const
if (sourceZone == targetZone)
continue;
if ((source->is<ProxyObject>() && source->as<ProxyObject>().target() == target) ||
if ((IsCrossCompartmentWrapper(source) && source->as<ProxyObject>().target() == target) ||
Debugger::isDebuggerCrossCompartmentEdge(source, target))
{
return sourceZone;

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

@ -97,6 +97,7 @@ let CompileError;
let LinkError;
let RuntimeError;
let Memory;
let instanceProto;
let memoryProto;
let mem1;
let Table;
@ -350,7 +351,7 @@ test(() => {
}, "'WebAssembly.Instance.prototype' data property");
test(() => {
const instanceProto = Instance.prototype;
instanceProto = Instance.prototype;
const instanceProtoDesc = Object.getOwnPropertyDescriptor(Instance, 'prototype');
assert_equals(instanceProto, instanceProtoDesc.value);
assert_equals(String(instanceProto), "[object WebAssembly.Instance]");
@ -366,12 +367,16 @@ test(() => {
}, "'WebAssembly.Instance' instance objects");
test(() => {
const instanceExportsDesc = Object.getOwnPropertyDescriptor(exportingInstance, 'exports');
assert_equals(typeof instanceExportsDesc.value, "object");
assert_equals(instanceExportsDesc.writable, true);
assert_equals(instanceExportsDesc.enumerable, true);
assert_equals(instanceExportsDesc.configurable, true);
}, "'WebAssembly.Instance' 'exports' data property");
const exportsDesc = Object.getOwnPropertyDescriptor(instanceProto, 'exports');
assert_equals(typeof exportsDesc.get, "function");
assert_equals(exportsDesc.set, undefined);
assert_equals(exportsDesc.enumerable, false);
assert_equals(exportsDesc.configurable, true);
const exportsGetter = exportsDesc.get;
assertThrows(() => exportsGetter.call(), TypeError);
assertThrows(() => exportsGetter.call({}), TypeError);
assert_equals(typeof exportsGetter.call(exportingInstance), "object");
}, "'WebAssembly.Instance.prototype.exports' accessor property");
test(() => {
exportsObj = exportingInstance.exports;
@ -385,7 +390,7 @@ test(() => {
assert_equals(Object.getPrototypeOf(exportsObj), null);
assertThrows(() => Object.defineProperty(exportsObj, 'g', {}), TypeError);
assert_equals(Object.keys(exportsObj).join(), "f");
}, "'WebAssembly.Instance' 'exports' object");
}, "exports object");
test(() => {
const f = exportsObj.f;

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

@ -123,6 +123,7 @@ GetObject(const MDefinition* ins)
case MDefinition::Op_LoadElementHole:
case MDefinition::Op_TypedArrayElements:
case MDefinition::Op_TypedObjectElements:
case MDefinition::Op_CopyLexicalEnvironmentObject:
object = ins->getOperand(0);
break;
case MDefinition::Op_GetPropertyCache:

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

@ -9571,12 +9571,8 @@ CodeGenerator::generateWasm(wasm::SigIdDesc sigId, wasm::BytecodeOffset trapOffs
// functions with small framePushed). Perform overflow-checking after
// pushing framePushed to catch cases with really large frames.
Label onOverflow;
if (!omitOverRecursedCheck()) {
masm.branchPtr(Assembler::AboveOrEqual,
Address(WasmTlsReg, offsetof(wasm::TlsData, stackLimit)),
masm.getStackPointer(),
&onOverflow);
}
if (!omitOverRecursedCheck())
masm.wasmEmitStackCheck(masm.getStackPointer(), ABINonArgReg0, &onOverflow);
if (!generateBody())
return false;

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

@ -12063,7 +12063,7 @@ IonBuilder::jsop_pushlexicalenv(uint32_t index)
current->add(ins);
current->setEnvironmentChain(ins);
return resumeAfter(ins);
return Ok();
}
AbortReasonOr<Ok>
@ -12077,7 +12077,7 @@ IonBuilder::jsop_copylexicalenv(bool copySlots)
current->add(ins);
current->setEnvironmentChain(ins);
return resumeAfter(ins);
return Ok();
}
AbortReasonOr<Ok>

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

@ -11640,6 +11640,9 @@ class MNewLexicalEnvironmentObject
bool appendRoots(MRootList& roots) const override {
return roots.append(scope_);
}
AliasSet getAliasSet() const override {
return AliasSet::None();
}
};
// Allocate a new LexicalEnvironmentObject from existing one
@ -11667,6 +11670,11 @@ class MCopyLexicalEnvironmentObject
bool possiblyCalls() const override {
return true;
}
AliasSet getAliasSet() const override {
return AliasSet::Load(AliasSet::ObjectFields |
AliasSet::FixedSlot |
AliasSet::DynamicSlot);
}
};
// Store to vp[slot] (slots that are not inline in an object).

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

@ -3090,6 +3090,17 @@ MacroAssembler::wasmAssertNonExitInvariants(Register activation)
#endif
}
void
MacroAssembler::wasmEmitStackCheck(Register sp, Register scratch, Label* onOverflow)
{
loadPtr(Address(WasmTlsReg, offsetof(wasm::TlsData, addressOfContext)), scratch);
loadPtr(Address(scratch, 0), scratch);
branchPtr(Assembler::AboveOrEqual,
Address(scratch, offsetof(JSContext, jitStackLimitNoInterrupt)),
sp,
onOverflow);
}
//}}} check_macroassembler_style
void

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

@ -1479,6 +1479,9 @@ class MacroAssembler : public MacroAssemblerSpecific
// Assert invariants that should be true within any non-exit-stub wasm code.
void wasmAssertNonExitInvariants(Register activation);
// Perform a stack-overflow test, branching to the given Label on overflow.
void wasmEmitStackCheck(Register sp, Register scratch, Label* onOverflow);
public:
// ========================================================================
// Clamping functions.

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

@ -1559,8 +1559,9 @@ Simulator::handleWasmInterrupt()
uint8_t* fp = (uint8_t*)get_register(r11);
WasmActivation* activation = wasm::MaybeActiveActivation(cx_);
const wasm::Code* code = activation->compartment()->wasm.lookupCode(pc);
if (!code || !code->segmentTier().containsFunctionPC(pc))
const wasm::CodeSegment* segment;
const wasm::Code* code = activation->compartment()->wasm.lookupCode(pc, &segment);
if (!code || !segment->containsFunctionPC(pc))
return;
// fp can be null during the prologue/epilogue of the entry function.
@ -1568,7 +1569,7 @@ Simulator::handleWasmInterrupt()
return;
activation->startInterrupt(pc, fp);
set_pc(int32_t(code->segmentTier().interruptCode()));
set_pc(int32_t(segment->interruptCode()));
}
// WebAssembly memories contain an extra region of guard pages (see
@ -1590,15 +1591,18 @@ Simulator::handleWasmFault(int32_t addr, unsigned numBytes)
if (!instance || !instance->memoryAccessInGuardRegion((uint8_t*)addr, numBytes))
return false;
const wasm::MemoryAccess* memoryAccess = instance->code().lookupMemoryAccess(pc);
const wasm::CodeSegment* segment;
const wasm::MemoryAccess* memoryAccess = instance->code().lookupMemoryAccess(pc, &segment);
if (!memoryAccess) {
act->startInterrupt(pc, fp);
set_pc(int32_t(instance->codeSegmentTier().outOfBoundsCode()));
if (!instance->code().containsCodePC(pc, &segment))
MOZ_CRASH("Cannot map PC to trap handler");
set_pc(int32_t(segment->outOfBoundsCode()));
return true;
}
MOZ_ASSERT(memoryAccess->hasTrapOutOfLineCode());
set_pc(int32_t(memoryAccess->trapOutOfLineCode(instance->codeBaseTier())));
set_pc(int32_t(memoryAccess->trapOutOfLineCode(segment->base())));
return true;
}

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

@ -244,12 +244,13 @@ void Simulator::handle_wasm_interrupt() {
uint8_t* fp = (uint8_t*)xreg(30);
js::WasmActivation* activation = js::wasm::MaybeActiveActivation(cx_);
const js::wasm::Code* code = activation->compartment()->wasm.lookupCode(pc);
if (!code || !code->segmentTier().containsFunctionPC(pc))
const js::wasm::CodeSegment* segment;
const js::wasm::Code* code = activation->compartment()->wasm.lookupCode(pc, &segment);
if (!code || !segment->containsFunctionPC(pc))
return;
activation->startInterrupt(pc, fp);
set_pc((Instruction*)code->segmentTier().interruptCode());
set_pc((Instruction*)segment->interruptCode());
}

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

@ -8057,7 +8057,8 @@ DebuggerFrame::setOnStepHandler(JSContext* cx, HandleDebuggerFrame frame, OnStep
return false;
} else if (!handler && prior) {
// Single stepping toggled on->off.
if (!instance->debug().decrementStepModeCount(cx, wasmFrame->funcIndex()))
FreeOp* fop = cx->runtime()->defaultFreeOp();
if (!instance->debug().decrementStepModeCount(fop, wasmFrame->funcIndex()))
return false;
}
} else {
@ -8391,8 +8392,7 @@ DebuggerFrame_maybeDecrementFrameScriptStepModeCount(FreeOp* fop, AbstractFrameP
return;
if (frame.isWasmDebugFrame()) {
wasm::Instance* instance = frame.wasmInstance();
instance->debug().decrementStepModeCount(instance->cx(),
frame.asWasmDebugFrame()->funcIndex());
instance->debug().decrementStepModeCount(fop, frame.asWasmDebugFrame()->funcIndex());
} else {
frame.script()->decrementStepModeCount(fop);
}

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

@ -1684,9 +1684,7 @@ WasmActivation::startInterrupt(void* pc, uint8_t* fp)
cx_->runtime()->setWasmResumePC(pc);
exitFP_ = reinterpret_cast<wasm::Frame*>(fp);
MOZ_ASSERT(cx() == exitFP_->tls->cx);
MOZ_ASSERT(compartment() == exitFP_->tls->instance->compartment());
MOZ_ASSERT(interrupted());
}

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

@ -1775,7 +1775,7 @@ class MOZ_STACK_CLASS ModuleValidator
public:
bool init() {
auto tierMetadata = js::MakeUnique<MetadataTier>(CompileMode::Ion);
auto tierMetadata = js::MakeUnique<MetadataTier>(Tier::Ion);
if (!tierMetadata)
return false;
@ -8072,12 +8072,7 @@ TryInstantiate(JSContext* cx, CallArgs args, Module& module, const AsmJSMetadata
if (!module.instantiate(cx, funcs, table, memory, valImports, nullptr, instanceObj))
return false;
RootedValue exportObjVal(cx);
if (!JS_GetProperty(cx, instanceObj, InstanceExportField, &exportObjVal))
return false;
MOZ_RELEASE_ASSERT(exportObjVal.isObject());
exportObj.set(&exportObjVal.toObject());
exportObj.set(&instanceObj->exportsObj());
return true;
}
@ -8555,7 +8550,7 @@ LookupAsmJSModuleInCache(JSContext* cx, AsmJSParser& parser, bool* loadedFromCac
if (!Module::assumptionsMatch(assumptions, cursor, remain))
return true;
auto tierMetadata = js::MakeUnique<MetadataTier>(CompileMode::Ion);
auto tierMetadata = js::MakeUnique<MetadataTier>(Tier::Ion);
if (!tierMetadata)
return false;

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

@ -2225,14 +2225,11 @@ class BaseCompiler
// be (we may need arbitrary spill slots and outgoing param slots) so
// emit a patchable add that is patched in endFunction().
//
// ScratchReg may be used by branchPtr(), so use ABINonArgReg0 for the
// effective address.
// ScratchReg may be used by branchPtr(), so use ABINonArgReg0/1 for
// temporaries.
stackAddOffset_ = masm.add32ToPtrWithPatch(StackPointer, ABINonArgReg0);
masm.branchPtr(Assembler::AboveOrEqual,
Address(WasmTlsReg, offsetof(TlsData, stackLimit)),
ABINonArgReg0,
&stackOverflowLabel_);
masm.wasmEmitStackCheck(ABINonArgReg0, ABINonArgReg1, &stackOverflowLabel_);
// Copy arguments from registers to stack.
@ -7574,7 +7571,7 @@ js::wasm::BaselineCanCompile()
bool
js::wasm::BaselineCompileFunction(CompileTask* task, FuncCompileUnit* unit, UniqueChars *error)
{
MOZ_ASSERT(task->mode() == CompileMode::Baseline);
MOZ_ASSERT(task->tier() == Tier::Baseline);
MOZ_ASSERT(task->env().kind == ModuleKind::Wasm);
const FuncBytes& func = unit->func();

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

@ -157,7 +157,7 @@ SendCodeRangesToProfiler(const CodeSegment& cs, const Bytes& bytecode, const Met
if (!enabled)
return;
for (const CodeRange& codeRange : metadata.tier().codeRanges) {
for (const CodeRange& codeRange : metadata.metadata(cs.tier()).codeRanges) {
if (!codeRange.isFunction())
continue;
@ -193,7 +193,7 @@ SendCodeRangesToProfiler(const CodeSegment& cs, const Bytes& bytecode, const Met
}
/* static */ UniqueConstCodeSegment
CodeSegment::create(CompileMode mode,
CodeSegment::create(Tier tier,
MacroAssembler& masm,
const ShareableBytes& bytecode,
const LinkDataTier& linkData,
@ -217,11 +217,11 @@ CodeSegment::create(CompileMode mode,
// Zero the padding.
memset(codeBytes.get() + bytesNeeded, 0, padding);
return create(mode, Move(codeBytes), codeLength, bytecode, linkData, metadata);
return create(tier, Move(codeBytes), codeLength, bytecode, linkData, metadata);
}
/* static */ UniqueConstCodeSegment
CodeSegment::create(CompileMode mode,
CodeSegment::create(Tier tier,
const Bytes& unlinkedBytes,
const ShareableBytes& bytecode,
const LinkDataTier& linkData,
@ -239,11 +239,11 @@ CodeSegment::create(CompileMode mode,
memcpy(codeBytes.get(), unlinkedBytes.begin(), unlinkedBytes.length());
memset(codeBytes.get() + unlinkedBytes.length(), 0, padding);
return create(mode, Move(codeBytes), codeLength, bytecode, linkData, metadata);
return create(tier, Move(codeBytes), codeLength, bytecode, linkData, metadata);
}
/* static */ UniqueConstCodeSegment
CodeSegment::create(CompileMode mode,
CodeSegment::create(Tier tier,
UniqueCodeBytes codeBytes,
uint32_t codeLength,
const ShareableBytes& bytecode,
@ -259,14 +259,14 @@ CodeSegment::create(CompileMode mode,
if (!cs)
return nullptr;
if (!cs->initialize(mode, Move(codeBytes), codeLength, bytecode, linkData, metadata))
if (!cs->initialize(tier, Move(codeBytes), codeLength, bytecode, linkData, metadata))
return nullptr;
return UniqueConstCodeSegment(cs.release());
}
bool
CodeSegment::initialize(CompileMode mode,
CodeSegment::initialize(Tier tier,
UniqueCodeBytes codeBytes,
uint32_t codeLength,
const ShareableBytes& bytecode,
@ -274,8 +274,9 @@ CodeSegment::initialize(CompileMode mode,
const Metadata& metadata)
{
MOZ_ASSERT(bytes_ == nullptr);
MOZ_ASSERT(tier == Tier::Baseline || tier == Tier::Ion);
mode_ = mode;
tier_ = tier;
bytes_ = Move(codeBytes);
functionLength_ = linkData.functionCodeLength;
length_ = codeLength;
@ -313,7 +314,7 @@ CodeSegment::addSizeOfMisc(mozilla::MallocSizeOf mallocSizeOf, size_t* code, siz
uint8_t*
CodeSegment::serialize(uint8_t* cursor, const LinkDataTier& linkData) const
{
MOZ_ASSERT(mode() == CompileMode::Ion);
MOZ_ASSERT(tier() == Tier::Ion);
cursor = WriteScalar<uint32_t>(cursor, length_);
uint8_t* base = cursor;
@ -340,7 +341,7 @@ CodeSegment::deserialize(const uint8_t* cursor, const ShareableBytes& bytecode,
if (!cursor)
return nullptr;
if (!initialize(CompileMode::Ion, Move(bytes), length, bytecode, linkData, metadata))
if (!initialize(Tier::Ion, Move(bytes), length, bytecode, linkData, metadata))
return nullptr;
return cursor;
@ -495,11 +496,53 @@ MetadataTier::deserialize(const uint8_t* cursor)
return cursor;
}
Tiers
Metadata::tiers() const
{
return Tiers(tier_->tier);
}
const MetadataTier&
Metadata::metadata(Tier t) const
{
switch (t) {
case Tier::Debug:
case Tier::Baseline:
MOZ_RELEASE_ASSERT(tier_->tier == Tier::Baseline);
return *tier_;
case Tier::Ion:
MOZ_RELEASE_ASSERT(tier_->tier == Tier::Ion);
return *tier_;
case Tier::TBD:
return *tier_;
default:
MOZ_CRASH();
}
}
MetadataTier&
Metadata::metadata(Tier t)
{
switch (t) {
case Tier::Debug:
case Tier::Baseline:
MOZ_RELEASE_ASSERT(tier_->tier == Tier::Baseline);
return *tier_;
case Tier::Ion:
MOZ_RELEASE_ASSERT(tier_->tier == Tier::Ion);
return *tier_;
case Tier::TBD:
return *tier_;
default:
MOZ_CRASH();
}
}
size_t
Metadata::serializedSize() const
{
return sizeof(pod()) +
tier().serializedSize() +
metadata(Tier::Ion).serializedSize() +
SerializedVectorSize(sigIds) +
SerializedPodVectorSize(globals) +
SerializedPodVectorSize(tables) +
@ -512,7 +555,12 @@ Metadata::serializedSize() const
size_t
Metadata::sizeOfExcludingThis(MallocSizeOf mallocSizeOf) const
{
return tier().sizeOfExcludingThis(mallocSizeOf) +
size_t sum = 0;
for (auto t : tiers())
sum += metadata(t).sizeOfExcludingThis(mallocSizeOf);
return sum +
SizeOfVectorExcludingThis(sigIds, mallocSizeOf) +
globals.sizeOfExcludingThis(mallocSizeOf) +
tables.sizeOfExcludingThis(mallocSizeOf) +
@ -526,7 +574,7 @@ Metadata::serialize(uint8_t* cursor) const
{
MOZ_ASSERT(!debugEnabled && debugFuncArgTypes.empty() && debugFuncReturnTypes.empty());
cursor = WriteBytes(cursor, &pod(), sizeof(pod()));
cursor = tier().serialize(cursor);
cursor = metadata(Tier::Ion).serialize(cursor);
cursor = SerializeVector(cursor, sigIds);
cursor = SerializePodVector(cursor, globals);
cursor = SerializePodVector(cursor, tables);
@ -541,7 +589,7 @@ Metadata::serialize(uint8_t* cursor) const
Metadata::deserialize(const uint8_t* cursor)
{
(cursor = ReadBytes(cursor, &pod(), sizeof(pod()))) &&
(cursor = tier().deserialize(cursor)) &&
(cursor = metadata(Tier::Ion).deserialize(cursor)) &&
(cursor = DeserializeVector(cursor, &sigIds)) &&
(cursor = DeserializePodVector(cursor, &globals)) &&
(cursor = DeserializePodVector(cursor, &tables)) &&
@ -568,9 +616,8 @@ struct ProjectFuncIndex
};
const FuncExport&
Metadata::lookupFuncExport(uint32_t funcIndex) const
MetadataTier::lookupFuncExport(uint32_t funcIndex) const
{
const FuncExportVector& funcExports = tier().funcExports;
size_t match;
if (!BinarySearch(ProjectFuncIndex(funcExports), 0, funcExports.length(), funcIndex, &match))
MOZ_CRASH("missing function export");
@ -617,6 +664,64 @@ Code::Code()
{
}
Tier
Code::anyTier() const
{
return tier_->tier();
}
Tiers
Code::tiers() const
{
return Tiers(tier_->tier());
}
const CodeSegment&
Code::segment(Tier tier) const
{
switch (tier) {
case Tier::Debug:
case Tier::Baseline:
MOZ_RELEASE_ASSERT(tier_->tier() == Tier::Baseline);
return *tier_;
case Tier::Ion:
MOZ_RELEASE_ASSERT(tier_->tier() == Tier::Ion);
return *tier_;
case Tier::TBD:
return *tier_;
default:
MOZ_CRASH();
}
}
bool
Code::containsFunctionPC(const void* pc, const CodeSegment** segmentp) const
{
for (auto t : tiers()) {
const CodeSegment& cs = segment(t);
if (cs.containsFunctionPC(pc)) {
if (segmentp)
*segmentp = &cs;
return true;
}
}
return false;
}
bool
Code::containsCodePC(const void* pc, const CodeSegment** segmentp) const
{
for (auto t : tiers()) {
const CodeSegment& cs = segment(t);
if (cs.containsCodePC(pc)) {
if (segmentp)
*segmentp = &cs;
return true;
}
}
return false;
}
struct CallSiteRetAddrOffset
{
const CallSiteVector& callSites;
@ -630,17 +735,16 @@ size_t
Code::serializedSize() const
{
return metadata().serializedSize() +
segmentTier().serializedSize();
segment(Tier::Ion).serializedSize();
}
uint8_t*
Code::serialize(uint8_t* cursor, const LinkData& linkData) const
{
MOZ_RELEASE_ASSERT(!metadata().debugEnabled);
MOZ_RELEASE_ASSERT(metadataTier().mode == CompileMode::Ion);
cursor = metadata().serialize(cursor);
cursor = segmentTier().serialize(cursor, linkData.tier());
cursor = segment(Tier::Ion).serialize(cursor, linkData.linkData(Tier::Ion));
return cursor;
}
@ -652,7 +756,7 @@ Code::deserialize(const uint8_t* cursor, const SharedBytes& bytecode, const Link
if (maybeMetadata) {
metadata = maybeMetadata;
} else {
auto tier = js::MakeUnique<MetadataTier>(CompileMode::Ion);
auto tier = js::MakeUnique<MetadataTier>(Tier::Ion);
if (!tier)
return nullptr;
@ -669,7 +773,7 @@ Code::deserialize(const uint8_t* cursor, const SharedBytes& bytecode, const Link
if (!codeSegment)
return nullptr;
cursor = codeSegment->deserialize(cursor, *bytecode, linkData.tier(), *metadata);
cursor = codeSegment->deserialize(cursor, *bytecode, linkData.linkData(Tier::Ion), *metadata);
if (!cursor)
return nullptr;
@ -680,24 +784,40 @@ Code::deserialize(const uint8_t* cursor, const SharedBytes& bytecode, const Link
}
const CallSite*
Code::lookupCallSite(void* returnAddress) const
Code::lookupCallSite(void* returnAddress, const CodeSegment** segmentp) const
{
uint32_t target = ((uint8_t*)returnAddress) - segmentTier().base();
size_t lowerBound = 0;
size_t upperBound = metadataTier().callSites.length();
for (auto t : tiers()) {
uint32_t target = ((uint8_t*)returnAddress) - segment(t).base();
size_t lowerBound = 0;
size_t upperBound = metadata(t).callSites.length();
size_t match;
if (!BinarySearch(CallSiteRetAddrOffset(metadataTier().callSites), lowerBound, upperBound, target, &match))
return nullptr;
size_t match;
if (BinarySearch(CallSiteRetAddrOffset(metadata(t).callSites), lowerBound, upperBound,
target, &match))
{
if (segmentp)
*segmentp = &segment(t);
return &metadata(t).callSites[match];
}
}
return &metadataTier().callSites[match];
return nullptr;
}
const CodeRange*
Code::lookupRange(void* pc) const
Code::lookupRange(void* pc, const CodeSegment** segmentp) const
{
CodeRange::OffsetInCode target((uint8_t*)pc - segmentTier().base());
return LookupInSorted(metadataTier().codeRanges, target);
for (auto t : tiers()) {
CodeRange::OffsetInCode target((uint8_t*)pc - segment(t).base());
const CodeRange* result = LookupInSorted(metadata(t).codeRanges, target);
if (result) {
if (segmentp)
*segmentp = &segment(t);
return result;
}
}
return nullptr;
}
struct MemoryAccessOffset
@ -710,19 +830,27 @@ struct MemoryAccessOffset
};
const MemoryAccess*
Code::lookupMemoryAccess(void* pc) const
Code::lookupMemoryAccess(void* pc, const CodeSegment** segmentp) const
{
MOZ_ASSERT(segmentTier().containsFunctionPC(pc));
for (auto t : tiers()) {
MOZ_ASSERT(segment(t).containsFunctionPC(pc));
uint32_t target = ((uint8_t*)pc) - segmentTier().base();
size_t lowerBound = 0;
size_t upperBound = metadataTier().memoryAccesses.length();
const MemoryAccessVector& memoryAccesses = metadata(t).memoryAccesses;
size_t match;
if (!BinarySearch(MemoryAccessOffset(metadataTier().memoryAccesses), lowerBound, upperBound, target, &match))
return nullptr;
uint32_t target = ((uint8_t*)pc) - segment(t).base();
size_t lowerBound = 0;
size_t upperBound = memoryAccesses.length();
return &metadataTier().memoryAccesses[match];
size_t match;
if (BinarySearch(MemoryAccessOffset(memoryAccesses), lowerBound, upperBound, target,
&match))
{
if (segmentp)
*segmentp = &segment(t);
return &memoryAccesses[match];
}
}
return nullptr;
}
// When enabled, generate profiling labels for every name in funcNames_ that is
@ -742,7 +870,10 @@ Code::ensureProfilingLabels(const Bytes* maybeBytecode, bool profilingEnabled) c
if (!labels->empty())
return;
for (const CodeRange& codeRange : metadataTier().codeRanges) {
// Any tier will do, we only need tier-invariant data that are incidentally
// stored with the code ranges.
for (const CodeRange& codeRange : metadata(anyTier()).codeRanges) {
if (!codeRange.isFunction())
continue;
@ -811,5 +942,6 @@ Code::addSizeOfMiscIfNotSeen(MallocSizeOf mallocSizeOf,
metadata().sizeOfIncludingThisIfNotSeen(mallocSizeOf, seenMetadata) +
profilingLabels_.lock()->sizeOfExcludingThis(mallocSizeOf);
segmentTier().addSizeOfMisc(mallocSizeOf, code, data);
for (auto t : tiers())
segment(t).addSizeOfMisc(mallocSizeOf, code, data);
}

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

@ -71,7 +71,7 @@ class CodeSegment
static UniqueCodeBytes AllocateCodeBytes(uint32_t codeLength);
// How this code was compiled.
CompileMode mode_;
Tier tier_;
// bytes_ points to a single allocation of executable machine code in
// the range [0, length_). The range [0, functionLength_) is
@ -86,14 +86,14 @@ class CodeSegment
uint8_t* outOfBoundsCode_;
uint8_t* unalignedAccessCode_;
bool initialize(CompileMode mode,
bool initialize(Tier tier,
UniqueCodeBytes bytes,
uint32_t codeLength,
const ShareableBytes& bytecode,
const LinkDataTier& linkData,
const Metadata& metadata);
static UniqueConstCodeSegment create(CompileMode mode,
static UniqueConstCodeSegment create(Tier tier,
UniqueCodeBytes bytes,
uint32_t codeLength,
const ShareableBytes& bytecode,
@ -104,7 +104,7 @@ class CodeSegment
void operator=(const CodeSegment&) = delete;
CodeSegment()
: mode_(CompileMode(-1)),
: tier_(Tier(-1)),
functionLength_(0),
length_(0),
interruptCode_(nullptr),
@ -112,19 +112,19 @@ class CodeSegment
unalignedAccessCode_(nullptr)
{}
static UniqueConstCodeSegment create(CompileMode mode,
static UniqueConstCodeSegment create(Tier tier,
jit::MacroAssembler& masm,
const ShareableBytes& bytecode,
const LinkDataTier& linkData,
const Metadata& metadata);
static UniqueConstCodeSegment create(CompileMode mode,
static UniqueConstCodeSegment create(Tier tier,
const Bytes& unlinkedBytes,
const ShareableBytes& bytecode,
const LinkDataTier& linkData,
const Metadata& metadata);
CompileMode mode() const { return mode_; }
Tier tier() const { return tier_; }
uint8_t* base() const { return bytes_.get(); }
uint32_t length() const { return length_; }
@ -349,9 +349,13 @@ typedef uint8_t ModuleHash[8];
struct MetadataTier
{
explicit MetadataTier(CompileMode mode) : mode(mode) {}
explicit MetadataTier(Tier tier)
: tier(tier)
{
MOZ_ASSERT(tier == Tier::Baseline || tier == Tier::Ion);
}
CompileMode mode;
const Tier tier;
MemoryAccessVector memoryAccesses;
CodeRangeVector codeRanges;
@ -363,6 +367,8 @@ struct MetadataTier
Uint32Vector debugTrapFarJumpOffsets;
Uint32Vector debugFuncToCodeRange;
const FuncExport& lookupFuncExport(uint32_t funcIndex) const;
WASM_DECLARE_SERIALIZABLE(MetadataTier);
};
@ -370,12 +376,12 @@ typedef UniquePtr<MetadataTier> UniqueMetadataTier;
struct Metadata : ShareableBase<Metadata>, MetadataCacheablePod
{
// Both `tier_` and the means of accessing it will become more complicated
// when tiering is implemented.
// `tier_` will become more complicated when tiering is implemented.
UniqueMetadataTier tier_;
const MetadataTier& tier() const { return *tier_; }
MetadataTier& tier() { return *tier_; }
Tiers tiers() const;
const MetadataTier& metadata(Tier t) const;
MetadataTier& metadata(Tier t);
explicit Metadata(UniqueMetadataTier tier, ModuleKind kind = ModuleKind::Wasm)
: MetadataCacheablePod(kind),
@ -402,8 +408,6 @@ struct Metadata : ShareableBase<Metadata>, MetadataCacheablePod
bool usesMemory() const { return UsesMemory(memoryUsage); }
bool hasSharedMemory() const { return memoryUsage == MemoryUsage::Shared; }
const FuncExport& lookupFuncExport(uint32_t funcIndex) const;
// AsmJSMetadata derives Metadata iff isAsmJS(). Mostly this distinction is
// encapsulated within AsmJS.cpp, but the additional virtual functions allow
// asm.js to override wasm behavior in the handful of cases that can't be
@ -440,9 +444,7 @@ typedef RefPtr<const Metadata> SharedMetadata;
class Code : public ShareableBase<Code>
{
// `tier_` and the means of accessing it will change as we implement
// tiering.
// `tier_` will become more complicated when tiering is implemented.
UniqueConstCodeSegment tier_;
SharedMetadata metadata_;
ExclusiveData<CacheableCharsVector> profilingLabels_;
@ -452,15 +454,23 @@ class Code : public ShareableBase<Code>
Code(UniqueConstCodeSegment tier, const Metadata& metadata);
const CodeSegment& segmentTier() const { return *tier_; }
const MetadataTier& metadataTier() const { return metadata_->tier(); }
Tier anyTier() const;
Tiers tiers() const;
const CodeSegment& segment(Tier tier) const;
const MetadataTier& metadata(Tier tier) const { return metadata_->metadata(tier); }
const Metadata& metadata() const { return *metadata_; }
// Frame iterator support:
const CallSite* lookupCallSite(void* returnAddress) const;
const CodeRange* lookupRange(void* pc) const;
const MemoryAccess* lookupMemoryAccess(void* pc) const;
const CallSite* lookupCallSite(void* returnAddress, const CodeSegment** segment = nullptr) const;
const CodeRange* lookupRange(void* pc, const CodeSegment** segment = nullptr) const;
const MemoryAccess* lookupMemoryAccess(void* pc, const CodeSegment** segment = nullptr) const;
// Signal handling support:
bool containsFunctionPC(const void* pc, const CodeSegment** segmentp = nullptr) const;
bool containsCodePC(const void* pc, const CodeSegment** segmentp = nullptr) const;
// To save memory, profilingLabels_ are generated lazily when profiling mode
// is enabled.

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

@ -27,6 +27,9 @@
using namespace js;
using namespace wasm;
// With tiering, instances can have one or two code segments, and code that
// searches the instance list will change. Search for Tier::TBD below.
Compartment::Compartment(Zone* zone)
: mutatingInstances_(false)
{}
@ -49,10 +52,10 @@ struct InstanceComparator
// Instances can share code, so the segments can be equal (though they
// can't partially overlap). If the codeBases are equal, we sort by
// Instance address. Thus a Code may map to many instances.
if (instance->codeBaseTier() == target.codeBaseTier())
if (instance->codeBase(Tier::TBD) == target.codeBase(Tier::TBD))
return instance < &target ? -1 : 1;
return target.codeBaseTier() < instance->codeBaseTier() ? -1 : 1;
return target.codeBase(Tier::TBD) < instance->codeBase(Tier::TBD) ? -1 : 1;
}
};
@ -103,14 +106,14 @@ struct PCComparator
explicit PCComparator(const void* pc) : pc(pc) {}
int operator()(const Instance* instance) const {
if (instance->codeSegmentTier().containsCodePC(pc))
if (instance->codeSegment(Tier::TBD).containsCodePC(pc))
return 0;
return pc < instance->codeBaseTier() ? -1 : 1;
return pc < instance->codeBase(Tier::TBD) ? -1 : 1;
}
};
const Code*
Compartment::lookupCode(const void* pc) const
Compartment::lookupCode(const void* pc, const CodeSegment** segmentp) const
{
// lookupCode() can be called asynchronously from the interrupt signal
// handler. In that case, the signal handler is just asking whether the pc
@ -123,7 +126,10 @@ Compartment::lookupCode(const void* pc) const
if (!BinarySearchIf(instances_, 0, instances_.length(), PCComparator(pc), &index))
return nullptr;
return &instances_[index]->code();
const Code& code = instances_[index]->code();
if (segmentp)
*segmentp = &code.segment(Tier::TBD);
return &code;
}
void

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

@ -28,6 +28,7 @@ class WasmActivation;
namespace wasm {
class Code;
class CodeSegment;
typedef Vector<Instance*, 0, SystemAllocPolicy> InstanceVector;
// wasm::Compartment lives in JSCompartment and contains the wasm-related
@ -75,9 +76,10 @@ class Compartment
const InstanceVector& instances() const { return instances_; }
// This methods returns the wasm::Code containing the given pc, if any
// exists in the compartment.
// exists in the compartment, and the segment for the tier in which the
// pc was found.
const Code* lookupCode(const void* pc) const;
const Code* lookupCode(const void* pc, const CodeSegment** segment = nullptr) const;
// Ensure all Instances in this JSCompartment have profiling labels created.

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

@ -189,7 +189,7 @@ DebugState::getLineOffsets(JSContext* cx, size_t lineno, Vector<uint32_t>* offse
return true;
if (binarySource_) {
const CallSite* callsite = SlowCallSiteSearchByOffset(metadataTier(), lineno);
const CallSite* callsite = SlowCallSiteSearchByOffset(metadata(Tier::Debug), lineno);
if (callsite && !offsets->append(lineno))
return false;
return true;
@ -228,7 +228,7 @@ DebugState::getAllColumnOffsets(JSContext* cx, Vector<ExprLoc>* offsets)
return true;
if (binarySource_) {
for (const CallSite& callSite : metadataTier().callSites) {
for (const CallSite& callSite : metadata(Tier::Debug).callSites) {
if (callSite.kind() != CallSite::Breakpoint)
continue;
uint32_t offset = callSite.lineOrBytecode();
@ -255,7 +255,7 @@ DebugState::getOffsetLocation(JSContext* cx, uint32_t offset, bool* found, size_
return true;
if (binarySource_) {
if (!SlowCallSiteSearchByOffset(metadataTier(), offset))
if (!SlowCallSiteSearchByOffset(metadata(Tier::Debug), offset))
return true; // offset was not found
*found = true;
*lineno = offset;
@ -311,7 +311,7 @@ bool
DebugState::incrementStepModeCount(JSContext* cx, uint32_t funcIndex)
{
MOZ_ASSERT(debugEnabled());
const CodeRange& codeRange = codeRanges()[debugFuncToCodeRange(funcIndex)];
const CodeRange& codeRange = codeRanges(Tier::Debug)[debugFuncToCodeRangeIndex(funcIndex)];
MOZ_ASSERT(codeRange.isFunction());
if (!stepModeCounters_.initialized() && !stepModeCounters_.init()) {
@ -330,11 +330,11 @@ DebugState::incrementStepModeCount(JSContext* cx, uint32_t funcIndex)
return false;
}
AutoWritableJitCode awjc(cx->runtime(), code_->segmentTier().base() + codeRange.begin(),
AutoWritableJitCode awjc(cx->runtime(), code_->segment(Tier::Debug).base() + codeRange.begin(),
codeRange.end() - codeRange.begin());
AutoFlushICache afc("Code::incrementStepModeCount");
for (const CallSite& callSite : callSites()) {
for (const CallSite& callSite : callSites(Tier::Debug)) {
if (callSite.kind() != CallSite::Breakpoint)
continue;
uint32_t offset = callSite.returnAddressOffset();
@ -345,10 +345,10 @@ DebugState::incrementStepModeCount(JSContext* cx, uint32_t funcIndex)
}
bool
DebugState::decrementStepModeCount(JSContext* cx, uint32_t funcIndex)
DebugState::decrementStepModeCount(FreeOp* fop, uint32_t funcIndex)
{
MOZ_ASSERT(debugEnabled());
const CodeRange& codeRange = codeRanges()[debugFuncToCodeRange(funcIndex)];
const CodeRange& codeRange = codeRanges(Tier::Debug)[debugFuncToCodeRangeIndex(funcIndex)];
MOZ_ASSERT(codeRange.isFunction());
MOZ_ASSERT(stepModeCounters_.initialized() && !stepModeCounters_.empty());
@ -359,11 +359,11 @@ DebugState::decrementStepModeCount(JSContext* cx, uint32_t funcIndex)
stepModeCounters_.remove(p);
AutoWritableJitCode awjc(cx->runtime(), code_->segmentTier().base() + codeRange.begin(),
AutoWritableJitCode awjc(fop->runtime(), code_->segment(Tier::Debug).base() + codeRange.begin(),
codeRange.end() - codeRange.begin());
AutoFlushICache afc("Code::decrementStepModeCount");
for (const CallSite& callSite : callSites()) {
for (const CallSite& callSite : callSites(Tier::Debug)) {
if (callSite.kind() != CallSite::Breakpoint)
continue;
uint32_t offset = callSite.returnAddressOffset();
@ -380,27 +380,28 @@ DebugState::hasBreakpointTrapAtOffset(uint32_t offset)
{
if (!debugEnabled())
return false;
return SlowCallSiteSearchByOffset(metadataTier(), offset);
return SlowCallSiteSearchByOffset(metadata(Tier::Debug), offset);
}
void
DebugState::toggleBreakpointTrap(JSRuntime* rt, uint32_t offset, bool enabled)
{
MOZ_ASSERT(debugEnabled());
const CallSite* callSite = SlowCallSiteSearchByOffset(metadataTier(), offset);
const CallSite* callSite = SlowCallSiteSearchByOffset(metadata(Tier::Debug), offset);
if (!callSite)
return;
size_t debugTrapOffset = callSite->returnAddressOffset();
const CodeRange* codeRange = code_->lookupRange(code_->segmentTier().base() + debugTrapOffset);
const CodeSegment& codeSegment = code_->segment(Tier::Debug);
const CodeRange* codeRange = code_->lookupRange(codeSegment.base() + debugTrapOffset);
MOZ_ASSERT(codeRange && codeRange->isFunction());
if (stepModeCounters_.initialized() && stepModeCounters_.lookup(codeRange->funcIndex()))
return; // no need to toggle when step mode is enabled
AutoWritableJitCode awjc(rt, code_->segmentTier().base(), code_->segmentTier().length());
AutoWritableJitCode awjc(rt, codeSegment.base(), codeSegment.length());
AutoFlushICache afc("Code::toggleBreakpointTrap");
AutoFlushICache::setRange(uintptr_t(code_->segmentTier().base()), code_->segmentTier().length());
AutoFlushICache::setRange(uintptr_t(codeSegment.base()), codeSegment.length());
toggleDebugTrap(debugTrapOffset, enabled);
}
@ -478,8 +479,8 @@ void
DebugState::toggleDebugTrap(uint32_t offset, bool enabled)
{
MOZ_ASSERT(offset);
uint8_t* trap = code_->segmentTier().base() + offset;
const Uint32Vector& farJumpOffsets = metadataTier().debugTrapFarJumpOffsets;
uint8_t* trap = code_->segment(Tier::Debug).base() + offset;
const Uint32Vector& farJumpOffsets = metadata(Tier::Debug).debugTrapFarJumpOffsets;
if (enabled) {
MOZ_ASSERT(farJumpOffsets.length() > 0);
size_t i = 0;
@ -488,7 +489,7 @@ DebugState::toggleDebugTrap(uint32_t offset, bool enabled)
if (i >= farJumpOffsets.length() ||
(i > 0 && offset - farJumpOffsets[i - 1] < farJumpOffsets[i] - offset))
i--;
uint8_t* farJump = code_->segmentTier().base() + farJumpOffsets[i];
uint8_t* farJump = code_->segment(Tier::Debug).base() + farJumpOffsets[i];
MacroAssembler::patchNopToCall(trap, farJump);
} else {
MacroAssembler::patchCallToNop(trap);
@ -510,10 +511,11 @@ DebugState::adjustEnterAndLeaveFrameTrapsState(JSContext* cx, bool enabled)
if (wasEnabled == stillEnabled)
return;
AutoWritableJitCode awjc(cx->runtime(), code_->segmentTier().base(), code_->segmentTier().length());
const CodeSegment& codeSegment = code_->segment(Tier::Debug);
AutoWritableJitCode awjc(cx->runtime(), codeSegment.base(), codeSegment.length());
AutoFlushICache afc("Code::adjustEnterAndLeaveFrameTrapsState");
AutoFlushICache::setRange(uintptr_t(code_->segmentTier().base()), code_->segmentTier().length());
for (const CallSite& callSite : callSites()) {
AutoFlushICache::setRange(uintptr_t(codeSegment.base()), codeSegment.length());
for (const CallSite& callSite : callSites(Tier::Debug)) {
if (callSite.kind() != CallSite::EnterFrame && callSite.kind() != CallSite::LeaveFrame)
continue;
toggleDebugTrap(callSite.returnAddressOffset(), stillEnabled);
@ -531,7 +533,7 @@ DebugState::debugGetLocalTypes(uint32_t funcIndex, ValTypeVector* locals, size_t
return false;
// Decode local var types from wasm binary function body.
const CodeRange& range = codeRanges()[debugFuncToCodeRange(funcIndex)];
const CodeRange& range = codeRanges(Tier::Debug)[debugFuncToCodeRangeIndex(funcIndex)];
// In wasm, the Code points to the function start via funcLineOrBytecode.
MOZ_ASSERT(!metadata().isAsmJS() && maybeBytecode_);
size_t offsetInModule = range.funcLineOrBytecode();

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

@ -137,7 +137,7 @@ class DebugState
bool stepModeEnabled(uint32_t funcIndex) const;
bool incrementStepModeCount(JSContext* cx, uint32_t funcIndex);
bool decrementStepModeCount(JSContext* cx, uint32_t funcIndex);
bool decrementStepModeCount(FreeOp* fop, uint32_t funcIndex);
// Stack inspection helpers.
@ -151,14 +151,14 @@ class DebugState
// Accessors for commonly used elements of linked structures.
const MetadataTier& metadataTier() const { return code_->metadataTier(); }
const MetadataTier& metadata(Tier t) const { return code_->metadata(t); }
const Metadata& metadata() const { return code_->metadata(); }
bool debugEnabled() const { return metadata().debugEnabled; }
const CodeRangeVector& codeRanges() const { return metadataTier().codeRanges; }
const CallSiteVector& callSites() const { return metadataTier().callSites; }
const CodeRangeVector& codeRanges(Tier t) const { return metadata(t).codeRanges; }
const CallSiteVector& callSites(Tier t) const { return metadata(t).callSites; }
uint32_t debugFuncToCodeRange(uint32_t funcIndex) const {
return metadataTier().debugFuncToCodeRange[funcIndex];
uint32_t debugFuncToCodeRangeIndex(uint32_t funcIndex) const {
return metadata(Tier::Debug).debugFuncToCodeRange[funcIndex];
}
// about:memory reporting:

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

@ -213,8 +213,12 @@ FrameIterator::debugEnabled() const
MOZ_ASSERT(!done());
// Only non-imported functions can have debug frames.
//
// Metadata::debugEnabled is only set if debugging is actually enabled (both
// requested, and available via baseline compilation), and Tier::Debug code
// will be available.
return code_->metadata().debugEnabled &&
codeRange_->funcIndex() >= code_->metadataTier().funcImports.length();
codeRange_->funcIndex() >= code_->metadata(Tier::Debug).funcImports.length();
}
DebugFrame*
@ -305,7 +309,8 @@ LoadActivation(MacroAssembler& masm, Register dest)
{
// WasmCall pushes a WasmActivation and an inactive JitActivation. The
// JitActivation only becomes active when calling into JS from wasm.
masm.loadPtr(Address(WasmTlsReg, offsetof(wasm::TlsData, cx)), dest);
masm.loadPtr(Address(WasmTlsReg, offsetof(wasm::TlsData, addressOfContext)), dest);
masm.loadPtr(Address(dest, 0), dest);
masm.loadPtr(Address(dest, JSContext::offsetOfActivation()), dest);
masm.loadPtr(Address(dest, Activation::offsetOfPrev()), dest);
}
@ -607,8 +612,9 @@ ProfilingFrameIterator::ProfilingFrameIterator(const WasmActivation& activation,
uint8_t* codeBase;
code_ = activation_->compartment()->wasm.lookupCode(pc);
if (code_) {
codeRange = code_->lookupRange(pc);
codeBase = code_->segmentTier().base();
const CodeSegment* codeSegment;
codeRange = code_->lookupRange(pc, &codeSegment);
codeBase = codeSegment->base();
} else if (!LookupBuiltinThunk(pc, &codeRange, &codeBase)) {
MOZ_ASSERT(done());
return;
@ -956,11 +962,12 @@ wasm::LookupFaultingInstance(WasmActivation* activation, void* pc, void* fp)
if (!code)
return nullptr;
const CodeRange* codeRange = code->lookupRange(pc);
const CodeSegment* codeSegment;
const CodeRange* codeRange = code->lookupRange(pc, &codeSegment);
if (!codeRange || !codeRange->isFunction())
return nullptr;
size_t offsetInModule = ((uint8_t*)pc) - code->segmentTier().base();
size_t offsetInModule = ((uint8_t*)pc) - codeSegment->base();
if (offsetInModule < codeRange->funcNormalEntry() + SetFP)
return nullptr;
if (offsetInModule >= codeRange->ret() - PoppedFP)

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

@ -46,7 +46,7 @@ static const unsigned COMPILATION_LIFO_DEFAULT_CHUNK_SIZE = 64 * 1024;
static const uint32_t BAD_CODE_RANGE = UINT32_MAX;
ModuleGenerator::ModuleGenerator(UniqueChars* error)
: compileMode_(CompileMode(-1)),
: tier_(Tier(-1)),
error_(error),
linkDataTier_(nullptr),
metadataTier_(nullptr),
@ -111,11 +111,11 @@ ModuleGenerator::initAsmJS(Metadata* asmJSMetadata)
{
MOZ_ASSERT(env_->isAsmJS());
if (!linkData_.initTier(CompileMode::Ion))
if (!linkData_.initTier(Tier::Ion))
return false;
linkDataTier_ = &linkData_.tier();
linkDataTier_ = &linkData_.linkData(Tier::Ion);
metadataTier_ = &asmJSMetadata->tier();
metadataTier_ = &asmJSMetadata->metadata(Tier::Ion);
metadata_ = asmJSMetadata;
MOZ_ASSERT(isAsmJS());
@ -123,7 +123,7 @@ ModuleGenerator::initAsmJS(Metadata* asmJSMetadata)
// wasm (since the baseline does not currently support Atomics or SIMD).
metadata_->debugEnabled = false;
compileMode_ = CompileMode::Ion;
tier_ = Tier::Ion;
// For asm.js, the Vectors in ModuleEnvironment are max-sized reservations
// and will be initialized in a linear order via init* functions as the
@ -143,15 +143,15 @@ ModuleGenerator::initWasm(const CompileArgs& args)
bool canBaseline = BaselineCanCompile();
bool debugEnabled = args.debugEnabled && canBaseline;
compileMode_ = ((args.alwaysBaseline || debugEnabled) && canBaseline)
? CompileMode::Baseline
: CompileMode::Ion;
tier_ = ((args.alwaysBaseline || debugEnabled) && canBaseline)
? Tier::Baseline
: Tier::Ion;
if (!linkData_.initTier(compileMode_))
if (!linkData_.initTier(tier_))
return false;
linkDataTier_ = &linkData_.tier();
linkDataTier_ = &linkData_.linkData(tier_);
auto metadataTier = js::MakeUnique<MetadataTier>(compileMode_);
auto metadataTier = js::MakeUnique<MetadataTier>(tier_);
if (!metadataTier)
return false;
@ -159,7 +159,7 @@ ModuleGenerator::initWasm(const CompileArgs& args)
if (!metadata_)
return false;
metadataTier_ = &metadata_->tier();
metadataTier_ = &metadata_->metadata(tier_);
MOZ_ASSERT(!isAsmJS());
@ -907,7 +907,7 @@ ModuleGenerator::startFuncDefs()
if (!tasks_.initCapacity(numTasks))
return false;
for (size_t i = 0; i < numTasks; i++)
tasks_.infallibleEmplaceBack(*env_, compileMode_, COMPILATION_LIFO_DEFAULT_CHUNK_SIZE);
tasks_.infallibleEmplaceBack(*env_, tier_, COMPILATION_LIFO_DEFAULT_CHUNK_SIZE);
if (!freeTasks_.reserve(numTasks))
return false;
@ -987,9 +987,10 @@ ModuleGenerator::finishFuncDef(uint32_t funcIndex, FunctionGenerator* fg)
return false;
uint32_t threshold;
switch (compileMode_) {
case CompileMode::Baseline: threshold = JitOptions.wasmBatchBaselineThreshold; break;
case CompileMode::Ion: threshold = JitOptions.wasmBatchIonThreshold; break;
switch (tier_) {
case Tier::Baseline: threshold = JitOptions.wasmBatchBaselineThreshold; break;
case Tier::Ion: threshold = JitOptions.wasmBatchIonThreshold; break;
default: MOZ_CRASH("Invalid tier value"); break;
}
batchedBytecode_ += funcBytecodeLength;
@ -1200,7 +1201,7 @@ ModuleGenerator::finish(const ShareableBytes& bytecode)
generateBytecodeHash(bytecode);
UniqueConstCodeSegment codeSegment = CodeSegment::create(compileMode_,
UniqueConstCodeSegment codeSegment = CodeSegment::create(tier_,
masm_,
bytecode,
*linkDataTier_,
@ -1240,19 +1241,21 @@ wasm::CompileFunction(CompileTask* task, UniqueChars* error)
TraceLoggerThread* logger = TraceLoggerForCurrentThread();
AutoTraceLog logCompile(logger, TraceLogger_WasmCompilation);
switch (task->mode()) {
case CompileMode::Ion:
switch (task->tier()) {
case Tier::Ion:
for (FuncCompileUnit& unit : task->units()) {
if (!IonCompileFunction(task, &unit, error))
return false;
}
break;
case CompileMode::Baseline:
case Tier::Baseline:
for (FuncCompileUnit& unit : task->units()) {
if (!BaselineCompileFunction(task, &unit, error))
return false;
}
break;
default:
MOZ_CRASH("Invalid tier value");
}
return true;

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

@ -131,7 +131,7 @@ typedef Vector<FuncCompileUnit, 8, SystemAllocPolicy> FuncCompileUnitVector;
class CompileTask
{
const ModuleEnvironment& env_;
CompileMode mode_;
Tier tier_;
LifoAlloc lifo_;
Maybe<jit::TempAllocator> alloc_;
Maybe<jit::MacroAssembler> masm_;
@ -148,11 +148,12 @@ class CompileTask
}
public:
CompileTask(const ModuleEnvironment& env, CompileMode mode, size_t defaultChunkSize)
CompileTask(const ModuleEnvironment& env, Tier tier, size_t defaultChunkSize)
: env_(env),
mode_(mode),
tier_(tier),
lifo_(defaultChunkSize)
{
MOZ_ASSERT(tier == Tier::Baseline || tier == Tier::Ion);
init();
}
LifoAlloc& lifo() {
@ -170,8 +171,8 @@ class CompileTask
FuncCompileUnitVector& units() {
return units_;
}
CompileMode mode() const {
return mode_;
Tier tier() const {
return tier_;
}
bool debugEnabled() const {
return debugEnabled_;
@ -209,7 +210,7 @@ class MOZ_STACK_CLASS ModuleGenerator
typedef EnumeratedArray<Trap, Trap::Limit, CallableOffsets> TrapExitOffsetArray;
// Constant parameters
CompileMode compileMode_;
Tier tier_;
UniqueChars* error_;
// Data that is moved into the result of finish()

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

@ -127,7 +127,9 @@ bool
Instance::callImport(JSContext* cx, uint32_t funcImportIndex, unsigned argc, const uint64_t* argv,
MutableHandleValue rval)
{
const FuncImport& fi = metadataTier().funcImports[funcImportIndex];
Tier tier = Tier::TBD;
const FuncImport& fi = metadata(tier).funcImports[funcImportIndex];
InvokeArgs args(cx);
if (!args.init(cx, argc))
@ -189,7 +191,7 @@ Instance::callImport(JSContext* cx, uint32_t funcImportIndex, unsigned argc, con
return true;
// The import may already have become optimized.
void* jitExitCode = codeBaseTier() + fi.jitExitCodeOffset();
void* jitExitCode = codeBase(tier) + fi.jitExitCodeOffset();
if (import.code == jitExitCode)
return true;
@ -254,7 +256,7 @@ Instance::callImport(JSContext* cx, uint32_t funcImportIndex, unsigned argc, con
/* static */ int32_t
Instance::callImport_void(Instance* instance, int32_t funcImportIndex, int32_t argc, uint64_t* argv)
{
JSContext* cx = instance->cx();
JSContext* cx = TlsContext.get();
RootedValue rval(cx);
return instance->callImport(cx, funcImportIndex, argc, argv, &rval);
}
@ -262,7 +264,7 @@ Instance::callImport_void(Instance* instance, int32_t funcImportIndex, int32_t a
/* static */ int32_t
Instance::callImport_i32(Instance* instance, int32_t funcImportIndex, int32_t argc, uint64_t* argv)
{
JSContext* cx = instance->cx();
JSContext* cx = TlsContext.get();
RootedValue rval(cx);
if (!instance->callImport(cx, funcImportIndex, argc, argv, &rval))
return false;
@ -273,7 +275,7 @@ Instance::callImport_i32(Instance* instance, int32_t funcImportIndex, int32_t ar
/* static */ int32_t
Instance::callImport_i64(Instance* instance, int32_t funcImportIndex, int32_t argc, uint64_t* argv)
{
JSContext* cx = instance->cx();
JSContext* cx = TlsContext.get();
RootedValue rval(cx);
if (!instance->callImport(cx, funcImportIndex, argc, argv, &rval))
return false;
@ -284,7 +286,7 @@ Instance::callImport_i64(Instance* instance, int32_t funcImportIndex, int32_t ar
/* static */ int32_t
Instance::callImport_f64(Instance* instance, int32_t funcImportIndex, int32_t argc, uint64_t* argv)
{
JSContext* cx = instance->cx();
JSContext* cx = TlsContext.get();
RootedValue rval(cx);
if (!instance->callImport(cx, funcImportIndex, argc, argv, &rval))
return false;
@ -297,7 +299,7 @@ Instance::growMemory_i32(Instance* instance, uint32_t delta)
{
MOZ_ASSERT(!instance->isAsmJS());
JSContext* cx = instance->cx();
JSContext* cx = TlsContext.get();
RootedWasmMemoryObject memory(cx, instance->memory_);
uint32_t ret = WasmMemoryObject::grow(memory, delta, cx);
@ -335,28 +337,33 @@ Instance::Instance(JSContext* cx,
tables_(Move(tables)),
enterFrameTrapsEnabled_(false)
{
MOZ_ASSERT(funcImports.length() == metadataTier().funcImports.length());
#ifdef DEBUG
for (auto t : metadata().tiers())
MOZ_ASSERT(funcImports.length() == metadata(t).funcImports.length());
#endif
MOZ_ASSERT(tables_.length() == metadata().tables.length());
tlsData()->cx = cx;
tlsData()->instance = this;
tlsData()->globalData = globals_->globalData();
tlsData()->memoryBase = memory ? memory->buffer().dataPointerEither().unwrap() : nullptr;
#ifndef WASM_HUGE_MEMORY
tlsData()->boundsCheckLimit = memory ? memory->buffer().wasmBoundsCheckLimit() : 0;
#endif
tlsData()->stackLimit = *(void**)cx->stackLimitAddressForJitCode(JS::StackForUntrustedScript);
tlsData()->globalData = globals_->globalData();
tlsData()->instance = this;
tlsData()->addressOfContext = (JSContext**)object->zone()->group()->addressOfOwnerContext();
for (size_t i = 0; i < metadataTier().funcImports.length(); i++) {
Tier callerTier = Tier::TBD;
Tier calleeTier = Tier::TBD;
for (size_t i = 0; i < metadata(callerTier).funcImports.length(); i++) {
HandleFunction f = funcImports[i];
const FuncImport& fi = metadataTier().funcImports[i];
const FuncImport& fi = metadata(callerTier).funcImports[i];
FuncImportTls& import = funcImportTls(fi);
if (!isAsmJS() && IsExportedWasmFunction(f)) {
WasmInstanceObject* calleeInstanceObj = ExportedFunctionToInstanceObject(f);
const CodeRange& codeRange = calleeInstanceObj->getExportedFunctionCodeRange(f);
const CodeRange& codeRange = calleeInstanceObj->getExportedFunctionCodeRange(f, calleeTier);
Instance& calleeInstance = calleeInstanceObj->instance();
import.tls = calleeInstance.tlsData();
import.code = calleeInstance.codeBaseTier() + codeRange.funcNormalEntry();
import.code = calleeInstance.codeBase(calleeTier) + codeRange.funcNormalEntry();
import.baselineScript = nullptr;
import.obj = calleeInstanceObj;
} else if (void* thunk = MaybeGetBuiltinThunk(f, fi.sig(), cx)) {
@ -366,7 +373,7 @@ Instance::Instance(JSContext* cx,
import.obj = f;
} else {
import.tls = tlsData();
import.code = codeBaseTier() + fi.interpExitCodeOffset();
import.code = codeBase(callerTier) + fi.interpExitCodeOffset();
import.baselineScript = nullptr;
import.obj = f;
}
@ -447,8 +454,10 @@ Instance::~Instance()
{
compartment_->wasm.unregisterInstance(*this);
for (unsigned i = 0; i < metadataTier().funcImports.length(); i++) {
FuncImportTls& import = funcImportTls(metadataTier().funcImports[i]);
const FuncImportVector& funcImports = metadata(code().anyTier()).funcImports;
for (unsigned i = 0; i < funcImports.length(); i++) {
FuncImportTls& import = funcImportTls(funcImports[i]);
if (import.baselineScript)
import.baselineScript->removeDependentWasmImport(*this, i);
}
@ -495,7 +504,7 @@ Instance::tracePrivate(JSTracer* trc)
MOZ_ASSERT(!gc::IsAboutToBeFinalized(&object_));
TraceEdge(trc, &object_, "wasm instance object");
for (const FuncImport& fi : metadataTier().funcImports)
for (const FuncImport& fi : metadata(code().anyTier()).funcImports)
TraceNullableEdge(trc, &funcImportTls(fi).obj, "wasm import");
for (const SharedTable& table : tables_)
@ -547,7 +556,9 @@ Instance::callExport(JSContext* cx, uint32_t funcIndex, CallArgs args)
// If there has been a moving grow, this Instance should have been notified.
MOZ_RELEASE_ASSERT(!memory_ || tlsData()->memoryBase == memory_->buffer().dataPointerEither());
const FuncExport& func = metadata().lookupFuncExport(funcIndex);
Tier tier = Tier::TBD;
const FuncExport& func = metadata(tier).lookupFuncExport(funcIndex);
// The calling convention for an external call into wasm is to pass an
// array of 16-byte values where each value contains either a coerced int32
@ -660,7 +671,7 @@ Instance::callExport(JSContext* cx, uint32_t funcIndex, CallArgs args)
JitActivation jitActivation(cx, /* active */ false);
// Call the per-exported-function trampoline created by GenerateEntry.
auto funcPtr = JS_DATA_TO_FUNC_PTR(ExportFuncPtr, codeBaseTier() + func.entryOffset());
auto funcPtr = JS_DATA_TO_FUNC_PTR(ExportFuncPtr, codeBase(tier) + func.entryOffset());
if (!CALL_GENERATED_2(funcPtr, exportArgs.begin(), tlsData()))
return false;
}
@ -804,9 +815,9 @@ Instance::onMovingGrowTable()
void
Instance::deoptimizeImportExit(uint32_t funcImportIndex)
{
const FuncImport& fi = metadataTier().funcImports[funcImportIndex];
const FuncImport& fi = metadata(code().anyTier()).funcImports[funcImportIndex];
FuncImportTls& import = funcImportTls(fi);
import.code = codeBaseTier() + fi.interpExitCodeOffset();
import.code = codeBase(Tier::TBD) + fi.interpExitCodeOffset();
import.baselineScript = nullptr;
}

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

@ -104,15 +104,14 @@ class Instance
bool init(JSContext* cx);
void trace(JSTracer* trc);
JSContext* cx() const { return tlsData()->cx; }
JSCompartment* compartment() const { return compartment_; }
const Code& code() const { return *code_; }
DebugState& debug() { return *debug_; }
const DebugState& debug() const { return *debug_; }
const CodeSegment& codeSegmentTier() const { return code_->segmentTier(); }
const CodeSegment& codeSegment(Tier t) const { return code_->segment(t); }
const GlobalSegment& globalSegment() const { return *globals_; }
uint8_t* codeBaseTier() const { return code_->segmentTier().base(); }
const MetadataTier& metadataTier() const { return code_->metadataTier(); }
uint8_t* codeBase(Tier t) const { return code_->segment(t).base(); }
const MetadataTier& metadata(Tier t) const { return code_->metadata(t); }
const Metadata& metadata() const { return code_->metadata(); }
bool isAsmJS() const { return metadata().isAsmJS(); }
const SharedTableVector& tables() const { return tables_; }

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

@ -3787,7 +3787,7 @@ EmitBodyExprs(FunctionCompiler& f)
bool
wasm::IonCompileFunction(CompileTask* task, FuncCompileUnit* unit, UniqueChars* error)
{
MOZ_ASSERT(task->mode() == CompileMode::Ion);
MOZ_ASSERT(task->tier() == Tier::Ion);
const FuncBytes& func = unit->func();
const ModuleEnvironment& env = task->env();

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

@ -653,6 +653,8 @@ WasmModuleObject::imports(JSContext* cx, unsigned argc, Value* vp)
if (!elems.reserve(module->imports().length()))
return false;
const FuncImportVector& funcImports = module->metadata(module->code().anyTier()).funcImports;
size_t numFuncImport = 0;
for (const Import& import : module->imports()) {
Rooted<IdValueVector> props(cx, IdValueVector(cx));
@ -675,7 +677,7 @@ WasmModuleObject::imports(JSContext* cx, unsigned argc, Value* vp)
props.infallibleAppend(IdValuePair(NameToId(names.kind), StringValue(kindStr)));
if (JitOptions.wasmTestMode && import.kind == DefinitionKind::Function) {
JSString* sigStr = SigToString(cx, module->metadataTier().funcImports[numFuncImport++].sig());
JSString* sigStr = SigToString(cx, funcImports[numFuncImport++].sig());
if (!sigStr)
return false;
if (!props.append(IdValuePair(NameToId(names.signature), StringValue(sigStr))))
@ -714,6 +716,8 @@ WasmModuleObject::exports(JSContext* cx, unsigned argc, Value* vp)
if (!elems.reserve(module->exports().length()))
return false;
const FuncExportVector& funcExports = module->metadata(module->code().anyTier()).funcExports;
size_t numFuncExport = 0;
for (const Export& exp : module->exports()) {
Rooted<IdValueVector> props(cx, IdValueVector(cx));
@ -731,7 +735,7 @@ WasmModuleObject::exports(JSContext* cx, unsigned argc, Value* vp)
props.infallibleAppend(IdValuePair(NameToId(names.kind), StringValue(kindStr)));
if (JitOptions.wasmTestMode && exp.kind() == DefinitionKind::Function) {
JSString* sigStr = SigToString(cx, module->metadataTier().funcExports[numFuncExport++].sig());
JSString* sigStr = SigToString(cx, funcExports[numFuncExport++].sig());
if (!sigStr)
return false;
if (!props.append(IdValuePair(NameToId(names.signature), StringValue(sigStr))))
@ -815,7 +819,9 @@ WasmModuleObject::create(JSContext* cx, Module& module, HandleObject proto)
obj->initReservedSlot(MODULE_SLOT, PrivateValue(&module));
module.AddRef();
cx->zone()->updateJitCodeMallocBytes(module.codeLengthTier());
// We account for the first tier here; the second tier, if different, will be
// accounted for separately when it's been compiled.
cx->zone()->updateJitCodeMallocBytes(module.codeLength(module.code().anyTier()));
return obj;
}
@ -941,8 +947,31 @@ const Class WasmInstanceObject::class_ =
&WasmInstanceObject::classOps_,
};
static bool
IsInstance(HandleValue v)
{
return v.isObject() && v.toObject().is<WasmInstanceObject>();
}
/* static */ bool
WasmInstanceObject::exportsGetterImpl(JSContext* cx, const CallArgs& args)
{
args.rval().setObject(args.thisv().toObject().as<WasmInstanceObject>().exportsObj());
return true;
}
/* static */ bool
WasmInstanceObject::exportsGetter(JSContext* cx, unsigned argc, Value* vp)
{
CallArgs args = CallArgsFromVp(argc, vp);
return CallNonGenericMethod<IsInstance, exportsGetterImpl>(cx, args);
}
const JSPropertySpec WasmInstanceObject::properties[] =
{ JS_PS_END };
{
JS_PSG("exports", WasmInstanceObject::exportsGetter, 0),
JS_PS_END
};
const JSFunctionSpec WasmInstanceObject::methods[] =
{ JS_FS_END };
@ -1031,6 +1060,13 @@ WasmInstanceObject::create(JSContext* cx,
return obj;
}
void
WasmInstanceObject::initExportsObj(JSObject& exportsObj)
{
MOZ_ASSERT(getReservedSlot(EXPORTS_OBJ_SLOT).isUndefined());
setReservedSlot(EXPORTS_OBJ_SLOT, ObjectValue(exportsObj));
}
static bool
GetImportArg(JSContext* cx, CallArgs callArgs, MutableHandleObject importObj)
{
@ -1094,6 +1130,12 @@ WasmInstanceObject::instance() const
return *(Instance*)getReservedSlot(INSTANCE_SLOT).toPrivate();
}
JSObject&
WasmInstanceObject::exportsObj() const
{
return getReservedSlot(EXPORTS_OBJ_SLOT).toObject();
}
WasmInstanceObject::ExportMap&
WasmInstanceObject::exports() const
{
@ -1127,7 +1169,7 @@ WasmInstanceObject::getExportedFunction(JSContext* cx, HandleWasmInstanceObject
}
const Instance& instance = instanceObj->instance();
unsigned numArgs = instance.metadata().lookupFuncExport(funcIndex).sig().args().length();
unsigned numArgs = instance.metadata(instance.code().anyTier()).lookupFuncExport(funcIndex).sig().args().length();
// asm.js needs to act like a normal JS function which means having the name
// from the original source and being callable as a constructor.
@ -1162,12 +1204,12 @@ WasmInstanceObject::getExportedFunction(JSContext* cx, HandleWasmInstanceObject
}
const CodeRange&
WasmInstanceObject::getExportedFunctionCodeRange(HandleFunction fun)
WasmInstanceObject::getExportedFunctionCodeRange(HandleFunction fun, Tier tier)
{
uint32_t funcIndex = ExportedFunctionToFuncIndex(fun);
MOZ_ASSERT(exports().lookup(funcIndex)->value() == fun);
const FuncExport& funcExport = instance().metadata().lookupFuncExport(funcIndex);
return instance().metadataTier().codeRanges[funcExport.codeRangeIndex()];
const FuncExport& funcExport = instance().metadata(tier).lookupFuncExport(funcIndex);
return instance().metadata(tier).codeRanges[funcExport.codeRangeIndex()];
}
/* static */ WasmFunctionScope*
@ -1707,6 +1749,7 @@ WasmTableObject::setImpl(JSContext* cx, const CallArgs& args)
if (value) {
RootedWasmInstanceObject instanceObj(cx, ExportedFunctionToInstanceObject(value));
uint32_t funcIndex = ExportedFunctionToFuncIndex(value);
Tier tier = Tier::TBD; // Perhaps the tier that the function is at?
#ifdef DEBUG
RootedFunction f(cx);
@ -1715,9 +1758,9 @@ WasmTableObject::setImpl(JSContext* cx, const CallArgs& args)
#endif
Instance& instance = instanceObj->instance();
const FuncExport& funcExport = instance.metadata().lookupFuncExport(funcIndex);
const CodeRange& codeRange = instance.metadataTier().codeRanges[funcExport.codeRangeIndex()];
void* code = instance.codeBaseTier() + codeRange.funcTableEntry();
const FuncExport& funcExport = instance.metadata(tier).lookupFuncExport(funcIndex);
const CodeRange& codeRange = instance.metadata(tier).codeRanges[funcExport.codeRangeIndex()];
void* code = instance.codeBase(tier) + codeRange.funcTableEntry();
table.set(index, code, instance);
} else {
table.setNull(index);

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

@ -80,10 +80,6 @@ MOZ_MUST_USE bool
Eval(JSContext* cx, Handle<TypedArrayObject*> code, HandleObject importObj,
MutableHandleWasmInstanceObject instanceObj);
// The field name of the export object on the instance object.
extern const char InstanceExportField[];
// These accessors can be used to probe JS values for being an exported wasm
// function.
@ -148,9 +144,12 @@ class WasmModuleObject : public NativeObject
class WasmInstanceObject : public NativeObject
{
static const unsigned INSTANCE_SLOT = 0;
static const unsigned EXPORTS_SLOT = 1;
static const unsigned SCOPES_SLOT = 2;
static const unsigned EXPORTS_OBJ_SLOT = 1;
static const unsigned EXPORTS_SLOT = 2;
static const unsigned SCOPES_SLOT = 3;
static const ClassOps classOps_;
static bool exportsGetterImpl(JSContext* cx, const CallArgs& args);
static bool exportsGetter(JSContext* cx, unsigned argc, Value* vp);
bool isNewborn() const;
static void finalize(FreeOp* fop, JSObject* obj);
static void trace(JSTracer* trc, JSObject* obj);
@ -176,7 +175,7 @@ class WasmInstanceObject : public NativeObject
WeakScopeMap& scopes() const;
public:
static const unsigned RESERVED_SLOTS = 3;
static const unsigned RESERVED_SLOTS = 4;
static const Class class_;
static const JSPropertySpec properties[];
static const JSFunctionSpec methods[];
@ -192,14 +191,17 @@ class WasmInstanceObject : public NativeObject
Handle<FunctionVector> funcImports,
const wasm::ValVector& globalImports,
HandleObject proto);
void initExportsObj(JSObject& exportsObj);
wasm::Instance& instance() const;
JSObject& exportsObj() const;
static bool getExportedFunction(JSContext* cx,
HandleWasmInstanceObject instanceObj,
uint32_t funcIndex,
MutableHandleFunction fun);
const wasm::CodeRange& getExportedFunctionCodeRange(HandleFunction fun);
const wasm::CodeRange& getExportedFunctionCodeRange(HandleFunction fun, wasm::Tier tier);
static WasmFunctionScope* getFunctionScope(JSContext* cx,
HandleWasmInstanceObject instanceObj,

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

@ -37,8 +37,6 @@ using namespace js::wasm;
using mozilla::IsNaN;
const char wasm::InstanceExportField[] = "exports";
#if defined(JS_CODEGEN_MIPS32) || defined(JS_CODEGEN_MIPS64)
// On MIPS, CodeLabels are instruction immediates so InternalLinks only
// patch instruction immediates.
@ -115,7 +113,7 @@ LinkDataTier::serializedSize() const
uint8_t*
LinkDataTier::serialize(uint8_t* cursor) const
{
MOZ_ASSERT(mode == CompileMode::Ion);
MOZ_ASSERT(tier == Tier::Ion);
cursor = WriteBytes(cursor, &pod(), sizeof(pod()));
cursor = SerializePodVector(cursor, internalLinks);
@ -139,11 +137,53 @@ LinkDataTier::sizeOfExcludingThis(MallocSizeOf mallocSizeOf) const
symbolicLinks.sizeOfExcludingThis(mallocSizeOf);
}
Tiers
LinkData::tiers() const
{
return Tiers(tier_->tier);
}
const LinkDataTier&
LinkData::linkData(Tier tier) const
{
switch (tier) {
case Tier::Debug:
case Tier::Baseline:
MOZ_RELEASE_ASSERT(tier_->tier == Tier::Baseline);
return *tier_;
case Tier::Ion:
MOZ_RELEASE_ASSERT(tier_->tier == Tier::Ion);
return *tier_;
case Tier::TBD:
return *tier_;
default:
MOZ_CRASH();
}
}
LinkDataTier&
LinkData::linkData(Tier tier)
{
switch (tier) {
case Tier::Debug:
case Tier::Baseline:
MOZ_RELEASE_ASSERT(tier_->tier == Tier::Baseline);
return *tier_;
case Tier::Ion:
MOZ_RELEASE_ASSERT(tier_->tier == Tier::Ion);
return *tier_;
case Tier::TBD:
return *tier_;
default:
MOZ_CRASH();
}
}
bool
LinkData::initTier(CompileMode mode)
LinkData::initTier(Tier tier)
{
MOZ_ASSERT(!tier_);
tier_ = js::MakeUnique<LinkDataTier>(mode);
tier_ = js::MakeUnique<LinkDataTier>(tier);
return tier_ != nullptr;
}
@ -261,7 +301,7 @@ Module::deserialize(const uint8_t* bytecodeBegin, size_t bytecodeSize,
return nullptr;
LinkData linkData;
if (!linkData.initTier(CompileMode::Ion))
if (!linkData.initTier(Tier::Ion))
return nullptr;
cursor = linkData.deserialize(cursor);
@ -431,11 +471,15 @@ Module::extractCode(JSContext* cx, MutableHandleValue vp) const
if (!result)
return false;
RootedObject code(cx, JS_NewUint8Array(cx, code_->segmentTier().length()));
// The tier could be a parameter to extractCode. For now, any tier will do.
Tier tier = code().anyTier();
const CodeSegment& codeSegment = code_->segment(tier);
RootedObject code(cx, JS_NewUint8Array(cx, codeSegment.length()));
if (!code)
return false;
memcpy(code->as<TypedArrayObject>().viewDataUnshared(), code_->segmentTier().base(), code_->segmentTier().length());
memcpy(code->as<TypedArrayObject>().viewDataUnshared(), codeSegment.base(), codeSegment.length());
RootedValue value(cx, ObjectValue(*code));
if (!JS_DefineProperty(cx, result, "code", value, JSPROP_ENUMERATE))
@ -445,7 +489,7 @@ Module::extractCode(JSContext* cx, MutableHandleValue vp) const
if (!segments)
return false;
for (const CodeRange& p : metadataTier().codeRanges) {
for (const CodeRange& p : metadata(tier).codeRanges) {
RootedObject segment(cx, NewObjectWithGivenProto<PlainObject>(cx, nullptr));
if (!segment)
return false;
@ -548,8 +592,9 @@ Module::initSegments(JSContext* cx,
for (const ElemSegment& seg : elemSegments_) {
Table& table = *tables[seg.tableIndex];
uint32_t offset = EvaluateInitExpr(globalImports, seg.offset);
const CodeRangeVector& codeRanges = metadataTier().codeRanges;
uint8_t* codeBase = instance.codeBaseTier();
Tier tier = Tier::TBD;
const CodeRangeVector& codeRanges = metadata(tier).codeRanges;
uint8_t* codeBase = instance.codeBase(tier);
for (uint32_t i = 0; i < seg.elemCodeRangeIndices.length(); i++) {
uint32_t funcIndex = seg.elemFuncIndices[i];
@ -559,9 +604,10 @@ Module::initSegments(JSContext* cx,
HandleFunction f = funcImports[funcIndex];
WasmInstanceObject* exportInstanceObj = ExportedFunctionToInstanceObject(f);
const CodeRange& cr = exportInstanceObj->getExportedFunctionCodeRange(f);
Tier exportTier = Tier::TBD;
const CodeRange& cr = exportInstanceObj->getExportedFunctionCodeRange(f, exportTier);
Instance& exportInstance = exportInstanceObj->instance();
table.set(offset + i, exportInstance.codeBaseTier() + cr.funcTableEntry(), exportInstance);
table.set(offset + i, exportInstance.codeBase(exportTier) + cr.funcTableEntry(), exportInstance);
} else {
const CodeRange& cr = codeRanges[seg.elemCodeRangeIndices[i]];
uint32_t entryOffset = table.isTypedFunction()
@ -602,21 +648,26 @@ FindImportForFuncImport(const ImportVector& imports, uint32_t funcImportIndex)
bool
Module::instantiateFunctions(JSContext* cx, Handle<FunctionVector> funcImports) const
{
MOZ_ASSERT(funcImports.length() == metadataTier().funcImports.length());
#ifdef DEBUG
for (auto t : code().tiers())
MOZ_ASSERT(funcImports.length() == metadata(t).funcImports.length());
#endif
if (metadata().isAsmJS())
return true;
for (size_t i = 0; i < metadataTier().funcImports.length(); i++) {
Tier tier = code().anyTier();
for (size_t i = 0; i < metadata(tier).funcImports.length(); i++) {
HandleFunction f = funcImports[i];
if (!IsExportedFunction(f) || ExportedFunctionToInstance(f).isAsmJS())
continue;
uint32_t funcIndex = ExportedFunctionToFuncIndex(f);
Instance& instance = ExportedFunctionToInstance(f);
const FuncExport& funcExport = instance.metadata().lookupFuncExport(funcIndex);
const FuncExport& funcExport = instance.metadata(tier).lookupFuncExport(funcIndex);
if (funcExport.sig() != metadataTier().funcImports[i].sig()) {
if (funcExport.sig() != metadata(tier).funcImports[i].sig()) {
const Import& import = FindImportForFuncImport(imports_, i);
JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_WASM_BAD_IMPORT_SIG,
import.module.get(), import.field.get());
@ -830,8 +881,7 @@ CreateExportObject(JSContext* cx,
HandleWasmTableObject tableObj,
HandleWasmMemoryObject memoryObj,
const ValVector& globalImports,
const ExportVector& exports,
MutableHandleObject exportObj)
const ExportVector& exports)
{
const Instance& instance = instanceObj->instance();
const Metadata& metadata = instance.metadata();
@ -840,14 +890,15 @@ CreateExportObject(JSContext* cx,
RootedValue val(cx);
if (!GetFunctionExport(cx, instanceObj, funcImports, exports[0], &val))
return false;
exportObj.set(&val.toObject());
instanceObj->initExportsObj(val.toObject());
return true;
}
RootedObject exportObj(cx);
if (metadata.isAsmJS())
exportObj.set(NewBuiltinClassInstance<PlainObject>(cx));
exportObj = NewBuiltinClassInstance<PlainObject>(cx);
else
exportObj.set(NewObjectWithGivenProto<PlainObject>(cx, nullptr));
exportObj = NewObjectWithGivenProto<PlainObject>(cx, nullptr);
if (!exportObj)
return false;
@ -884,6 +935,7 @@ CreateExportObject(JSContext* cx,
return false;
}
instanceObj->initExportsObj(*exportObj);
return true;
}
@ -920,10 +972,10 @@ Module::instantiate(JSContext* cx,
// bytes that we keep around for debugging instead, because the debugger
// may patch the pre-linked code at any time.
if (!codeIsBusy_.compareExchange(false, true)) {
auto codeSegment = CodeSegment::create(CompileMode::Baseline,
auto codeSegment = CodeSegment::create(Tier::Baseline,
*unlinkedCodeForDebugging_,
*bytecode_,
linkData_.tier(),
linkData_.linkData(Tier::Baseline),
metadata());
if (!codeSegment)
return false;
@ -970,17 +1022,7 @@ Module::instantiate(JSContext* cx,
if (!instance)
return false;
RootedObject exportObj(cx);
if (!CreateExportObject(cx, instance, funcImports, table, memory, globalImports, exports_, &exportObj))
return false;
JSAtom* atom = Atomize(cx, InstanceExportField, strlen(InstanceExportField));
if (!atom)
return false;
RootedId id(cx, AtomToId(atom));
RootedValue val(cx, ObjectValue(*exportObj));
if (!JS_DefinePropertyById(cx, instance, id, val, JSPROP_ENUMERATE))
if (!CreateExportObject(cx, instance, funcImports, table, memory, globalImports, exports_))
return false;
// Register the instance with the JSCompartment so that it can find out

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

@ -45,10 +45,12 @@ struct LinkDataTierCacheablePod
struct LinkDataTier : LinkDataTierCacheablePod
{
CompileMode mode;
const Tier tier;
explicit LinkDataTier(CompileMode mode) : mode(mode) {
MOZ_ASSERT(mode == CompileMode::Ion || mode == CompileMode::Baseline);
explicit LinkDataTier(Tier tier)
: tier(tier)
{
MOZ_ASSERT(tier == Tier::Baseline || tier == Tier::Ion);
}
LinkDataTierCacheablePod& pod() { return *this; }
@ -83,17 +85,17 @@ typedef UniquePtr<LinkDataTier> UniqueLinkDataTier;
struct LinkData
{
// `tier_` and the means of accessing it will become more complicated once
// tiering is implemented.
// `tier_` will become more complicated once tiering is implemented.
UniqueLinkDataTier tier_;
LinkData() : tier_(nullptr) {}
// Construct the tier_ object.
bool initTier(CompileMode mode);
bool initTier(Tier tier);
const LinkDataTier& tier() const { MOZ_ASSERT(tier_); return *tier_; }
LinkDataTier& tier() { MOZ_ASSERT(tier_); return *tier_; }
Tiers tiers() const;
const LinkDataTier& linkData(Tier tier) const;
LinkDataTier& linkData(Tier tier);
WASM_DECLARE_SERIALIZABLE(LinkData)
};
@ -166,12 +168,13 @@ class Module : public JS::WasmModule
}
~Module() override { /* Note: can be called on any thread */ }
const MetadataTier& metadataTier() const { return code_->metadataTier(); }
const Code& code() const { return *code_; }
const Metadata& metadata() const { return code_->metadata(); }
const MetadataTier& metadata(Tier t) const { return code_->metadata(t); }
const ImportVector& imports() const { return imports_; }
const ExportVector& exports() const { return exports_; }
const Bytes& bytecode() const { return bytecode_->bytes; }
uint32_t codeLengthTier() const { return code_->segmentTier().length(); }
uint32_t codeLength(Tier t) const { return code_->segment(t).length(); }
// Instantiate this module with the given imports:

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

@ -663,20 +663,23 @@ MOZ_COLD static void
HandleMemoryAccess(EMULATOR_CONTEXT* context, uint8_t* pc, uint8_t* faultingAddress,
const Instance& instance, WasmActivation* activation, uint8_t** ppc)
{
MOZ_RELEASE_ASSERT(instance.codeSegmentTier().containsFunctionPC(pc));
MOZ_RELEASE_ASSERT(instance.code().containsFunctionPC(pc));
const MemoryAccess* memoryAccess = instance.code().lookupMemoryAccess(pc);
const CodeSegment* segment;
const MemoryAccess* memoryAccess = instance.code().lookupMemoryAccess(pc, &segment);
if (!memoryAccess) {
// If there is no associated MemoryAccess for the faulting PC, this must be
// experimental SIMD.js or Atomics. When these are converted to
// non-experimental wasm features, this case, as well as outOfBoundsCode,
// can be removed.
activation->startInterrupt(pc, ContextToFP(context));
*ppc = instance.codeSegmentTier().outOfBoundsCode();
if (!instance.code().containsCodePC(pc, &segment))
MOZ_CRASH("Cannot map PC to trap handler");
*ppc = segment->outOfBoundsCode();
return;
}
MOZ_RELEASE_ASSERT(memoryAccess->insnOffset() == (pc - instance.codeBaseTier()));
MOZ_RELEASE_ASSERT(memoryAccess->insnOffset() == (pc - segment->base()));
// On WASM_HUGE_MEMORY platforms, asm.js code may fault. asm.js does not
// trap on fault and so has no trap out-of-line path. Instead, stores are
@ -684,7 +687,7 @@ HandleMemoryAccess(EMULATOR_CONTEXT* context, uint8_t* pc, uint8_t* faultingAddr
// loads silently succeed with a JS-semantics-determined value.
if (memoryAccess->hasTrapOutOfLineCode()) {
*ppc = memoryAccess->trapOutOfLineCode(instance.codeBaseTier());
*ppc = memoryAccess->trapOutOfLineCode(segment->base());
return;
}
@ -696,7 +699,7 @@ HandleMemoryAccess(EMULATOR_CONTEXT* context, uint8_t* pc, uint8_t* faultingAddr
uint8_t* end = Disassembler::DisassembleHeapAccess(pc, &access);
const Disassembler::ComplexAddress& address = access.address();
MOZ_RELEASE_ASSERT(end > pc);
MOZ_RELEASE_ASSERT(instance.codeSegmentTier().containsFunctionPC(end));
MOZ_RELEASE_ASSERT(segment->containsFunctionPC(end));
// Check x64 asm.js heap access invariants.
MOZ_RELEASE_ASSERT(address.disp() >= 0);
@ -809,18 +812,21 @@ MOZ_COLD static void
HandleMemoryAccess(EMULATOR_CONTEXT* context, uint8_t* pc, uint8_t* faultingAddress,
const Instance& instance, WasmActivation* activation, uint8_t** ppc)
{
MOZ_RELEASE_ASSERT(instance.codeSegmentTier().containsFunctionPC(pc));
MOZ_RELEASE_ASSERT(instance.code().containsFunctionPC(pc));
const MemoryAccess* memoryAccess = instance.code().lookupMemoryAccess(pc);
const CodeSegment* segment;
const MemoryAccess* memoryAccess = instance.code().lookupMemoryAccess(pc, &segment);
if (!memoryAccess) {
// See explanation in the WASM_HUGE_MEMORY HandleMemoryAccess.
activation->startInterrupt(pc, ContextToFP(context));
*ppc = instance.codeSegmentTier().outOfBoundsCode();
if (!instance.code().containsCodePC(pc, &segment))
MOZ_CRASH("Cannot map PC to trap handler");
*ppc = segment->outOfBoundsCode();
return;
}
MOZ_RELEASE_ASSERT(memoryAccess->hasTrapOutOfLineCode());
*ppc = memoryAccess->trapOutOfLineCode(instance.codeBaseTier());
*ppc = memoryAccess->trapOutOfLineCode(segment->base());
}
#endif // WASM_HUGE_MEMORY
@ -862,11 +868,12 @@ HandleFault(PEXCEPTION_POINTERS exception)
if (!activation)
return false;
const Code* code = activation->compartment()->wasm.lookupCode(pc);
const CodeSegment* codeSegment;
const Code* code = activation->compartment()->wasm.lookupCode(pc, &codeSegment);
if (!code)
return false;
if (!code->segmentTier().containsFunctionPC(pc)) {
if (!codeSegment->containsFunctionPC(pc)) {
// On Windows, it is possible for InterruptRunningJitCode to execute
// between a faulting heap access and the handling of the fault due
// to InterruptRunningJitCode's use of SuspendThread. When this happens,
@ -876,9 +883,16 @@ HandleFault(PEXCEPTION_POINTERS exception)
// always the logically-faulting pc). Fortunately, we can detect this
// case and silence the exception ourselves (the exception will
// retrigger after the interrupt jumps back to resumePC).
return pc == code->segmentTier().interruptCode() &&
activation->interrupted() &&
code->segmentTier().containsFunctionPC(activation->resumePC());
for (auto t : code->tiers()) {
if (pc == code->segment(t).interruptCode() &&
activation->interrupted() &&
code->segment(t).containsFunctionPC(activation->resumePC()))
{
return true;
}
}
return false;
}
const Instance* instance = LookupFaultingInstance(activation, pc, ContextToFP(context));
@ -1021,7 +1035,7 @@ HandleMachException(JSContext* cx, const ExceptionRequest& request)
return false;
const Instance* instance = LookupFaultingInstance(activation, pc, ContextToFP(&context));
if (!instance || !instance->codeSegmentTier().containsFunctionPC(pc))
if (!instance || !instance->code().containsFunctionPC(pc))
return false;
uint8_t* faultingAddress = reinterpret_cast<uint8_t*>(request.body.code[1]);
@ -1227,8 +1241,9 @@ HandleFault(int signum, siginfo_t* info, void* ctx)
if (!activation)
return false;
const CodeSegment* segment;
const Instance* instance = LookupFaultingInstance(activation, pc, ContextToFP(context));
if (!instance || !instance->codeSegmentTier().containsFunctionPC(pc))
if (!instance || !instance->code().containsFunctionPC(pc, &segment))
return false;
uint8_t* faultingAddress = reinterpret_cast<uint8_t*>(info->si_addr);
@ -1259,7 +1274,7 @@ HandleFault(int signum, siginfo_t* info, void* ctx)
// error and we should signal that properly, but to do so we must inspect
// the operand of the failed access.
activation->startInterrupt(pc, ContextToFP(context));
*ppc = instance->codeSegmentTier().unalignedAccessCode();
*ppc = segment->unalignedAccessCode();
return true;
}
#endif
@ -1348,8 +1363,9 @@ RedirectJitCodeToInterruptCheck(JSContext* cx, CONTEXT* context)
// get into any weird interrupt-during-interrupt-stub cases.
if (!cx->compartment())
return false;
const Code* code = cx->compartment()->wasm.lookupCode(pc);
if (!code || !code->segmentTier().containsFunctionPC(pc))
const CodeSegment* codeSegment;
const Code* code = cx->compartment()->wasm.lookupCode(pc, &codeSegment);
if (!code || !codeSegment->containsFunctionPC(pc))
return false;
// Only probe cx->activation() via MaybeActiveActivation after we know the
@ -1375,7 +1391,7 @@ RedirectJitCodeToInterruptCheck(JSContext* cx, CONTEXT* context)
return false;
activation->startInterrupt(pc, fp);
*ContextToPC(context) = code->segmentTier().interruptCode();
*ContextToPC(context) = codeSegment->interruptCode();
#endif
return true;

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

@ -736,7 +736,8 @@ wasm::GenerateImportJitExit(MacroAssembler& masm, const FuncImport& fi, Label* t
Register act = WasmIonExitRegE1;
// JitActivation* act = cx->activation();
masm.loadPtr(Address(WasmTlsReg, offsetof(TlsData, cx)), cx);
masm.loadPtr(Address(WasmTlsReg, offsetof(TlsData, addressOfContext)), cx);
masm.loadPtr(Address(cx, 0), cx);
masm.loadPtr(Address(cx, JSContext::offsetOfActivation()), act);
// act.active_ = true;
@ -772,7 +773,8 @@ wasm::GenerateImportJitExit(MacroAssembler& masm, const FuncImport& fi, Label* t
Register tmp = WasmIonExitRegD2;
// JitActivation* act = cx->activation();
masm.loadPtr(Address(WasmTlsReg, offsetof(TlsData, cx)), cx);
masm.loadPtr(Address(WasmTlsReg, offsetof(TlsData, addressOfContext)), cx);
masm.loadPtr(Address(cx, 0), cx);
masm.loadPtr(Address(cx, JSContext::offsetOfActivation()), act);
// cx->jitTop = act->prevJitTop_;

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

@ -1178,12 +1178,54 @@ enum ModuleKind
AsmJS
};
// Code can be compiled either with the Baseline compiler or the Ion compiler.
// Code can be compiled either with the Baseline compiler or the Ion compiler,
// and tier-variant data are tagged with the Tier value.
//
// A tier value is used to request tier-variant aspects of code, metadata, or
// linkdata. The tiers are normally explicit (Baseline and Ion); implicit tiers
// can be obtained through accessors on Code objects (eg, anyTier).
enum class CompileMode
enum class Tier
{
Baseline,
Ion
Ion,
Debug, // An alias for Baseline in calls to tier-variant accessors
TBD, // A placeholder while tiering is being implemented
};
// Iterator over tiers present in a tiered data structure.
class Tiers
{
Tier t_[2];
uint32_t n_;
public:
explicit Tiers() {
n_ = 0;
}
explicit Tiers(Tier t) {
MOZ_ASSERT(t == Tier::Baseline || t == Tier::Ion);
t_[0] = t;
n_ = 1;
}
explicit Tiers(Tier t, Tier u) {
MOZ_ASSERT(t == Tier::Baseline || t == Tier::Ion);
MOZ_ASSERT(u == Tier::Baseline || u == Tier::Ion);
MOZ_ASSERT(t != u);
t_[0] = t;
t_[1] = u;
n_ = 2;
}
Tier* begin() {
return t_;
}
Tier* end() {
return t_ + n_;
}
};
// Represents the resizable limits of memories and tables.
@ -1245,15 +1287,6 @@ struct ExportArg
struct TlsData
{
// Pointer to the JSContext that contains this TLS data.
JSContext* cx;
// Pointer to the Instance that contains this TLS data.
Instance* instance;
// Pointer to the global data for this Instance.
uint8_t* globalData;
// Pointer to the base of the default memory (or null if there is none).
uint8_t* memoryBase;
@ -1262,10 +1295,14 @@ struct TlsData
uint32_t boundsCheckLimit;
#endif
// Stack limit for the current thread. This limit is checked against the
// stack pointer in the prologue of functions that allocate stack space. See
// `CodeGenerator::generateWasm`.
void* stackLimit;
// Pointer to the global data for this Instance.
uint8_t* globalData;
// Pointer to the Instance that contains this TLS data.
Instance* instance;
// Shortcut to instance->zone->group->addressOfOwnerContext
JSContext** addressOfContext;
// The globalArea must be the last field. Globals for the module start here
// and are inline in this structure. 16-byte alignment is required for SIMD

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

@ -20,15 +20,7 @@ enum ArenaObjectID {
#include "nsPresArenaObjectList.h"
#undef PRES_ARENA_OBJECT
/**
* The PresArena implementation uses this bit to distinguish objects
* allocated by size from objects allocated by type ID (that is, frames
* using AllocateByFrameID and other objects using AllocateByObjectID).
* It should not collide with any Object ID (above) or frame ID (in
* nsQueryFrame.h). It is not 0x80000000 to avoid the question of
* whether enumeration constants are signed.
*/
eArenaObjectID_NON_OBJECT_MARKER = 0x40000000
eArenaObjectID_COUNT
};
};

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