зеркало из https://github.com/mozilla/gecko-dev.git
Merge inbound to m-c. a=merge
This commit is contained in:
Коммит
30caacbb11
|
@ -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
|
||||
};
|
||||
|
||||
};
|
||||
|
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче