Backed out changesets 6295dbaa06de, 66e037e5ff7d, and 4a1171cc4dac (bug 567058) for being the likely cause of the spike in e10s test_pluginstream_err.html crashes.

CLOSED TREE
This commit is contained in:
Ryan VanderMeulen 2015-01-13 13:28:36 -05:00
parent b82b313197
commit 3f1ea40df0
7 changed files with 125 additions and 258 deletions

View File

@ -2305,7 +2305,7 @@ nsFrameLoader::CreateStaticClone(nsIFrameLoader* aDest)
bool
nsFrameLoader::DoLoadFrameScript(const nsAString& aURL, bool aRunInGlobalScope)
{
auto* tabParent = static_cast<TabParent*>(GetRemoteBrowser());
mozilla::dom::PBrowserParent* tabParent = GetRemoteBrowser();
if (tabParent) {
return tabParent->SendLoadRemoteScript(nsString(aURL), aRunInGlobalScope);
}

View File

@ -994,11 +994,6 @@ ContentParent::CreateBrowserOrApp(const TabContext& aContext,
return nullptr;
}
if (TabParent* parent = TabParent::GetNextTabParent()) {
parent->SetOwnerElement(aFrameElement);
return parent;
}
ProcessPriority initialPriority = GetInitialProcessPriority(aFrameElement);
bool isInContentProcess = (XRE_GetProcessType() != GeckoProcessType_Default);
TabId tabId;

View File

@ -79,12 +79,6 @@ struct ShowInfo
double defaultScale;
};
struct FrameScriptInfo
{
nsString url;
bool runInGlobalScope;
};
prio(normal upto urgent) intr protocol PBrowser
{
manager PContent or PContentBridge;
@ -123,8 +117,7 @@ parent:
Event(RemoteDOMEvent aEvent);
sync CreateWindow(PBrowser aNewTab,
uint32_t aChromeFlags,
intr CreateWindow(uint32_t aChromeFlags,
bool aCalledFromJS,
bool aPositionSpecified,
bool aSizeSpecified,
@ -132,7 +125,7 @@ parent:
nsString aName,
nsString aFeatures,
nsString aBaseURI)
returns (bool windowOpened, FrameScriptInfo[] frameScripts);
returns (bool windowIsNew, PBrowser window);
sync SyncMessage(nsString aMessage, ClonedMessageData aData,
CpowEntry[] aCpows, Principal aPrincipal)

View File

@ -1429,53 +1429,93 @@ TabChild::ProvideWindow(nsIDOMWindow* aParent, uint32_t aChromeFlags,
// isn't a request to open a modal-type window, we're going to create a new
// <iframe mozbrowser/mozapp> and return its window here.
nsCOMPtr<nsIDocShell> docshell = do_GetInterface(aParent);
bool iframeMoz = (docshell && docshell->GetIsInBrowserOrApp() &&
!(aChromeFlags & (nsIWebBrowserChrome::CHROME_MODAL |
nsIWebBrowserChrome::CHROME_OPENAS_DIALOG |
nsIWebBrowserChrome::CHROME_OPENAS_CHROME)));
if (docshell && docshell->GetIsInBrowserOrApp() &&
!(aChromeFlags & (nsIWebBrowserChrome::CHROME_MODAL |
nsIWebBrowserChrome::CHROME_OPENAS_DIALOG |
nsIWebBrowserChrome::CHROME_OPENAS_CHROME))) {
if (!iframeMoz) {
int32_t openLocation =
nsWindowWatcher::GetWindowOpenLocation(aParent, aChromeFlags, aCalledFromJS,
aPositionSpecified, aSizeSpecified);
// If it turns out we're opening in the current browser, just hand over the
// current browser's docshell.
if (openLocation == nsIBrowserDOMWindow::OPEN_CURRENTWINDOW) {
nsCOMPtr<nsIWebBrowser> browser = do_GetInterface(WebNavigation());
*aWindowIsNew = false;
return browser->GetContentDOMWindow(aReturn);
}
// Note that BrowserFrameProvideWindow may return NS_ERROR_ABORT if the
// open window call was canceled. It's important that we pass this error
// code back to our caller.
return BrowserFrameProvideWindow(aParent, aURI, aName, aFeatures,
aWindowIsNew, aReturn);
}
// Note that ProvideWindowCommon may return NS_ERROR_ABORT if the
// open window call was canceled. It's important that we pass this error
// code back to our caller.
return ProvideWindowCommon(aParent,
iframeMoz,
aChromeFlags,
aCalledFromJS,
aPositionSpecified,
aSizeSpecified,
aURI,
aName,
aFeatures,
aWindowIsNew,
aReturn);
int32_t openLocation =
nsWindowWatcher::GetWindowOpenLocation(aParent, aChromeFlags, aCalledFromJS,
aPositionSpecified, aSizeSpecified);
// If it turns out we're opening in the current browser, just hand over the
// current browser's docshell.
if (openLocation == nsIBrowserDOMWindow::OPEN_CURRENTWINDOW) {
nsCOMPtr<nsIWebBrowser> browser = do_GetInterface(WebNavigation());
*aWindowIsNew = false;
return browser->GetContentDOMWindow(aReturn);
}
// Otherwise, we're opening a new tab or a new window. We have to contact
// TabParent in order to do either.
PBrowserChild* newChild;
nsAutoCString uriString;
if (aURI) {
aURI->GetSpec(uriString);
}
nsCOMPtr<nsIDOMDocument> domDoc;
aParent->GetDocument(getter_AddRefs(domDoc));
if (!domDoc) {
NS_ERROR("Could retrieve document from nsIBaseWindow");
return NS_ERROR_FAILURE;
}
nsCOMPtr<nsIDocument> doc;
doc = do_QueryInterface(domDoc);
if (!doc) {
NS_ERROR("Document from nsIBaseWindow didn't QI to nsIDocument");
return NS_ERROR_FAILURE;
}
nsCOMPtr<nsIURI> baseURI = doc->GetDocBaseURI();
if (!baseURI) {
NS_ERROR("nsIDocument didn't return a base URI");
return NS_ERROR_FAILURE;
}
nsAutoCString baseURIString;
baseURI->GetSpec(baseURIString);
nsAutoString nameString;
nameString.Assign(aName);
nsAutoCString features;
// We can assume that if content is requesting to open a window from a remote
// tab, then we want to enforce that the new window is also a remote tab.
features.Assign(aFeatures);
features.Append(",remote");
if (!CallCreateWindow(aChromeFlags, aCalledFromJS, aPositionSpecified,
aSizeSpecified, NS_ConvertUTF8toUTF16(uriString),
nameString, NS_ConvertUTF8toUTF16(features),
NS_ConvertUTF8toUTF16(baseURIString),
aWindowIsNew, &newChild)) {
return NS_ERROR_NOT_AVAILABLE;
}
nsCOMPtr<nsIDOMWindow> win =
do_GetInterface(static_cast<TabChild*>(newChild)->WebNavigation());
win.forget(aReturn);
return NS_OK;
}
nsresult
TabChild::ProvideWindowCommon(nsIDOMWindow* aOpener,
bool aIframeMoz,
uint32_t aChromeFlags,
bool aCalledFromJS,
bool aPositionSpecified,
bool aSizeSpecified,
nsIURI* aURI,
const nsAString& aName,
const nsACString& aFeatures,
bool* aWindowIsNew,
nsIDOMWindow** aReturn)
TabChild::BrowserFrameProvideWindow(nsIDOMWindow* aOpener,
nsIURI* aURI,
const nsAString& aName,
const nsACString& aFeatures,
bool* aWindowIsNew,
nsIDOMWindow** aReturn)
{
*aReturn = nullptr;
@ -1499,7 +1539,7 @@ TabChild::ProvideWindowCommon(nsIDOMWindow* aOpener,
&tabId);
nsRefPtr<TabChild> newChild = new TabChild(ContentChild::GetSingleton(), tabId,
/* TabContext */ *this, aChromeFlags);
/* TabContext */ *this, /* chromeFlags */ 0);
if (NS_FAILED(newChild->Init())) {
return NS_ERROR_ABORT;
}
@ -1508,7 +1548,7 @@ TabChild::ProvideWindowCommon(nsIDOMWindow* aOpener,
unused << Manager()->SendPBrowserConstructor(
// We release this ref in DeallocPBrowserChild
nsRefPtr<TabChild>(newChild).forget().take(),
tabId, IPCTabContext(context, mScrolling), aChromeFlags,
tabId, IPCTabContext(context, mScrolling), /* chromeFlags */ 0,
cc->GetID(), cc->IsForApp(), cc->IsForBrowser());
nsAutoCString spec;
@ -1518,51 +1558,9 @@ TabChild::ProvideWindowCommon(nsIDOMWindow* aOpener,
NS_ConvertUTF8toUTF16 url(spec);
nsString name(aName);
nsAutoCString features(aFeatures);
nsTArray<FrameScriptInfo> frameScripts;
if (aIframeMoz) {
newChild->SendBrowserFrameOpenWindow(this, url, name,
NS_ConvertUTF8toUTF16(features),
aWindowIsNew);
} else {
nsCOMPtr<nsIDOMDocument> domDoc;
aOpener->GetDocument(getter_AddRefs(domDoc));
if (!domDoc) {
NS_ERROR("Could retrieve document from nsIBaseWindow");
return NS_ERROR_FAILURE;
}
nsCOMPtr<nsIDocument> doc;
doc = do_QueryInterface(domDoc);
if (!doc) {
NS_ERROR("Document from nsIBaseWindow didn't QI to nsIDocument");
return NS_ERROR_FAILURE;
}
nsCOMPtr<nsIURI> baseURI = doc->GetDocBaseURI();
if (!baseURI) {
NS_ERROR("nsIDocument didn't return a base URI");
return NS_ERROR_FAILURE;
}
nsAutoCString baseURIString;
baseURI->GetSpec(baseURIString);
// We can assume that if content is requesting to open a window from a remote
// tab, then we want to enforce that the new window is also a remote tab.
features.AppendLiteral(",remote");
if (!SendCreateWindow(newChild,
aChromeFlags, aCalledFromJS, aPositionSpecified,
aSizeSpecified, url,
name, NS_ConvertUTF8toUTF16(features),
NS_ConvertUTF8toUTF16(baseURIString),
aWindowIsNew,
&frameScripts)) {
return NS_ERROR_NOT_AVAILABLE;
}
}
NS_ConvertUTF8toUTF16 features(aFeatures);
newChild->SendBrowserFrameOpenWindow(this, url, name,
features, aWindowIsNew);
if (!*aWindowIsNew) {
PBrowserChild::Send__delete__(newChild);
return NS_ERROR_ABORT;
@ -1585,13 +1583,6 @@ TabChild::ProvideWindowCommon(nsIDOMWindow* aOpener,
// pretty bogus; see bug 763602.
newChild->DoFakeShow(scrolling, textureFactoryIdentifier, layersId, renderFrame);
for (size_t i = 0; i < frameScripts.Length(); i++) {
FrameScriptInfo& info = frameScripts[i];
if (!newChild->RecvLoadRemoteScript(info.url(), info.runInGlobalScope())) {
MOZ_CRASH();
}
}
nsCOMPtr<nsIDOMWindow> win = do_GetInterface(newChild->WebNavigation());
win.forget(aReturn);
return NS_OK;
@ -1923,14 +1914,7 @@ TabChild::ApplyShowInfo(const ShowInfo& aInfo)
nsCOMPtr<nsIDocShell> docShell = do_GetInterface(WebNavigation());
if (docShell) {
nsCOMPtr<nsIDocShellTreeItem> item = do_GetInterface(docShell);
if (IsBrowserOrApp()) {
// B2G allows window.name to be set by changing the name attribute on the
// <iframe mozbrowser> element. window.open calls cause this attribute to
// be set to the correct value. A normal <xul:browser> element has no such
// attribute. The data we get here comes from reading the attribute, so we
// shouldn't trust it for <xul:browser> elements.
item->SetName(aInfo.name());
}
item->SetName(aInfo.name());
docShell->SetFullscreenAllowed(aInfo.fullscreenAllowed());
if (aInfo.isPrivate()) {
bool nonBlank;

View File

@ -574,17 +574,12 @@ private:
void UpdateTapState(const WidgetTouchEvent& aEvent, nsEventStatus aStatus);
nsresult
ProvideWindowCommon(nsIDOMWindow* aOpener,
bool aIframeMoz,
uint32_t aChromeFlags,
bool aCalledFromJS,
bool aPositionSpecified,
bool aSizeSpecified,
nsIURI* aURI,
const nsAString& aName,
const nsACString& aFeatures,
bool* aWindowIsNew,
nsIDOMWindow** aReturn);
BrowserFrameProvideWindow(nsIDOMWindow* aOpener,
nsIURI* aURI,
const nsAString& aName,
const nsACString& aFeatures,
bool* aWindowIsNew,
nsIDOMWindow** aReturn);
bool HasValidInnerSize();

View File

@ -272,7 +272,6 @@ TabParent::TabParent(nsIContentParent* aManager,
, mChromeFlags(aChromeFlags)
, mInitedByParent(false)
, mTabId(aTabId)
, mSkipLoad(false)
{
MOZ_ASSERT(aManager);
}
@ -450,49 +449,18 @@ TabParent::RecvEvent(const RemoteDOMEvent& aEvent)
return true;
}
struct MOZ_STACK_CLASS TabParent::AutoUseNewTab MOZ_FINAL
{
public:
AutoUseNewTab(TabParent* aNewTab, bool* aWindowIsNew)
: mNewTab(aNewTab), mWindowIsNew(aWindowIsNew)
{
MOZ_ASSERT(!TabParent::sNextTabParent);
TabParent::sNextTabParent = aNewTab;
aNewTab->mSkipLoad = true;
}
~AutoUseNewTab()
{
mNewTab->mSkipLoad = false;
if (TabParent::sNextTabParent) {
MOZ_ASSERT(TabParent::sNextTabParent == mNewTab);
TabParent::sNextTabParent = nullptr;
*mWindowIsNew = false;
}
}
private:
TabParent* mNewTab;
bool* mWindowIsNew;
};
bool
TabParent::RecvCreateWindow(PBrowserParent* aNewTab,
const uint32_t& aChromeFlags,
const bool& aCalledFromJS,
const bool& aPositionSpecified,
const bool& aSizeSpecified,
const nsString& aURI,
const nsString& aName,
const nsString& aFeatures,
const nsString& aBaseURI,
bool* aWindowIsNew,
InfallibleTArray<FrameScriptInfo>* aFrameScripts)
TabParent::AnswerCreateWindow(const uint32_t& aChromeFlags,
const bool& aCalledFromJS,
const bool& aPositionSpecified,
const bool& aSizeSpecified,
const nsString& aURI,
const nsString& aName,
const nsString& aFeatures,
const nsString& aBaseURI,
bool* aWindowIsNew,
PBrowserParent** aRetVal)
{
// We always expect to open a new window here. If we don't, it's an error.
*aWindowIsNew = true;
if (IsBrowserOrApp()) {
return false;
}
@ -502,8 +470,6 @@ TabParent::RecvCreateWindow(PBrowserParent* aNewTab,
do_GetService(NS_WINDOWWATCHER_CONTRACTID, &rv);
NS_ENSURE_SUCCESS(rv, false);
TabParent* newTab = static_cast<TabParent*>(aNewTab);
nsCOMPtr<nsIContent> frame(do_QueryInterface(mFrameElement));
NS_ENSURE_TRUE(frame, false);
@ -517,6 +483,8 @@ TabParent::RecvCreateWindow(PBrowserParent* aNewTab,
MOZ_ASSERT(openLocation == nsIBrowserDOMWindow::OPEN_NEWTAB ||
openLocation == nsIBrowserDOMWindow::OPEN_NEWWINDOW);
*aWindowIsNew = true;
// Opening new tabs is the easy case...
if (openLocation == nsIBrowserDOMWindow::OPEN_NEWTAB) {
NS_ENSURE_TRUE(mBrowserDOMWindow, false);
@ -529,18 +497,17 @@ TabParent::RecvCreateWindow(PBrowserParent* aNewTab,
params->SetReferrer(aBaseURI);
params->SetIsPrivate(isPrivate);
AutoUseNewTab aunt(newTab, aWindowIsNew);
nsCOMPtr<nsIFrameLoaderOwner> frameLoaderOwner;
mBrowserDOMWindow->OpenURIInFrame(nullptr, params,
openLocation,
nsIBrowserDOMWindow::OPEN_NEWTAB,
nsIBrowserDOMWindow::OPEN_NEW,
getter_AddRefs(frameLoaderOwner));
if (!frameLoaderOwner) {
*aWindowIsNew = false;
}
NS_ENSURE_TRUE(frameLoaderOwner, false);
aFrameScripts->SwapElements(newTab->mDelayedFrameScripts);
nsRefPtr<nsFrameLoader> frameLoader = frameLoaderOwner->GetFrameLoader();
NS_ENSURE_TRUE(frameLoader, false);
*aRetVal = frameLoader->GetRemoteBrowser();
return true;
}
@ -563,8 +530,6 @@ TabParent::RecvCreateWindow(PBrowserParent* aNewTab,
nsCOMPtr<nsIDOMWindow> window;
AutoUseNewTab aunt(newTab, aWindowIsNew);
rv = pwwatch->OpenWindow2(parent, finalURIString.get(),
NS_ConvertUTF16toUTF8(aName).get(),
NS_ConvertUTF16toUTF8(aFeatures).get(), aCalledFromJS,
@ -580,45 +545,15 @@ TabParent::RecvCreateWindow(PBrowserParent* aNewTab,
nsCOMPtr<nsITabParent> newRemoteTab = newDocShell->GetOpenedRemote();
NS_ENSURE_TRUE(newRemoteTab, false);
MOZ_ASSERT(static_cast<TabParent*>(newRemoteTab.get()) == newTab);
aFrameScripts->SwapElements(newTab->mDelayedFrameScripts);
*aRetVal = static_cast<TabParent*>(newRemoteTab.get());
return true;
}
TabParent* TabParent::sNextTabParent;
/* static */ TabParent*
TabParent::GetNextTabParent()
{
TabParent* result = sNextTabParent;
sNextTabParent = nullptr;
return result;
}
bool
TabParent::SendLoadRemoteScript(const nsString& aURL,
const bool& aRunInGlobalScope)
{
if (mSkipLoad) {
mDelayedFrameScripts.AppendElement(FrameScriptInfo(aURL, aRunInGlobalScope));
return true;
}
MOZ_ASSERT(mDelayedFrameScripts.IsEmpty());
return PBrowserParent::SendLoadRemoteScript(aURL, aRunInGlobalScope);
}
void
TabParent::LoadURL(nsIURI* aURI)
{
MOZ_ASSERT(aURI);
if (mSkipLoad) {
// Don't send the message if the child wants to load its own URL.
return;
}
if (mIsDestroyed) {
return;
}

View File

@ -134,17 +134,16 @@ public:
const nsString& aName,
const nsString& aFeatures,
bool* aOutWindowOpened) MOZ_OVERRIDE;
virtual bool RecvCreateWindow(PBrowserParent* aOpener,
const uint32_t& aChromeFlags,
const bool& aCalledFromJS,
const bool& aPositionSpecified,
const bool& aSizeSpecified,
const nsString& aURI,
const nsString& aName,
const nsString& aFeatures,
const nsString& aBaseURI,
bool* aWindowIsNew,
InfallibleTArray<FrameScriptInfo>* aFrameScripts) MOZ_OVERRIDE;
virtual bool AnswerCreateWindow(const uint32_t& aChromeFlags,
const bool& aCalledFromJS,
const bool& aPositionSpecified,
const bool& aSizeSpecified,
const nsString& aURI,
const nsString& aName,
const nsString& aFeatures,
const nsString& aBaseURI,
bool* aWindowIsNew,
PBrowserParent** aRetVal) MOZ_OVERRIDE;
virtual bool RecvSyncMessage(const nsString& aMessage,
const ClonedMessageData& aData,
const InfallibleTArray<CpowEntry>& aCpows,
@ -353,11 +352,6 @@ public:
void SetInitedByParent() { mInitedByParent = true; }
bool IsInitedByParent() const { return mInitedByParent; }
static TabParent* GetNextTabParent();
bool SendLoadRemoteScript(const nsString& aURL,
const bool& aRunInGlobalScope);
protected:
bool ReceiveMessage(const nsString& aMessage,
bool aSync,
@ -474,35 +468,6 @@ private:
TabId mTabId;
// Helper class for RecvCreateWindow.
struct AutoUseNewTab;
// When loading a new tab or window via window.open, the child process sends
// a new PBrowser to use. We store that tab in sNextTabParent and then
// proceed through the browser's normal paths to create a new
// window/tab. When it comes time to create a new TabParent, we instead use
// sNextTabParent.
static TabParent* sNextTabParent;
// When loading a new tab or window via window.open, the child is
// responsible for loading the URL it wants into the new
// TabChild. Simultaneously, though, the parent sends a LoadURL message to
// every new PBrowser (usually for about:blank). This message usually
// arrives after the child has started to load the URL it wants, and
// overrides it. To prevent this, we set mSkipLoad to true when creating the
// new tab. This flag prevents the unwanted LoadURL message from being sent
// by the parent.
bool mSkipLoad;
// When loading a new tab or window via window.open, we want to ensure that
// frame scripts for that tab are loaded before any scripts start to run in
// the window. We can't load the frame scripts the normal way, using
// separate IPC messages, since they won't be processed by the child until
// returning to the event loop, which is too late. Instead, we queue up
// frame scripts that we intend to load and send them as part of the
// CreateWindow response. Then TabChild loads them immediately.
nsTArray<FrameScriptInfo> mDelayedFrameScripts;
private:
// This is used when APZ needs to find the TabParent associated with a layer
// to dispatch events.