diff --git a/accessible/base/nsAccessibilityService.cpp b/accessible/base/nsAccessibilityService.cpp index 768ed5c2d70..227aff7402b 100644 --- a/accessible/base/nsAccessibilityService.cpp +++ b/accessible/base/nsAccessibilityService.cpp @@ -1257,7 +1257,11 @@ nsAccessibilityService::Init() logging::CheckEnv(); #endif - gApplicationAccessible = new ApplicationAccessibleWrap(); + if (XRE_GetProcessType() == GeckoProcessType_Default) + gApplicationAccessible = new ApplicationAccessibleWrap(); + else + gApplicationAccessible = new ApplicationAccessible(); + NS_ADDREF(gApplicationAccessible); // will release in Shutdown() #ifdef MOZ_CRASHREPORTER @@ -1274,7 +1278,8 @@ nsAccessibilityService::Init() gIsShutdown = false; // Now its safe to start platform accessibility. - PlatformInit(); + if (XRE_GetProcessType() == GeckoProcessType_Default) + PlatformInit(); return true; } @@ -1316,7 +1321,9 @@ nsAccessibilityService::Shutdown() gIsShutdown = true; - PlatformShutdown(); + if (XRE_GetProcessType() == GeckoProcessType_Default) + PlatformShutdown(); + gApplicationAccessible->Shutdown(); NS_RELEASE(gApplicationAccessible); gApplicationAccessible = nullptr; diff --git a/b2g/app/b2g.js b/b2g/app/b2g.js index e7039fb9221..970fd35632a 100644 --- a/b2g/app/b2g.js +++ b/b2g/app/b2g.js @@ -328,6 +328,7 @@ pref("media.eme.apiVisible", true); pref("media.video-queue.default-size", 3); // optimize images' memory usage +pref("image.downscale-during-decode.enabled", true); pref("image.decode-only-on-draw.enabled", false); pref("image.mem.allow_locking_in_content_processes", true); // Limit the surface cache to 1/8 of main memory or 128MB, whichever is smaller. diff --git a/b2g/config/dolphin/sources.xml b/b2g/config/dolphin/sources.xml index 9ceb0bc6869..6ae5451e5b7 100644 --- a/b2g/config/dolphin/sources.xml +++ b/b2g/config/dolphin/sources.xml @@ -15,7 +15,7 @@ - + diff --git a/b2g/config/emulator-ics/sources.xml b/b2g/config/emulator-ics/sources.xml index 6648ddf948b..8c7320f7f80 100644 --- a/b2g/config/emulator-ics/sources.xml +++ b/b2g/config/emulator-ics/sources.xml @@ -19,7 +19,7 @@ - + diff --git a/b2g/config/emulator-jb/sources.xml b/b2g/config/emulator-jb/sources.xml index 38e7453a7d6..fdd6af7eb02 100644 --- a/b2g/config/emulator-jb/sources.xml +++ b/b2g/config/emulator-jb/sources.xml @@ -17,7 +17,7 @@ - + diff --git a/b2g/config/emulator-kk/sources.xml b/b2g/config/emulator-kk/sources.xml index d4454f31eb8..66d9616f951 100644 --- a/b2g/config/emulator-kk/sources.xml +++ b/b2g/config/emulator-kk/sources.xml @@ -15,7 +15,7 @@ - + diff --git a/b2g/config/emulator-l/sources.xml b/b2g/config/emulator-l/sources.xml index 617176637ad..5a78c07c293 100644 --- a/b2g/config/emulator-l/sources.xml +++ b/b2g/config/emulator-l/sources.xml @@ -15,7 +15,7 @@ - + diff --git a/b2g/config/emulator/sources.xml b/b2g/config/emulator/sources.xml index 6648ddf948b..8c7320f7f80 100644 --- a/b2g/config/emulator/sources.xml +++ b/b2g/config/emulator/sources.xml @@ -19,7 +19,7 @@ - + diff --git a/b2g/config/flame-kk/sources.xml b/b2g/config/flame-kk/sources.xml index 067e12babc8..871188c4591 100644 --- a/b2g/config/flame-kk/sources.xml +++ b/b2g/config/flame-kk/sources.xml @@ -15,7 +15,7 @@ - + diff --git a/b2g/config/flame/sources.xml b/b2g/config/flame/sources.xml index 722afd65db7..5b4036dbc61 100644 --- a/b2g/config/flame/sources.xml +++ b/b2g/config/flame/sources.xml @@ -17,7 +17,7 @@ - + diff --git a/b2g/config/gaia.json b/b2g/config/gaia.json index ef3cd6eb188..72750f58cbc 100644 --- a/b2g/config/gaia.json +++ b/b2g/config/gaia.json @@ -1,9 +1,9 @@ { "git": { - "git_revision": "426fe6450ab8da92bb473fef12ccb39c6c920dd0", + "git_revision": "83b27f522642ea573c57e882657ab5c73d4b07f4", "remote": "https://git.mozilla.org/releases/gaia.git", "branch": "" }, - "revision": "b48088c5abd6ad5a64b9b870e52d6de14b3f2bc3", + "revision": "6f889f462ec6387626570bab40a0f032a205edf6", "repo_path": "integration/gaia-central" } diff --git a/b2g/config/nexus-4/sources.xml b/b2g/config/nexus-4/sources.xml index 41cc82dedbf..bf5ca7c07fe 100644 --- a/b2g/config/nexus-4/sources.xml +++ b/b2g/config/nexus-4/sources.xml @@ -17,7 +17,7 @@ - + diff --git a/b2g/config/nexus-5-l/sources.xml b/b2g/config/nexus-5-l/sources.xml index f4b27484498..929cd609aaa 100644 --- a/b2g/config/nexus-5-l/sources.xml +++ b/b2g/config/nexus-5-l/sources.xml @@ -15,7 +15,7 @@ - + diff --git a/browser/base/content/browser-eme.js b/browser/base/content/browser-eme.js index 08e8a9c15f8..a9065a89b97 100644 --- a/browser/base/content/browser-eme.js +++ b/browser/base/content/browser-eme.js @@ -206,6 +206,7 @@ let gEMEHandler = { let options = { dismissed: true, eventCallback: aTopic => aTopic == "swapping", + learnMoreURL: Services.urlFormatter.formatURLPref("app.support.baseURL") + "drm-content", }; PopupNotifications.show(browser, "drmContentPlaying", message, anchorId, mainAction, null, options); }, diff --git a/browser/base/content/test/general/browser.ini b/browser/base/content/test/general/browser.ini index 062fcf2502c..e4e0d5b2846 100644 --- a/browser/base/content/test/general/browser.ini +++ b/browser/base/content/test/general/browser.ini @@ -238,7 +238,7 @@ skip-if = e10s && debug [browser_bug624734.js] [browser_bug633691.js] [browser_bug647886.js] -skip-if = buildapp == 'mulet' || e10s # Bug 1093373 - Relies on browser.sessionHistory +skip-if = buildapp == 'mulet' [browser_bug655584.js] [browser_bug664672.js] [browser_bug676619.js] diff --git a/browser/base/content/test/general/browser_bug647886.js b/browser/base/content/test/general/browser_bug647886.js index 4a41fc6ada1..6b5bbef4944 100644 --- a/browser/base/content/test/general/browser_bug647886.js +++ b/browser/base/content/test/general/browser_bug647886.js @@ -1,36 +1,25 @@ /* Any copyright is dedicated to the Public Domain. http://creativecommons.org/publicdomain/zero/1.0/ */ -function test() { - waitForExplicitFinish(); - - gBrowser.selectedTab = gBrowser.addTab(); - gBrowser.selectedBrowser.addEventListener("load", function () { - gBrowser.selectedBrowser.removeEventListener("load", arguments.callee, true); +add_task(function* () { + yield BrowserTestUtils.openNewForegroundTab(gBrowser, "http://example.com"); + yield ContentTask.spawn(gBrowser.selectedBrowser, {}, function* () { content.history.pushState({}, "2", "2.html"); + }); - testBackButton(); - }, true); - - loadURI("http://example.com"); -} - -function testBackButton() { var backButton = document.getElementById("back-button"); var rect = backButton.getBoundingClientRect(); info("waiting for the history menu to open"); - backButton.addEventListener("popupshown", function (event) { - backButton.removeEventListener("popupshown", arguments.callee, false); - - ok(true, "history menu opened"); - event.target.hidePopup(); - gBrowser.removeTab(gBrowser.selectedTab); - finish(); - }, false); - + let popupShownPromise = BrowserTestUtils.waitForEvent(backButton, "popupshown"); EventUtils.synthesizeMouseAtCenter(backButton, {type: "mousedown"}); EventUtils.synthesizeMouse(backButton, rect.width / 2, rect.height, {type: "mouseup"}); -} + let event = yield popupShownPromise; + + ok(true, "history menu opened"); + + event.target.hidePopup(); + gBrowser.removeTab(gBrowser.selectedTab); +}); diff --git a/docshell/base/LoadContext.cpp b/docshell/base/LoadContext.cpp index 1d2df187423..5631b79896f 100644 --- a/docshell/base/LoadContext.cpp +++ b/docshell/base/LoadContext.cpp @@ -11,7 +11,8 @@ namespace mozilla { NS_IMPL_ISUPPORTS(LoadContext, nsILoadContext, nsIInterfaceRequestor) -LoadContext::LoadContext(nsIPrincipal* aPrincipal, nsILoadContext* aOptionalBase) +LoadContext::LoadContext(nsIPrincipal* aPrincipal, + nsILoadContext* aOptionalBase) : mTopFrameElement(nullptr) , mNestedFrameId(0) , mIsContent(true) @@ -22,17 +23,18 @@ LoadContext::LoadContext(nsIPrincipal* aPrincipal, nsILoadContext* aOptionalBase #endif { MOZ_ALWAYS_TRUE(NS_SUCCEEDED(aPrincipal->GetAppId(&mAppId))); - MOZ_ALWAYS_TRUE(NS_SUCCEEDED( - aPrincipal->GetIsInBrowserElement(&mIsInBrowserElement))); + MOZ_ALWAYS_TRUE( + NS_SUCCEEDED(aPrincipal->GetIsInBrowserElement(&mIsInBrowserElement))); if (!aOptionalBase) { return; } MOZ_ALWAYS_TRUE(NS_SUCCEEDED(aOptionalBase->GetIsContent(&mIsContent))); - MOZ_ALWAYS_TRUE(NS_SUCCEEDED( - aOptionalBase->GetUsePrivateBrowsing(&mUsePrivateBrowsing))); - MOZ_ALWAYS_TRUE(NS_SUCCEEDED(aOptionalBase->GetUseRemoteTabs(&mUseRemoteTabs))); + MOZ_ALWAYS_TRUE( + NS_SUCCEEDED(aOptionalBase->GetUsePrivateBrowsing(&mUsePrivateBrowsing))); + MOZ_ALWAYS_TRUE( + NS_SUCCEEDED(aOptionalBase->GetUseRemoteTabs(&mUseRemoteTabs))); } //----------------------------------------------------------------------------- diff --git a/docshell/base/LoadContext.h b/docshell/base/LoadContext.h index 22fd28583da..ff0c9adfd03 100644 --- a/docshell/base/LoadContext.h +++ b/docshell/base/LoadContext.h @@ -53,7 +53,8 @@ public: #ifdef DEBUG , mIsNotNull(aToCopy.mIsNotNull) #endif - {} + { + } // AppId/inBrowser arguments override those in SerializedLoadContext provided // by child process. @@ -70,7 +71,8 @@ public: #ifdef DEBUG , mIsNotNull(aToCopy.mIsNotNull) #endif - {} + { + } LoadContext(dom::Element* aTopFrameElement, uint32_t aAppId, @@ -88,7 +90,8 @@ public: #ifdef DEBUG , mIsNotNull(true) #endif - {} + { + } // Constructor taking reserved appId for the safebrowsing cookie. explicit LoadContext(uint32_t aAppId) @@ -102,7 +105,8 @@ public: #ifdef DEBUG , mIsNotNull(true) #endif - {} + { + } // Constructor for creating a LoadContext with a given principal's appId and // browser flag. @@ -127,4 +131,3 @@ private: } // namespace mozilla #endif // LoadContext_h - diff --git a/docshell/base/SerializedLoadContext.cpp b/docshell/base/SerializedLoadContext.cpp index 0c746bd2b90..f328845b64f 100644 --- a/docshell/base/SerializedLoadContext.cpp +++ b/docshell/base/SerializedLoadContext.cpp @@ -77,4 +77,3 @@ SerializedLoadContext::Init(nsILoadContext* aLoadContext) } } // namespace IPC - diff --git a/docshell/base/SerializedLoadContext.h b/docshell/base/SerializedLoadContext.h index fe2fb2e4dbd..4655dca68af 100644 --- a/docshell/base/SerializedLoadContext.h +++ b/docshell/base/SerializedLoadContext.h @@ -72,11 +72,11 @@ struct ParamTraits static bool Read(const Message* aMsg, void** aIter, paramType* aResult) { if (!ReadParam(aMsg, aIter, &aResult->mIsNotNull) || - !ReadParam(aMsg, aIter, &aResult->mIsContent) || - !ReadParam(aMsg, aIter, &aResult->mIsPrivateBitValid) || - !ReadParam(aMsg, aIter, &aResult->mUsePrivateBrowsing) || - !ReadParam(aMsg, aIter, &aResult->mUseRemoteTabs) || - !ReadParam(aMsg, aIter, &aResult->mAppId) || + !ReadParam(aMsg, aIter, &aResult->mIsContent) || + !ReadParam(aMsg, aIter, &aResult->mIsPrivateBitValid) || + !ReadParam(aMsg, aIter, &aResult->mUsePrivateBrowsing) || + !ReadParam(aMsg, aIter, &aResult->mUseRemoteTabs) || + !ReadParam(aMsg, aIter, &aResult->mAppId) || !ReadParam(aMsg, aIter, &aResult->mIsInBrowserElement)) { return false; } @@ -88,4 +88,3 @@ struct ParamTraits } // namespace IPC #endif // SerializedLoadContext_h - diff --git a/docshell/base/nsDSURIContentListener.cpp b/docshell/base/nsDSURIContentListener.cpp index b8434f40155..5a94654535b 100644 --- a/docshell/base/nsDSURIContentListener.cpp +++ b/docshell/base/nsDSURIContentListener.cpp @@ -26,10 +26,6 @@ using namespace mozilla; -//***************************************************************************** -//*** nsDSURIContentListener: Object Management -//***************************************************************************** - nsDSURIContentListener::nsDSURIContentListener(nsDocShell* aDocShell) : mDocShell(aDocShell) , mExistingJPEGRequest(nullptr) @@ -50,10 +46,6 @@ nsDSURIContentListener::Init() return rv; } -//***************************************************************************** -// nsDSURIContentListener::nsISupports -//***************************************************************************** - NS_IMPL_ADDREF(nsDSURIContentListener) NS_IMPL_RELEASE(nsDSURIContentListener) @@ -63,16 +55,11 @@ NS_INTERFACE_MAP_BEGIN(nsDSURIContentListener) NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference) NS_INTERFACE_MAP_END -//***************************************************************************** -// nsDSURIContentListener::nsIURIContentListener -//***************************************************************************** - NS_IMETHODIMP nsDSURIContentListener::OnStartURIOpen(nsIURI* aURI, bool* aAbortOpen) { - // If mDocShell is null here, that means someone's starting a load - // in our docshell after it's already been destroyed. Don't let - // that happen. + // If mDocShell is null here, that means someone's starting a load in our + // docshell after it's already been destroyed. Don't let that happen. if (!mDocShell) { *aAbortOpen = true; return NS_OK; @@ -188,17 +175,16 @@ nsDSURIContentListener::IsPreferred(const char* aContentType, aDesiredContentType, aCanHandle); } - // we used to return false here if we didn't have a parent properly - // registered at the top of the docshell hierarchy to dictate what - // content types this docshell should be a preferred handler for. But - // this really makes it hard for developers using iframe or browser tags - // because then they need to make sure they implement - // nsIURIContentListener otherwise all link clicks would get sent to - // another window because we said we weren't the preferred handler type. - // I'm going to change the default now...if we can handle the content, - // and someone didn't EXPLICITLY set a nsIURIContentListener at the top - // of our docshell chain, then we'll now always attempt to process the - // content ourselves... + // we used to return false here if we didn't have a parent properly registered + // at the top of the docshell hierarchy to dictate what content types this + // docshell should be a preferred handler for. But this really makes it hard + // for developers using iframe or browser tags because then they need to make + // sure they implement nsIURIContentListener otherwise all link clicks would + // get sent to another window because we said we weren't the preferred handler + // type. I'm going to change the default now... if we can handle the content, + // and someone didn't EXPLICITLY set a nsIURIContentListener at the top of our + // docshell chain, then we'll now always attempt to process the content + // ourselves... return CanHandleContent(aContentType, true, aDesiredContentType, aCanHandle); } diff --git a/docshell/base/nsDefaultURIFixup.cpp b/docshell/base/nsDefaultURIFixup.cpp index 97b5745dc94..aa10be1acd3 100644 --- a/docshell/base/nsDefaultURIFixup.cpp +++ b/docshell/base/nsDefaultURIFixup.cpp @@ -970,7 +970,8 @@ nsDefaultURIFixup::KeywordURIFixup(const nsACString& aURIString, // If we're at the end of the string or this is the first slash, // check if the thing before the slash looks like ipv4: - if ((iter.size_forward() == 1 || (lastSlashLoc == uint32_t(kNotFound) && *iter == '/')) && + if ((iter.size_forward() == 1 || + (lastSlashLoc == uint32_t(kNotFound) && *iter == '/')) && // Need 2 or 3 dots + only digits (foundDots == 2 || foundDots == 3) && // and they should be all that came before now: diff --git a/docshell/base/nsDocShell.cpp b/docshell/base/nsDocShell.cpp index 23de8182170..fe34b94d523 100644 --- a/docshell/base/nsDocShell.cpp +++ b/docshell/base/nsDocShell.cpp @@ -712,7 +712,8 @@ SendPing(void* aClosure, nsIContent* aContent, nsIURI* aURI, nsPingListener* pingListener = new nsPingListener(info->requireSameHost, aContent, loadGroup); - nsCOMPtr interceptController = do_QueryInterface(info->docShell); + nsCOMPtr interceptController = + do_QueryInterface(info->docShell); pingListener->SetInterceptController(interceptController); nsCOMPtr listener(pingListener); @@ -845,10 +846,6 @@ DecreasePrivateDocShellCount() } } -//***************************************************************************** -//*** nsDocShell: Object Management -//***************************************************************************** - static uint64_t gDocshellIDCounter = 0; nsDocShell::nsDocShell() @@ -1032,10 +1029,6 @@ nsDocShell::DestroyChildren() nsDocLoader::DestroyChildren(); } -//***************************************************************************** -// nsDocShell::nsISupports -//***************************************************************************** - NS_IMPL_ADDREF_INHERITED(nsDocShell, nsDocLoader) NS_IMPL_RELEASE_INHERITED(nsDocShell, nsDocLoader) @@ -1061,9 +1054,6 @@ NS_INTERFACE_MAP_BEGIN(nsDocShell) NS_INTERFACE_MAP_ENTRY(nsINetworkInterceptController) NS_INTERFACE_MAP_END_INHERITING(nsDocLoader) -///***************************************************************************** -// nsDocShell::nsIInterfaceRequestor -//***************************************************************************** NS_IMETHODIMP nsDocShell::GetInterface(const nsIID& aIID, void** aSink) { @@ -1361,9 +1351,6 @@ nsDocShell::ConvertLoadTypeToDocShellLoadInfo(uint32_t aLoadType) return docShellLoadType; } -//***************************************************************************** -// nsDocShell::nsIDocShell -//***************************************************************************** NS_IMETHODIMP nsDocShell::LoadURI(nsIURI* aURI, nsIDocShellLoadInfo* aLoadInfo, @@ -2610,14 +2597,16 @@ nsDocShell::SetAllowContentRetargeting(bool aAllowContentRetargeting) } NS_IMETHODIMP -nsDocShell::GetAllowContentRetargetingOnChildren(bool* aAllowContentRetargetingOnChildren) +nsDocShell::GetAllowContentRetargetingOnChildren( + bool* aAllowContentRetargetingOnChildren) { *aAllowContentRetargetingOnChildren = mAllowContentRetargetingOnChildren; return NS_OK; } NS_IMETHODIMP -nsDocShell::SetAllowContentRetargetingOnChildren(bool aAllowContentRetargetingOnChildren) +nsDocShell::SetAllowContentRetargetingOnChildren( + bool aAllowContentRetargetingOnChildren) { mAllowContentRetargetingOnChildren = aAllowContentRetargetingOnChildren; return NS_OK; @@ -3489,7 +3478,8 @@ nsDocShell::SetDocLoaderParent(nsDocLoader* aParent) if (NS_SUCCEEDED(parentAsDocShell->GetAllowWindowControl(&value))) { SetAllowWindowControl(value); } - SetAllowContentRetargeting(parentAsDocShell->GetAllowContentRetargetingOnChildren()); + SetAllowContentRetargeting( + parentAsDocShell->GetAllowContentRetargetingOnChildren()); if (NS_SUCCEEDED(parentAsDocShell->GetIsActive(&value))) { SetIsActive(value); } @@ -5611,6 +5601,7 @@ nsDocShell::GetSessionHistory(nsISHistory** aSessionHistory) //***************************************************************************** // nsDocShell::nsIWebPageDescriptor //***************************************************************************** + NS_IMETHODIMP nsDocShell::LoadPage(nsISupports* aPageDescriptor, uint32_t aDisplayType) { @@ -7174,7 +7165,7 @@ nsDocShell::RefreshURIFromQueue() timer->InitWithCallback(refreshInfo, delay, nsITimer::TYPE_ONE_SHOT); } } - } // while + } return NS_OK; } @@ -7821,20 +7812,19 @@ nsDocShell::EndPageLoad(nsIWebProgress* aProgress, aStatus == NS_ERROR_PROXY_CONNECTION_REFUSED) && (isTopFrame || UseErrorPages())) { DisplayLoadError(aStatus, url, nullptr, aChannel); - } - else if (aStatus == NS_ERROR_NET_TIMEOUT || - aStatus == NS_ERROR_REDIRECT_LOOP || - aStatus == NS_ERROR_UNKNOWN_SOCKET_TYPE || - aStatus == NS_ERROR_NET_INTERRUPT || - aStatus == NS_ERROR_NET_RESET || - aStatus == NS_ERROR_OFFLINE || - aStatus == NS_ERROR_MALWARE_URI || - aStatus == NS_ERROR_PHISHING_URI || - aStatus == NS_ERROR_UNWANTED_URI || - aStatus == NS_ERROR_UNSAFE_CONTENT_TYPE || - aStatus == NS_ERROR_REMOTE_XUL || - aStatus == NS_ERROR_OFFLINE || - NS_ERROR_GET_MODULE(aStatus) == NS_ERROR_MODULE_SECURITY) { + } else if (aStatus == NS_ERROR_NET_TIMEOUT || + aStatus == NS_ERROR_REDIRECT_LOOP || + aStatus == NS_ERROR_UNKNOWN_SOCKET_TYPE || + aStatus == NS_ERROR_NET_INTERRUPT || + aStatus == NS_ERROR_NET_RESET || + aStatus == NS_ERROR_OFFLINE || + aStatus == NS_ERROR_MALWARE_URI || + aStatus == NS_ERROR_PHISHING_URI || + aStatus == NS_ERROR_UNWANTED_URI || + aStatus == NS_ERROR_UNSAFE_CONTENT_TYPE || + aStatus == NS_ERROR_REMOTE_XUL || + aStatus == NS_ERROR_OFFLINE || + NS_ERROR_GET_MODULE(aStatus) == NS_ERROR_MODULE_SECURITY) { // Errors to be shown for any frame DisplayLoadError(aStatus, url, nullptr, aChannel); } else if (aStatus == NS_ERROR_DOCUMENT_NOT_CACHED) { @@ -7846,8 +7836,7 @@ nsDocShell::EndPageLoad(nsIWebProgress* aProgress, } DisplayLoadError(aStatus, url, nullptr, aChannel); } - } - else if (url && NS_SUCCEEDED(aStatus)) { + } else if (url && NS_SUCCEEDED(aStatus)) { // If we have a host mozilla::net::PredictorLearnRedirect(url, aChannel, this); } @@ -8001,9 +7990,9 @@ nsDocShell::CreateAboutBlankContentViewer(nsIPrincipal* aPrincipal, blankDoc->SetSandboxFlags(mSandboxFlags); // create a content viewer for us and the new document - docFactory->CreateInstanceForDocument(NS_ISUPPORTS_CAST(nsIDocShell*, this), - blankDoc, "view", - getter_AddRefs(viewer)); + docFactory->CreateInstanceForDocument( + NS_ISUPPORTS_CAST(nsIDocShell*, this), blankDoc, "view", + getter_AddRefs(viewer)); // hook 'em up if (viewer) { @@ -8405,8 +8394,8 @@ class MOZ_STACK_CLASS PresentationEventForgetter { public: explicit PresentationEventForgetter( - nsRevocableEventPtr& - aRestorePresentationEvent) + nsRevocableEventPtr& + aRestorePresentationEvent) : mRestorePresentationEvent(aRestorePresentationEvent) , mEvent(aRestorePresentationEvent.get()) { @@ -8785,7 +8774,8 @@ nsDocShell::RestoreFromHistory() childShell->GetAllowDNSPrefetch(&allowDNSPrefetch); bool allowContentRetargeting = childShell->GetAllowContentRetargeting(); - bool allowContentRetargetingOnChildren = childShell->GetAllowContentRetargetingOnChildren(); + bool allowContentRetargetingOnChildren = + childShell->GetAllowContentRetargetingOnChildren(); uint32_t defaultLoadFlags; childShell->GetDefaultLoadFlags(&defaultLoadFlags); @@ -8804,7 +8794,8 @@ nsDocShell::RestoreFromHistory() childShell->SetAllowMedia(allowMedia); childShell->SetAllowDNSPrefetch(allowDNSPrefetch); childShell->SetAllowContentRetargeting(allowContentRetargeting); - childShell->SetAllowContentRetargetingOnChildren(allowContentRetargetingOnChildren); + childShell->SetAllowContentRetargetingOnChildren( + allowContentRetargetingOnChildren); childShell->SetDefaultLoadFlags(defaultLoadFlags); rv = childShell->BeginRestore(nullptr, false); @@ -9085,8 +9076,9 @@ nsDocShell::CreateContentViewer(const nsACString& aContentType, aOpenedChannel->SetLoadFlags(loadFlags); mLoadGroup->AddRequest(aRequest, nullptr); - if (currentLoadGroup) + if (currentLoadGroup) { currentLoadGroup->RemoveRequest(aRequest, nullptr, NS_BINDING_RETARGETED); + } // Update the notification callbacks, so that progress and // status information are sent to the right docshell... @@ -9405,6 +9397,7 @@ nsDocShell::CheckLoadingPermissions() //***************************************************************************** // nsDocShell: Site Loading //***************************************************************************** + namespace { #ifdef MOZ_PLACES @@ -9515,7 +9508,8 @@ public: } } - NS_IMETHOD Run() + NS_IMETHOD + Run() { return mDocShell->InternalLoad(mURI, mReferrer, mReferrerPolicy, @@ -11222,7 +11216,7 @@ nsDocShell::OnNewURI(nsIURI* aURI, nsIChannel* aChannel, nsISupports* aOwner, updateSHistory = false; updateGHistory = false; // XXX Why global history too? } - } // rootSH + } // Check if the url to be loaded is the same as the one already loaded. if (mCurrentURI) { @@ -11823,9 +11817,9 @@ nsDocShell::AddToSessionHistory(nsIURI* aURI, nsIChannel* aChannel, nsCOMPtr child; shContainer->GetChildAt(i, getter_AddRefs(child)); shContainer->RemoveChild(child); - } // for + } entry->AbandonBFCacheEntry(); - } // shContainer + } } // Create a new entry if necessary. @@ -12166,7 +12160,8 @@ nsDocShell::WalkHistoryEntries(nsISHEntry* aRootEntry, if (aRootShell) { // Walk the children of aRootShell and see if one of them // has srcChild as a SHEntry. - nsTObserverArray::ForwardIterator iter(aRootShell->mChildList); + nsTObserverArray::ForwardIterator iter( + aRootShell->mChildList); while (iter.HasMore()) { nsDocShell* child = static_cast(iter.GetNext()); @@ -12939,10 +12934,6 @@ nsDocShell::SetLayoutHistoryState(nsILayoutHistoryState* aLayoutHistoryState) return NS_OK; } -//***************************************************************************** -//*** nsRefreshTimer: Object Management -//***************************************************************************** - nsRefreshTimer::nsRefreshTimer() : mDelay(0), mRepeat(false), mMetaRefresh(false) { @@ -12952,10 +12943,6 @@ nsRefreshTimer::~nsRefreshTimer() { } -//***************************************************************************** -// nsRefreshTimer::nsISupports -//***************************************************************************** - NS_IMPL_ADDREF(nsRefreshTimer) NS_IMPL_RELEASE(nsRefreshTimer) @@ -12964,9 +12951,6 @@ NS_INTERFACE_MAP_BEGIN(nsRefreshTimer) NS_INTERFACE_MAP_ENTRY(nsITimerCallback) NS_INTERFACE_MAP_END_THREADSAFE -///***************************************************************************** -// nsRefreshTimer::nsITimerCallback -//****************************************************************************** NS_IMETHODIMP nsRefreshTimer::Notify(nsITimer* aTimer) { @@ -12981,9 +12965,6 @@ nsRefreshTimer::Notify(nsITimer* aTimer) return NS_OK; } -//***************************************************************************** -// nsDocShell::InterfaceRequestorProxy -//***************************************************************************** nsDocShell::InterfaceRequestorProxy::InterfaceRequestorProxy( nsIInterfaceRequestor* aRequestor) { @@ -13022,8 +13003,9 @@ nsDocShell::SetBaseUrlForWyciwyg(nsIContentViewer* aContentViewer) nsCOMPtr baseURI; nsresult rv = NS_ERROR_NOT_AVAILABLE; - if (sURIFixup) + if (sURIFixup) { rv = sURIFixup->CreateExposableURI(mCurrentURI, getter_AddRefs(baseURI)); + } // Get the current document and set the base uri if (baseURI) { @@ -13069,6 +13051,7 @@ nsDocShell::GetAuthPrompt(uint32_t aPromptReason, const nsIID& aIID, //***************************************************************************** // nsDocShell::nsILoadContext //***************************************************************************** + NS_IMETHODIMP nsDocShell::GetAssociatedWindow(nsIDOMWindow** aWindow) { @@ -13321,8 +13304,6 @@ nsDocShell::SelectNone(void) return DoCommand("cmd_selectNone"); } -//---------------------------------------------------------------------- - // link handling class OnLinkClickEvent : public nsRunnable @@ -13382,8 +13363,6 @@ OnLinkClickEvent::OnLinkClickEvent(nsDocShell* aHandler, { } -//---------------------------------------- - NS_IMETHODIMP nsDocShell::OnLinkClick(nsIContent* aContent, nsIURI* aURI, @@ -13934,7 +13913,6 @@ nsDocShell::GetURLSearchParams() class JavascriptTimelineMarker : public TimelineMarker { public: - JavascriptTimelineMarker(nsDocShell* aDocShell, const char* aName, const char* aReason) : TimelineMarker(aDocShell, aName, TRACING_INTERVAL_START, @@ -13949,7 +13927,7 @@ public: }; void -nsDocShell::NotifyJSRunToCompletionStart(const char *aReason) +nsDocShell::NotifyJSRunToCompletionStart(const char* aReason) { bool timelineOn = nsIDocShell::GetRecordProfileTimelineMarkers(); @@ -14009,7 +13987,8 @@ nsDocShell::MaybeNotifyKeywordSearchLoading(const nsString& aProvider, } NS_IMETHODIMP -nsDocShell::ShouldPrepareForIntercept(nsIURI* aURI, bool aIsNavigate, bool* aShouldIntercept) +nsDocShell::ShouldPrepareForIntercept(nsIURI* aURI, bool aIsNavigate, + bool* aShouldIntercept) { *aShouldIntercept = false; if (mSandboxFlags) { @@ -14017,7 +13996,7 @@ nsDocShell::ShouldPrepareForIntercept(nsIURI* aURI, bool aIsNavigate, bool* aSho return NS_OK; } - nsCOMPtr swm = mozilla::services::GetServiceWorkerManager(); + nsCOMPtr swm = services::GetServiceWorkerManager(); if (!swm) { return NS_OK; } @@ -14037,7 +14016,7 @@ nsDocShell::ShouldPrepareForIntercept(nsIURI* aURI, bool aIsNavigate, bool* aSho NS_IMETHODIMP nsDocShell::ChannelIntercepted(nsIInterceptedChannel* aChannel) { - nsCOMPtr swm = mozilla::services::GetServiceWorkerManager(); + nsCOMPtr swm = services::GetServiceWorkerManager(); if (!swm) { aChannel->Cancel(); return NS_OK; diff --git a/docshell/base/nsDocShell.h b/docshell/base/nsDocShell.h index 8c83e681780..7c6d1cad70b 100644 --- a/docshell/base/nsDocShell.h +++ b/docshell/base/nsDocShell.h @@ -89,9 +89,6 @@ class nsIURILoader; class nsIWebBrowserFind; class nsIWidget; -/* load commands were moved to nsIDocShell.h */ -/* load types were moved to nsDocShellLoadTypes.h */ - /* internally used ViewMode types */ enum ViewMode { @@ -99,10 +96,6 @@ enum ViewMode viewSource = 0x1 }; -//***************************************************************************** -//*** nsRefreshTimer -//***************************************************************************** - class nsRefreshTimer : public nsITimerCallback { public: @@ -130,10 +123,6 @@ enum eCharsetReloadState eCharsetReloadStopOrigional }; -//***************************************************************************** -//*** nsDocShell -//***************************************************************************** - class nsDocShell final : public nsDocLoader , public nsIDocShell @@ -159,7 +148,7 @@ class nsDocShell final public: MOZ_DECLARE_WEAKREFERENCE_TYPENAME(nsDocShell) - // Object Management + nsDocShell(); NS_DECL_AND_IMPL_ZEROING_OPERATOR_NEW @@ -186,7 +175,8 @@ public: NS_DECL_NSINETWORKINTERCEPTCONTROLLER NS_FORWARD_SAFE_NSIDOMSTORAGEMANAGER(TopSessionStorageManager()) - NS_IMETHOD Stop() override { + NS_IMETHOD Stop() override + { // Need this here because otherwise nsIWebNavigation::Stop // overrides the docloader's Stop() return nsDocLoader::Stop(); @@ -219,7 +209,7 @@ public: nsDocShellInfoLoadType ConvertLoadTypeToDocShellLoadInfo(uint32_t aLoadType); uint32_t ConvertDocShellLoadInfoToLoadType( - nsDocShellInfoLoadType aDocShellLoadType); + nsDocShellInfoLoadType aDocShellLoadType); // Don't use NS_DECL_NSILOADCONTEXT because some of nsILoadContext's methods // are shared with nsIDocShell (appID, etc.) and can't be declared twice. @@ -237,10 +227,10 @@ public: // Restores a cached presentation from history (mLSHE). // This method swaps out the content viewer and simulates loads for - // subframes. It then simulates the completion of the toplevel load. + // subframes. It then simulates the completion of the toplevel load. nsresult RestoreFromHistory(); - // Perform a URI load from a refresh timer. This is just like the + // Perform a URI load from a refresh timer. This is just like the // ForceRefreshURI method on nsIRefreshURI, but makes sure to take // the timer involved out of mRefreshURIList if it's there. // aTimer must not be null. @@ -269,8 +259,7 @@ public: // Add new profile timeline markers to this docShell. This will only add // markers if the docShell is currently recording profile timeline markers. // See nsIDocShell::recordProfileTimelineMarkers - void AddProfileTimelineMarker(const char* aName, - TracingMetadata aMetaData); + void AddProfileTimelineMarker(const char* aName, TracingMetadata aMetaData); void AddProfileTimelineMarker(mozilla::UniquePtr&& aMarker); // Global counter for how many docShells are currently recording profile @@ -283,13 +272,12 @@ public: bool aInPrivateBrowsing); protected: - // Object Management virtual ~nsDocShell(); virtual void DestroyChildren() override; // Content Viewer Management nsresult EnsureContentViewer(); - // aPrincipal can be passed in if the caller wants. If null is + // aPrincipal can be passed in if the caller wants. If null is // passed in, the about:blank principal will end up being used. nsresult CreateAboutBlankContentViewer(nsIPrincipal* aPrincipal, nsIURI* aBaseURI, @@ -307,16 +295,16 @@ protected: nsresult GetEldestPresContext(nsPresContext** aPresContext); - // Get the principal that we'll set on the channel if we're inheriting. If + // Get the principal that we'll set on the channel if we're inheriting. If // aConsiderCurrentDocument is true, we try to use the current document if - // at all possible. If that fails, we fall back on the parent document. + // at all possible. If that fails, we fall back on the parent document. // If that fails too, we force creation of a content viewer and use the - // resulting principal. If aConsiderCurrentDocument is false, we just look + // resulting principal. If aConsiderCurrentDocument is false, we just look // at the parent. nsIPrincipal* GetInheritedPrincipal(bool aConsiderCurrentDocument); - // Actually open a channel and perform a URI load. Note: whatever owner is - // passed to this function will be set on the channel. Callers who wish to + // Actually open a channel and perform a URI load. Note: whatever owner is + // passed to this function will be set on the channel. Callers who wish to // not have an owner on the channel should just pass null. // If aSrcdoc is not void, the load will be considered as a srcdoc load, // and the contents of aSrcdoc will be loaded instead of aURI. @@ -361,7 +349,7 @@ protected: // In this case it is the caller's responsibility to ensure // FireOnLocationChange is called. // In all other cases false is returned. - // Either aChannel or aOwner must be null. If aChannel is + // Either aChannel or aOwner must be null. If aChannel is // present, the owner should be gotten from it. // If OnNewURI calls AddToSessionHistory, it will pass its // aCloneSHChildren argument as aCloneChildren. @@ -376,10 +364,10 @@ protected: // Session History bool ShouldAddToSessionHistory(nsIURI* aURI); - // Either aChannel or aOwner must be null. If aChannel is + // Either aChannel or aOwner must be null. If aChannel is // present, the owner should be gotten from it. // If aCloneChildren is true, then our current session history's - // children will be cloned onto the new entry. This should be + // children will be cloned onto the new entry. This should be // used when we aren't actually changing the document while adding // the new session history entry. nsresult AddToSessionHistory(nsIURI* aURI, nsIChannel* aChannel, @@ -399,7 +387,7 @@ protected: // Clone a session history tree for subframe navigation. // The tree rooted at |aSrcEntry| will be cloned into |aDestEntry|, except // for the entry with id |aCloneID|, which will be replaced with - // |aReplaceEntry|. |aSrcShell| is a (possibly null) docshell which + // |aReplaceEntry|. |aSrcShell| is a (possibly null) docshell which // corresponds to |aSrcEntry| via its mLSHE or mOHE pointers, and will // have that pointer updated to point to the cloned history entry. // If aCloneChildren is true then the children of the entry with id @@ -430,7 +418,7 @@ protected: void SwapHistoryEntries(nsISHEntry* aOldEntry, nsISHEntry* aNewEntry); // Call this method to swap in a new history entry to m[OL]SHE, rather than - // setting it directly. This completes the navigation in all docshells + // setting it directly. This completes the navigation in all docshells // in the case of a subframe navigation. void SetHistoryEntry(nsCOMPtr* aPtr, nsISHEntry* aEntry); @@ -448,7 +436,7 @@ protected: void* aData); // For each child of aRootEntry, find the corresponding docshell which is - // a child of aRootShell, and call aCallback. The opaque pointer aData + // a child of aRootShell, and call aCallback. The opaque pointer aData // is passed to the callback. static nsresult WalkHistoryEntries(nsISHEntry* aRootEntry, nsDocShell* aRootShell, @@ -477,7 +465,7 @@ protected: * channel. * * This method first checks the channel's property bag to see if previous - * info has been saved. If not, it gives back the referrer of the channel. + * info has been saved. If not, it gives back the referrer of the channel. * * @param aChannel * The channel we are transitioning to @@ -506,7 +494,7 @@ protected: uint32_t aChannelRedirectFlags); /** - * Helper function for adding a URI visit using IHistory. If IHistory is + * Helper function for adding a URI visit using IHistory. If IHistory is * not available, the method tries nsIGlobalHistory2. * * The IHistory API maintains chains of visits, tracking both HTTP referrers @@ -514,7 +502,7 @@ protected: * the previous URI in the chain. * * Visits can be saved either during a redirect or when the request has - * reached its final destination. The previous URI in the visit may be + * reached its final destination. The previous URI in the visit may be * from another redirect or it may be the referrer. * * @pre aURI is not null. @@ -583,13 +571,13 @@ protected: nsresult aResult); // Sets the current document's current state object to the given SHEntry's - // state object. The current state object is eventually given to the page + // state object. The current state object is eventually given to the page // in the PopState event. nsresult SetDocCurrentStateObj(nsISHEntry* aShEntry); nsresult CheckLoadingPermissions(); - // Security checks to prevent frameset spoofing. See comments at + // Security checks to prevent frameset spoofing. See comments at // implementation sites. static bool CanAccessItem(nsIDocShellTreeItem* aTargetItem, nsIDocShellTreeItem* aAccessingItem, @@ -610,33 +598,33 @@ protected: // in session history. // mContentViewer points to the current content viewer associated with - // this docshell. When loading a new document, the content viewer is - // either destroyed or stored into a session history entry. To make sure + // this docshell. When loading a new document, the content viewer is + // either destroyed or stored into a session history entry. To make sure // that destruction happens in a controlled fashion, a given content viewer // is always owned in exactly one of these ways: // 1) The content viewer is active and owned by a docshell's // mContentViewer. // 2) The content viewer is still being displayed while we begin loading - // a new document. The content viewer is owned by the _new_ + // a new document. The content viewer is owned by the _new_ // content viewer's mPreviousViewer, and has a pointer to the - // nsISHEntry where it will eventually be stored. The content viewer + // nsISHEntry where it will eventually be stored. The content viewer // has been close()d by the docshell, which detaches the document from // the window object. - // 3) The content viewer is cached in session history. The nsISHEntry - // has the only owning reference to the content viewer. The viewer + // 3) The content viewer is cached in session history. The nsISHEntry + // has the only owning reference to the content viewer. The viewer // has released its nsISHEntry pointer to prevent circular ownership. // // When restoring a content viewer from session history, open() is called - // to reattach the document to the window object. The content viewer is + // to reattach the document to the window object. The content viewer is // then placed into mContentViewer and removed from the history entry. // (mContentViewer is put into session history as described above, if // applicable). // Determines whether we can safely cache the current mContentViewer in - // session history. This checks a number of factors such as cache policy, + // session history. This checks a number of factors such as cache policy, // pending requests, and unload handlers. // |aLoadType| should be the load type that will replace the current - // presentation. |aNewRequest| should be the request for the document to + // presentation. |aNewRequest| should be the request for the document to // be loaded in place of the current document, or null if such a request // has not been created yet. |aNewDocument| should be the document that will // replace the current document. @@ -662,7 +650,7 @@ protected: int32_t* aHeight); // Call this when a URI load is handed to us (via OnLinkClick or - // InternalLoad). This makes sure that we're not inside unload, or that if + // InternalLoad). This makes sure that we're not inside unload, or that if // we are it's still OK to load this URI. bool IsOKToLoadURI(nsIURI* aURI); @@ -680,7 +668,7 @@ protected: bool ShouldBlockLoadingForBackButton(); - // Convenience method for getting our parent docshell. Can return null + // Convenience method for getting our parent docshell. Can return null already_AddRefed GetParentDocshell(); // Check if we have an app redirect registered for the URI and redirect if @@ -788,7 +776,7 @@ protected: nsCOMPtr mLSHE; // Holds a weak pointer to a RestorePresentationEvent object if any that - // holds a weak pointer back to us. We use this pointer to possibly revoke + // holds a weak pointer back to us. We use this pointer to possibly revoke // the event whenever necessary. nsRevocableEventPtr mRestorePresentationEvent; @@ -801,9 +789,9 @@ protected: // Secure browser UI object nsCOMPtr mSecurityUI; - // The URI we're currently loading. This is only relevant during the - // firing of a pagehide/unload. The caller of FirePageHideNotification() - // is responsible for setting it and unsetting it. It may be null if the + // The URI we're currently loading. This is only relevant during the + // firing of a pagehide/unload. The caller of FirePageHideNotification() + // is responsible for setting it and unsetting it. It may be null if the // pagehide/unload is happening for some reason other than just loading a // new URI. nsCOMPtr mLoadingURI; @@ -824,11 +812,11 @@ protected: nsCOMPtr mMixedContentChannel; // WEAK REFERENCES BELOW HERE. - // Note these are intentionally not addrefd. Doing so will create a cycle. + // Note these are intentionally not addrefd. Doing so will create a cycle. // For that reasons don't use nsCOMPtr. nsIDocShellTreeOwner* mTreeOwner; // Weak Reference - mozilla::dom::EventTarget* mChromeEventHandler; //Weak Reference + mozilla::dom::EventTarget* mChromeEventHandler; // Weak Reference eCharsetReloadState mCharsetReloadState; @@ -842,7 +830,7 @@ protected: int32_t mMarginWidth; int32_t mMarginHeight; - // This can either be a content docshell or a chrome docshell. After + // This can either be a content docshell or a chrome docshell. After // Create() is called, the type is not expected to change. int32_t mItemType; @@ -910,7 +898,7 @@ protected: void RecomputeCanExecuteScripts(); // This boolean is set to true right before we fire pagehide and generally - // unset when we embed a new content viewer. While it's true no navigation + // unset when we embed a new content viewer. While it's true no navigation // is allowed in this docshell. bool mFiredUnloadEvent; @@ -957,7 +945,7 @@ protected: FrameType mFrameType; // We only expect mOwnOrContainingAppId to be something other than - // UNKNOWN_APP_ID if mFrameType != eFrameTypeRegular. For vanilla iframes + // UNKNOWN_APP_ID if mFrameType != eFrameTypeRegular. For vanilla iframes // inside an app, we'll retrieve the containing app-id by walking up the // docshell hierarchy. // diff --git a/docshell/base/nsDocShellEditorData.h b/docshell/base/nsDocShellEditorData.h index 53036b98e6d..272190503cc 100644 --- a/docshell/base/nsDocShellEditorData.h +++ b/docshell/base/nsDocShellEditorData.h @@ -58,7 +58,6 @@ protected: // Backup for the corresponding nsIHTMLDocument's editing state while // the editor is detached. nsIHTMLDocument::EditingState mDetachedEditingState; - }; #endif // nsDocShellEditorData_h__ diff --git a/docshell/base/nsDocShellEnumerator.h b/docshell/base/nsDocShellEnumerator.h index a299aa0f350..87de74f0f77 100644 --- a/docshell/base/nsDocShellEnumerator.h +++ b/docshell/base/nsDocShellEnumerator.h @@ -89,7 +89,6 @@ public: protected: virtual nsresult BuildArrayRecursive(nsIDocShellTreeItem* aItem, nsTArray& aItemArray); - }; class nsDocShellBackwardsEnumerator : public nsDocShellEnumerator diff --git a/docshell/base/nsDocShellLoadInfo.cpp b/docshell/base/nsDocShellLoadInfo.cpp index a81884687f6..5f2bf2d55f1 100644 --- a/docshell/base/nsDocShellLoadInfo.cpp +++ b/docshell/base/nsDocShellLoadInfo.cpp @@ -4,7 +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/. */ -// Local Includes #include "nsDocShellLoadInfo.h" #include "nsISHEntry.h" #include "nsIInputStream.h" @@ -12,10 +11,6 @@ #include "nsIDocShell.h" #include "mozilla/net/ReferrerPolicy.h" -//***************************************************************************** -//*** nsDocShellLoadInfo: Object Management -//***************************************************************************** - nsDocShellLoadInfo::nsDocShellLoadInfo() : mInheritOwner(false) , mOwnerIsExplicit(false) @@ -30,10 +25,6 @@ nsDocShellLoadInfo::~nsDocShellLoadInfo() { } -//***************************************************************************** -// nsDocShellLoadInfo::nsISupports -//***************************************************************************** - NS_IMPL_ADDREF(nsDocShellLoadInfo) NS_IMPL_RELEASE(nsDocShellLoadInfo) @@ -42,10 +33,6 @@ NS_INTERFACE_MAP_BEGIN(nsDocShellLoadInfo) NS_INTERFACE_MAP_ENTRY(nsIDocShellLoadInfo) NS_INTERFACE_MAP_END -//***************************************************************************** -// nsDocShellLoadInfo::nsIDocShellLoadInfo -//***************************************************************************** - NS_IMETHODIMP nsDocShellLoadInfo::GetReferrer(nsIURI** aReferrer) { diff --git a/docshell/base/nsDocShellLoadTypes.h b/docshell/base/nsDocShellLoadTypes.h index 518df7d1019..273dd87b0d6 100644 --- a/docshell/base/nsDocShellLoadTypes.h +++ b/docshell/base/nsDocShellLoadTypes.h @@ -27,8 +27,8 @@ * above 0xffff (e.g. LOAD_FLAGS_BYPASS_CLASSIFIER), since MAKE_LOAD_TYPE would * just shift them out anyway. */ -#define EXTRA_LOAD_FLAGS (LOAD_FLAGS_FIRST_LOAD | \ - LOAD_FLAGS_ALLOW_POPUPS | \ +#define EXTRA_LOAD_FLAGS (LOAD_FLAGS_FIRST_LOAD | \ + LOAD_FLAGS_ALLOW_POPUPS | \ 0xffff0000) /* load types are legal combinations of load commands and flags @@ -65,7 +65,8 @@ enum LoadType * Docshell. Instead, Docshell triggers the load itself when a * consumer-triggered load failed. */ - LOAD_ERROR_PAGE = MAKE_LOAD_TYPE(nsIDocShell::LOAD_CMD_NORMAL, LOAD_FLAGS_ERROR_PAGE) + LOAD_ERROR_PAGE = MAKE_LOAD_TYPE(nsIDocShell::LOAD_CMD_NORMAL, + LOAD_FLAGS_ERROR_PAGE) // NOTE: Adding a new value? Remember to update IsValidLoadType! }; diff --git a/docshell/base/nsDocShellTransferableHooks.cpp b/docshell/base/nsDocShellTransferableHooks.cpp index 890bd05f6ca..441ade12873 100644 --- a/docshell/base/nsDocShellTransferableHooks.cpp +++ b/docshell/base/nsDocShellTransferableHooks.cpp @@ -17,10 +17,6 @@ nsTransferableHookData::~nsTransferableHookData() { } -//***************************************************************************** -// nsIClipboardDragDropHookList -//***************************************************************************** - NS_IMPL_ISUPPORTS(nsTransferableHookData, nsIClipboardDragDropHookList) NS_IMETHODIMP diff --git a/docshell/base/nsDownloadHistory.cpp b/docshell/base/nsDownloadHistory.cpp index 46005600903..32513ef0026 100644 --- a/docshell/base/nsDownloadHistory.cpp +++ b/docshell/base/nsDownloadHistory.cpp @@ -12,14 +12,8 @@ #include "nsIURI.h" #include "mozilla/Services.h" -//////////////////////////////////////////////////////////////////////////////// -//// nsDownloadHistory - NS_IMPL_ISUPPORTS(nsDownloadHistory, nsIDownloadHistory) -//////////////////////////////////////////////////////////////////////////////// -//// nsIDownloadHistory - NS_IMETHODIMP nsDownloadHistory::AddDownload(nsIURI* aSource, nsIURI* aReferrer, @@ -42,8 +36,7 @@ nsDownloadHistory::AddDownload(nsIURI* aSource, NS_ENSURE_SUCCESS(rv, rv); if (!visited) { - nsCOMPtr os = - mozilla::services::GetObserverService(); + nsCOMPtr os = mozilla::services::GetObserverService(); if (os) { os->NotifyObservers(aSource, NS_LINK_VISITED_EVENT_TOPIC, nullptr); } diff --git a/docshell/base/nsILinkHandler.h b/docshell/base/nsILinkHandler.h index 797b3fe1340..7cdcd566dfa 100644 --- a/docshell/base/nsILinkHandler.h +++ b/docshell/base/nsILinkHandler.h @@ -14,7 +14,6 @@ class nsIDocShell; class nsIInputStream; class nsIRequest; -// Interface ID for nsILinkHandler #define NS_ILINKHANDLER_IID \ { 0xceb9aade, 0x43da, 0x4f1a, \ { 0xac, 0x8a, 0xc7, 0x09, 0xfb, 0x22, 0x46, 0x64 } } diff --git a/docshell/base/nsIWebShellServices.h b/docshell/base/nsIWebShellServices.h index 2781da289a3..c67de0ff72f 100644 --- a/docshell/base/nsIWebShellServices.h +++ b/docshell/base/nsIWebShellServices.h @@ -9,20 +9,16 @@ #include "nsISupports.h" #include "nsCharsetSource.h" -// Interface ID for nsIWebShellServices - /* 0c628af0-5638-4703-8f99-ed6134c9de18 */ #define NS_IWEB_SHELL_SERVICES_IID \ { 0x0c628af0, 0x5638, 0x4703, {0x8f, 0x99, 0xed, 0x61, 0x34, 0xc9, 0xde, 0x18} } -//---------------------------------------------------------------------- - class nsIWebShellServices : public nsISupports { public: NS_DECLARE_STATIC_IID_ACCESSOR(NS_IWEB_SHELL_SERVICES_IID) - NS_IMETHOD ReloadDocument(const char* aCharset = nullptr , + NS_IMETHOD ReloadDocument(const char* aCharset = nullptr, int32_t aSource = kCharsetUninitialized) = 0; NS_IMETHOD StopDocumentLoad(void) = 0; }; diff --git a/docshell/base/nsWebNavigationInfo.h b/docshell/base/nsWebNavigationInfo.h index 430fb95aa84..2b54156f7ed 100644 --- a/docshell/base/nsWebNavigationInfo.h +++ b/docshell/base/nsWebNavigationInfo.h @@ -14,7 +14,6 @@ class nsCString; -// Class ID for webnavigationinfo #define NS_WEBNAVIGATION_INFO_CID \ { 0xf30bc0a2, 0x958b, 0x4287,{0xbf, 0x62, 0xce, 0x38, 0xba, 0x0c, 0x81, 0x1e}} diff --git a/docshell/build/nsDocShellCID.h b/docshell/build/nsDocShellCID.h index 6049688f4d9..35432ee1b51 100644 --- a/docshell/build/nsDocShellCID.h +++ b/docshell/build/nsDocShellCID.h @@ -7,8 +7,7 @@ #ifndef nsDocShellCID_h__ #define nsDocShellCID_h__ -#define NS_GLOBALHISTORY2_CONTRACTID \ - "@mozilla.org/browser/global-history;2" +#define NS_GLOBALHISTORY2_CONTRACTID "@mozilla.org/browser/global-history;2" /** * A contract for a service that will track download history. This can be @@ -17,16 +16,14 @@ * * @implements nsIDownloadHistory */ -#define NS_DOWNLOADHISTORY_CONTRACTID \ - "@mozilla.org/browser/download-history;1" +#define NS_DOWNLOADHISTORY_CONTRACTID "@mozilla.org/browser/download-history;1" /** * A contract that can be used to get a service that provides * meta-information about nsIWebNavigation objects' capabilities. * @implements nsIWebNavigationInfo */ -#define NS_WEBNAVIGATION_INFO_CONTRACTID \ - "@mozilla.org/webnavigation-info;1" +#define NS_WEBNAVIGATION_INFO_CONTRACTID "@mozilla.org/webnavigation-info;1" /** * Class and contract ID for the docshell. This is the container for a web @@ -34,9 +31,9 @@ * exact ones keep changing; if they stabilize somewhat that will get * documented. */ -#define NS_DOCSHELL_CID \ - { 0xf1eac762, 0x87e9, 0x11d3, \ - { 0xaf, 0x80, 0x00, 0xa0, 0x24, 0xff, 0xc0, 0x8c } } +#define NS_DOCSHELL_CID \ + { 0xf1eac762, 0x87e9, 0x11d3, \ + { 0xaf, 0x80, 0x00, 0xa0, 0x24, 0xff, 0xc0, 0x8c } } #define NS_DOCSHELL_CONTRACTID "@mozilla.org/docshell/html;1" /** @@ -51,7 +48,8 @@ * * @implements nsIExternalURLHandlerService */ -#define NS_EXTERNALURLHANDLERSERVICE_CONTRACTID "@mozilla.org/uriloader/external-url-handler-service;1" +#define NS_EXTERNALURLHANDLERSERVICE_CONTRACTID \ + "@mozilla.org/uriloader/external-url-handler-service;1" /** * An observer service topic that can be listened to to catch creation diff --git a/docshell/build/nsDocShellModule.cpp b/docshell/build/nsDocShellModule.cpp index 790b0b8c2bf..d75286e7bd9 100644 --- a/docshell/build/nsDocShellModule.cpp +++ b/docshell/build/nsDocShellModule.cpp @@ -23,7 +23,7 @@ #include "nsLocalHandlerApp.h" #ifdef MOZ_ENABLE_DBUS #include "nsDBusHandlerApp.h" -#endif +#endif #if defined(MOZ_WIDGET_ANDROID) #include "nsExternalSharingAppService.h" #include "nsExternalURLHandlerService.h" @@ -81,7 +81,7 @@ NS_GENERIC_FACTORY_CONSTRUCTOR(nsOfflineCacheUpdate) NS_GENERIC_FACTORY_CONSTRUCTOR(PlatformLocalHandlerApp_t) #ifdef MOZ_ENABLE_DBUS NS_GENERIC_FACTORY_CONSTRUCTOR(nsDBusHandlerApp) -#endif +#endif #if defined(MOZ_WIDGET_ANDROID) NS_GENERIC_FACTORY_CONSTRUCTOR(nsExternalSharingAppService) NS_GENERIC_FACTORY_CONSTRUCTOR(nsExternalURLHandlerService) @@ -120,7 +120,6 @@ NS_DEFINE_NAMED_CID(NS_SHISTORY_CID); NS_DEFINE_NAMED_CID(NS_SHISTORY_INTERNAL_CID); NS_DEFINE_NAMED_CID(NS_DOWNLOADHISTORY_CID); - const mozilla::Module::CIDEntry kDocShellCIDs[] = { { &kNS_DOCSHELL_CID, false, nullptr, nsDocShellConstructor }, { &kNS_DEFAULTURIFIXUP_CID, false, nullptr, nsDefaultURIFixupConstructor }, diff --git a/docshell/shistory/src/nsSHEntry.cpp b/docshell/shistory/src/nsSHEntry.cpp index 065d8898be2..baf30539632 100644 --- a/docshell/shistory/src/nsSHEntry.cpp +++ b/docshell/shistory/src/nsSHEntry.cpp @@ -3,7 +3,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/. */ -// Local Includes #include "nsSHEntry.h" #include "nsIDocShellLoadInfo.h" #include "nsIDocShellTreeItem.h" @@ -22,13 +21,9 @@ namespace dom = mozilla::dom; static uint32_t gEntryID = 0; -//***************************************************************************** -//*** nsSHEntry: Object Management -//***************************************************************************** - - nsSHEntry::nsSHEntry() - : mReferrerPolicy(mozilla::net::RP_Default) + : mShared(new nsSHEntryShared()) + , mReferrerPolicy(mozilla::net::RP_Default) , mLoadType(0) , mID(gEntryID++) , mScrollPositionX(0) @@ -37,26 +32,25 @@ nsSHEntry::nsSHEntry() , mURIWasModified(false) , mIsSrcdocEntry(false) { - mShared = new nsSHEntryShared(); } -nsSHEntry::nsSHEntry(const nsSHEntry &other) - : mShared(other.mShared) - , mURI(other.mURI) - , mReferrerURI(other.mReferrerURI) - , mReferrerPolicy(other.mReferrerPolicy) - , mTitle(other.mTitle) - , mPostData(other.mPostData) +nsSHEntry::nsSHEntry(const nsSHEntry& aOther) + : mShared(aOther.mShared) + , mURI(aOther.mURI) + , mReferrerURI(aOther.mReferrerURI) + , mReferrerPolicy(aOther.mReferrerPolicy) + , mTitle(aOther.mTitle) + , mPostData(aOther.mPostData) , mLoadType(0) // XXX why not copy? - , mID(other.mID) + , mID(aOther.mID) , mScrollPositionX(0) // XXX why not copy? , mScrollPositionY(0) // XXX why not copy? - , mParent(other.mParent) - , mURIWasModified(other.mURIWasModified) - , mStateData(other.mStateData) - , mIsSrcdocEntry(other.mIsSrcdocEntry) - , mSrcdocData(other.mSrcdocData) - , mBaseURI(other.mBaseURI) + , mParent(aOther.mParent) + , mURIWasModified(aOther.mURIWasModified) + , mStateData(aOther.mStateData) + , mIsSrcdocEntry(aOther.mIsSrcdocEntry) + , mSrcdocData(aOther.mSrcdocData) + , mBaseURI(aOther.mBaseURI) { } @@ -75,88 +69,90 @@ nsSHEntry::~nsSHEntry() mChildren.EnumerateForwards(ClearParentPtr, nullptr); } -//***************************************************************************** -// nsSHEntry: nsISupports -//***************************************************************************** - NS_IMPL_ISUPPORTS(nsSHEntry, nsISHContainer, nsISHEntry, nsISHEntryInternal) -//***************************************************************************** -// nsSHEntry: nsISHEntry -//***************************************************************************** - -NS_IMETHODIMP nsSHEntry::SetScrollPosition(int32_t x, int32_t y) +NS_IMETHODIMP +nsSHEntry::SetScrollPosition(int32_t aX, int32_t aY) { - mScrollPositionX = x; - mScrollPositionY = y; + mScrollPositionX = aX; + mScrollPositionY = aY; return NS_OK; } -NS_IMETHODIMP nsSHEntry::GetScrollPosition(int32_t *x, int32_t *y) +NS_IMETHODIMP +nsSHEntry::GetScrollPosition(int32_t* aX, int32_t* aY) { - *x = mScrollPositionX; - *y = mScrollPositionY; + *aX = mScrollPositionX; + *aY = mScrollPositionY; return NS_OK; } -NS_IMETHODIMP nsSHEntry::GetURIWasModified(bool* aOut) +NS_IMETHODIMP +nsSHEntry::GetURIWasModified(bool* aOut) { *aOut = mURIWasModified; return NS_OK; } -NS_IMETHODIMP nsSHEntry::SetURIWasModified(bool aIn) +NS_IMETHODIMP +nsSHEntry::SetURIWasModified(bool aIn) { mURIWasModified = aIn; return NS_OK; } -NS_IMETHODIMP nsSHEntry::GetURI(nsIURI** aURI) +NS_IMETHODIMP +nsSHEntry::GetURI(nsIURI** aURI) { *aURI = mURI; NS_IF_ADDREF(*aURI); return NS_OK; } -NS_IMETHODIMP nsSHEntry::SetURI(nsIURI* aURI) +NS_IMETHODIMP +nsSHEntry::SetURI(nsIURI* aURI) { mURI = aURI; return NS_OK; } -NS_IMETHODIMP nsSHEntry::GetReferrerURI(nsIURI **aReferrerURI) +NS_IMETHODIMP +nsSHEntry::GetReferrerURI(nsIURI** aReferrerURI) { *aReferrerURI = mReferrerURI; NS_IF_ADDREF(*aReferrerURI); return NS_OK; } -NS_IMETHODIMP nsSHEntry::SetReferrerURI(nsIURI *aReferrerURI) +NS_IMETHODIMP +nsSHEntry::SetReferrerURI(nsIURI* aReferrerURI) { mReferrerURI = aReferrerURI; return NS_OK; } -NS_IMETHODIMP nsSHEntry::GetReferrerPolicy(uint32_t *aReferrerPolicy) +NS_IMETHODIMP +nsSHEntry::GetReferrerPolicy(uint32_t* aReferrerPolicy) { *aReferrerPolicy = mReferrerPolicy; return NS_OK; } -NS_IMETHODIMP nsSHEntry::SetReferrerPolicy(uint32_t aReferrerPolicy) +NS_IMETHODIMP +nsSHEntry::SetReferrerPolicy(uint32_t aReferrerPolicy) { mReferrerPolicy = aReferrerPolicy; return NS_OK; } NS_IMETHODIMP -nsSHEntry::SetContentViewer(nsIContentViewer *aViewer) +nsSHEntry::SetContentViewer(nsIContentViewer* aViewer) { return mShared->SetContentViewer(aViewer); } NS_IMETHODIMP -nsSHEntry::GetContentViewer(nsIContentViewer **aResult) +nsSHEntry::GetContentViewer(nsIContentViewer** aResult) { *aResult = mShared->mContentViewer; NS_IF_ADDREF(*aResult); @@ -164,15 +160,15 @@ nsSHEntry::GetContentViewer(nsIContentViewer **aResult) } NS_IMETHODIMP -nsSHEntry::GetAnyContentViewer(nsISHEntry **aOwnerEntry, - nsIContentViewer **aResult) +nsSHEntry::GetAnyContentViewer(nsISHEntry** aOwnerEntry, + nsIContentViewer** aResult) { // Find a content viewer in the root node or any of its children, // assuming that there is only one content viewer total in any one // nsSHEntry tree GetContentViewer(aResult); if (*aResult) { -#ifdef DEBUG_PAGE_CACHE +#ifdef DEBUG_PAGE_CACHE printf("Found content viewer\n"); #endif *aOwnerEntry = this; @@ -203,124 +199,142 @@ nsSHEntry::SetSticky(bool aSticky) } NS_IMETHODIMP -nsSHEntry::GetSticky(bool *aSticky) +nsSHEntry::GetSticky(bool* aSticky) { *aSticky = mShared->mSticky; return NS_OK; } -NS_IMETHODIMP nsSHEntry::GetTitle(char16_t** aTitle) +NS_IMETHODIMP +nsSHEntry::GetTitle(char16_t** aTitle) { // Check for empty title... if (mTitle.IsEmpty() && mURI) { // Default title is the URL. nsAutoCString spec; - if (NS_SUCCEEDED(mURI->GetSpec(spec))) + if (NS_SUCCEEDED(mURI->GetSpec(spec))) { AppendUTF8toUTF16(spec, mTitle); + } } *aTitle = ToNewUnicode(mTitle); return NS_OK; } -NS_IMETHODIMP nsSHEntry::SetTitle(const nsAString &aTitle) +NS_IMETHODIMP +nsSHEntry::SetTitle(const nsAString& aTitle) { mTitle = aTitle; return NS_OK; } -NS_IMETHODIMP nsSHEntry::GetPostData(nsIInputStream** aResult) +NS_IMETHODIMP +nsSHEntry::GetPostData(nsIInputStream** aResult) { *aResult = mPostData; NS_IF_ADDREF(*aResult); return NS_OK; } -NS_IMETHODIMP nsSHEntry::SetPostData(nsIInputStream* aPostData) +NS_IMETHODIMP +nsSHEntry::SetPostData(nsIInputStream* aPostData) { mPostData = aPostData; return NS_OK; } -NS_IMETHODIMP nsSHEntry::GetLayoutHistoryState(nsILayoutHistoryState** aResult) +NS_IMETHODIMP +nsSHEntry::GetLayoutHistoryState(nsILayoutHistoryState** aResult) { *aResult = mShared->mLayoutHistoryState; NS_IF_ADDREF(*aResult); return NS_OK; } -NS_IMETHODIMP nsSHEntry::SetLayoutHistoryState(nsILayoutHistoryState* aState) +NS_IMETHODIMP +nsSHEntry::SetLayoutHistoryState(nsILayoutHistoryState* aState) { mShared->mLayoutHistoryState = aState; if (mShared->mLayoutHistoryState) { - mShared->mLayoutHistoryState-> - SetScrollPositionOnly(!mShared->mSaveLayoutState); + mShared->mLayoutHistoryState->SetScrollPositionOnly( + !mShared->mSaveLayoutState); } return NS_OK; } -NS_IMETHODIMP nsSHEntry::GetLoadType(uint32_t * aResult) +NS_IMETHODIMP +nsSHEntry::GetLoadType(uint32_t* aResult) { *aResult = mLoadType; return NS_OK; } -NS_IMETHODIMP nsSHEntry::SetLoadType(uint32_t aLoadType) +NS_IMETHODIMP +nsSHEntry::SetLoadType(uint32_t aLoadType) { mLoadType = aLoadType; return NS_OK; } -NS_IMETHODIMP nsSHEntry::GetID(uint32_t * aResult) +NS_IMETHODIMP +nsSHEntry::GetID(uint32_t* aResult) { *aResult = mID; return NS_OK; } -NS_IMETHODIMP nsSHEntry::SetID(uint32_t aID) +NS_IMETHODIMP +nsSHEntry::SetID(uint32_t aID) { mID = aID; return NS_OK; } -nsSHEntryShared* nsSHEntry::GetSharedState() +nsSHEntryShared* +nsSHEntry::GetSharedState() { return mShared; } -NS_IMETHODIMP nsSHEntry::GetIsSubFrame(bool * aFlag) +NS_IMETHODIMP +nsSHEntry::GetIsSubFrame(bool* aFlag) { *aFlag = mShared->mIsFrameNavigation; return NS_OK; } -NS_IMETHODIMP nsSHEntry::SetIsSubFrame(bool aFlag) +NS_IMETHODIMP +nsSHEntry::SetIsSubFrame(bool aFlag) { mShared->mIsFrameNavigation = aFlag; return NS_OK; } -NS_IMETHODIMP nsSHEntry::GetCacheKey(nsISupports** aResult) +NS_IMETHODIMP +nsSHEntry::GetCacheKey(nsISupports** aResult) { *aResult = mShared->mCacheKey; NS_IF_ADDREF(*aResult); return NS_OK; } -NS_IMETHODIMP nsSHEntry::SetCacheKey(nsISupports* aCacheKey) +NS_IMETHODIMP +nsSHEntry::SetCacheKey(nsISupports* aCacheKey) { mShared->mCacheKey = aCacheKey; return NS_OK; } -NS_IMETHODIMP nsSHEntry::GetSaveLayoutStateFlag(bool * aFlag) +NS_IMETHODIMP +nsSHEntry::GetSaveLayoutStateFlag(bool* aFlag) { *aFlag = mShared->mSaveLayoutState; return NS_OK; } -NS_IMETHODIMP nsSHEntry::SetSaveLayoutStateFlag(bool aFlag) +NS_IMETHODIMP +nsSHEntry::SetSaveLayoutStateFlag(bool aFlag) { mShared->mSaveLayoutState = aFlag; if (mShared->mLayoutHistoryState) { @@ -330,44 +344,48 @@ NS_IMETHODIMP nsSHEntry::SetSaveLayoutStateFlag(bool aFlag) return NS_OK; } -NS_IMETHODIMP nsSHEntry::GetExpirationStatus(bool * aFlag) +NS_IMETHODIMP +nsSHEntry::GetExpirationStatus(bool* aFlag) { *aFlag = mShared->mExpired; return NS_OK; } -NS_IMETHODIMP nsSHEntry::SetExpirationStatus(bool aFlag) +NS_IMETHODIMP +nsSHEntry::SetExpirationStatus(bool aFlag) { mShared->mExpired = aFlag; return NS_OK; } -NS_IMETHODIMP nsSHEntry::GetContentType(nsACString& aContentType) +NS_IMETHODIMP +nsSHEntry::GetContentType(nsACString& aContentType) { aContentType = mShared->mContentType; return NS_OK; } -NS_IMETHODIMP nsSHEntry::SetContentType(const nsACString& aContentType) +NS_IMETHODIMP +nsSHEntry::SetContentType(const nsACString& aContentType) { mShared->mContentType = aContentType; return NS_OK; } NS_IMETHODIMP -nsSHEntry::Create(nsIURI * aURI, const nsAString &aTitle, - nsIInputStream * aInputStream, - nsILayoutHistoryState * aLayoutHistoryState, - nsISupports * aCacheKey, const nsACString& aContentType, - nsISupports* aOwner, - uint64_t aDocShellID, bool aDynamicCreation) +nsSHEntry::Create(nsIURI* aURI, const nsAString& aTitle, + nsIInputStream* aInputStream, + nsILayoutHistoryState* aLayoutHistoryState, + nsISupports* aCacheKey, const nsACString& aContentType, + nsISupports* aOwner, uint64_t aDocShellID, + bool aDynamicCreation) { mURI = aURI; mTitle = aTitle; mPostData = aInputStream; // Set the LoadType by default to loadHistory during creation - mLoadType = (uint32_t) nsIDocShellLoadInfo::loadHistory; + mLoadType = (uint32_t)nsIDocShellLoadInfo::loadHistory; mShared->mCacheKey = aCacheKey; mShared->mContentType = aContentType; @@ -375,7 +393,7 @@ nsSHEntry::Create(nsIURI * aURI, const nsAString &aTitle, mShared->mDocShellID = aDocShellID; mShared->mDynamicallyCreated = aDynamicCreation; - // By default all entries are set false for subframe flag. + // By default all entries are set false for subframe flag. // nsDocShell::CloneAndReplace() which creates entries for // all subframe navigations, sets the flag to true. mShared->mIsFrameNavigation = false; @@ -384,7 +402,7 @@ nsSHEntry::Create(nsIURI * aURI, const nsAString &aTitle, mShared->mSaveLayoutState = true; mShared->mLayoutHistoryState = aLayoutHistoryState; - //By default the page is not expired + // By default the page is not expired mShared->mExpired = false; mIsSrcdocEntry = false; @@ -394,7 +412,7 @@ nsSHEntry::Create(nsIURI * aURI, const nsAString &aTitle, } NS_IMETHODIMP -nsSHEntry::Clone(nsISHEntry ** aResult) +nsSHEntry::Clone(nsISHEntry** aResult) { *aResult = new nsSHEntry(*this); NS_ADDREF(*aResult); @@ -402,7 +420,7 @@ nsSHEntry::Clone(nsISHEntry ** aResult) } NS_IMETHODIMP -nsSHEntry::GetParent(nsISHEntry ** aResult) +nsSHEntry::GetParent(nsISHEntry** aResult) { NS_ENSURE_ARG_POINTER(aResult); *aResult = mParent; @@ -411,7 +429,7 @@ nsSHEntry::GetParent(nsISHEntry ** aResult) } NS_IMETHODIMP -nsSHEntry::SetParent(nsISHEntry * aParent) +nsSHEntry::SetParent(nsISHEntry* aParent) { /* parent not Addrefed on purpose to avoid cyclic reference * Null parent is OK @@ -423,49 +441,49 @@ nsSHEntry::SetParent(nsISHEntry * aParent) } NS_IMETHODIMP -nsSHEntry::SetWindowState(nsISupports *aState) +nsSHEntry::SetWindowState(nsISupports* aState) { mShared->mWindowState = aState; return NS_OK; } NS_IMETHODIMP -nsSHEntry::GetWindowState(nsISupports **aState) +nsSHEntry::GetWindowState(nsISupports** aState) { NS_IF_ADDREF(*aState = mShared->mWindowState); return NS_OK; } NS_IMETHODIMP -nsSHEntry::SetViewerBounds(const nsIntRect &aBounds) +nsSHEntry::SetViewerBounds(const nsIntRect& aBounds) { mShared->mViewerBounds = aBounds; return NS_OK; } NS_IMETHODIMP -nsSHEntry::GetViewerBounds(nsIntRect &aBounds) +nsSHEntry::GetViewerBounds(nsIntRect& aBounds) { aBounds = mShared->mViewerBounds; return NS_OK; } NS_IMETHODIMP -nsSHEntry::GetOwner(nsISupports **aOwner) +nsSHEntry::GetOwner(nsISupports** aOwner) { NS_IF_ADDREF(*aOwner = mShared->mOwner); return NS_OK; } NS_IMETHODIMP -nsSHEntry::SetOwner(nsISupports *aOwner) +nsSHEntry::SetOwner(nsISupports* aOwner) { mShared->mOwner = aOwner; return NS_OK; } NS_IMETHODIMP -nsSHEntry::GetBFCacheEntry(nsIBFCacheEntry **aEntry) +nsSHEntry::GetBFCacheEntry(nsIBFCacheEntry** aEntry) { NS_ENSURE_ARG_POINTER(aEntry); NS_IF_ADDREF(*aEntry = mShared); @@ -473,18 +491,18 @@ nsSHEntry::GetBFCacheEntry(nsIBFCacheEntry **aEntry) } bool -nsSHEntry::HasBFCacheEntry(nsIBFCacheEntry *aEntry) +nsSHEntry::HasBFCacheEntry(nsIBFCacheEntry* aEntry) { return static_cast(mShared) == aEntry; } NS_IMETHODIMP -nsSHEntry::AdoptBFCacheEntry(nsISHEntry *aEntry) +nsSHEntry::AdoptBFCacheEntry(nsISHEntry* aEntry) { nsCOMPtr shEntry = do_QueryInterface(aEntry); NS_ENSURE_STATE(shEntry); - nsSHEntryShared *shared = shEntry->GetSharedState(); + nsSHEntryShared* shared = shEntry->GetSharedState(); NS_ENSURE_STATE(shared); mShared = shared; @@ -492,11 +510,11 @@ nsSHEntry::AdoptBFCacheEntry(nsISHEntry *aEntry) } NS_IMETHODIMP -nsSHEntry::SharesDocumentWith(nsISHEntry *aEntry, bool *aOut) +nsSHEntry::SharesDocumentWith(nsISHEntry* aEntry, bool* aOut) { NS_ENSURE_ARG_POINTER(aOut); - nsCOMPtr internal = do_QueryInterface(aEntry); + nsCOMPtr internal = do_QueryInterface(aEntry); NS_ENSURE_STATE(internal); *aOut = mShared == internal->GetSharedState(); @@ -518,14 +536,14 @@ nsSHEntry::GetIsSrcdocEntry(bool* aIsSrcdocEntry) } NS_IMETHODIMP -nsSHEntry::GetSrcdocData(nsAString &aSrcdocData) +nsSHEntry::GetSrcdocData(nsAString& aSrcdocData) { aSrcdocData = mSrcdocData; return NS_OK; } NS_IMETHODIMP -nsSHEntry::SetSrcdocData(const nsAString &aSrcdocData) +nsSHEntry::SetSrcdocData(const nsAString& aSrcdocData) { mSrcdocData = aSrcdocData; mIsSrcdocEntry = true; @@ -533,7 +551,7 @@ nsSHEntry::SetSrcdocData(const nsAString &aSrcdocData) } NS_IMETHODIMP -nsSHEntry::GetBaseURI(nsIURI **aBaseURI) +nsSHEntry::GetBaseURI(nsIURI** aBaseURI) { *aBaseURI = mBaseURI; NS_IF_ADDREF(*aBaseURI); @@ -541,25 +559,21 @@ nsSHEntry::GetBaseURI(nsIURI **aBaseURI) } NS_IMETHODIMP -nsSHEntry::SetBaseURI(nsIURI *aBaseURI) +nsSHEntry::SetBaseURI(nsIURI* aBaseURI) { mBaseURI = aBaseURI; return NS_OK; } -//***************************************************************************** -// nsSHEntry: nsISHContainer -//***************************************************************************** - -NS_IMETHODIMP -nsSHEntry::GetChildCount(int32_t * aCount) +NS_IMETHODIMP +nsSHEntry::GetChildCount(int32_t* aCount) { *aCount = mChildren.Count(); return NS_OK; } NS_IMETHODIMP -nsSHEntry::AddChild(nsISHEntry * aChild, int32_t aOffset) +nsSHEntry::AddChild(nsISHEntry* aChild, int32_t aOffset) { if (aChild) { NS_ENSURE_SUCCESS(aChild->SetParent(this), NS_ERROR_FAILURE); @@ -579,7 +593,7 @@ nsSHEntry::AddChild(nsISHEntry * aChild, int32_t aOffset) // // Assert that aOffset will not be so high as to grow us a lot. // - NS_ASSERTION(aOffset < (mChildren.Count()+1023), "Large frames array!\n"); + NS_ASSERTION(aOffset < (mChildren.Count() + 1023), "Large frames array!\n"); bool newChildIsDyn = false; if (aChild) { @@ -634,7 +648,7 @@ nsSHEntry::AddChild(nsISHEntry * aChild, int32_t aOffset) } } } - + if (dynEntry) { nsCOMArray tmp; tmp.SetCount(aOffset - dynEntryIndex + 1); @@ -642,7 +656,6 @@ nsSHEntry::AddChild(nsISHEntry * aChild, int32_t aOffset) NS_ASSERTION(mChildren[aOffset + 1] == dynEntry, "Whaat?"); } } - // Make sure there isn't anything at aOffset. if (aOffset < mChildren.Count()) { @@ -664,7 +677,7 @@ nsSHEntry::AddChild(nsISHEntry * aChild, int32_t aOffset) } NS_IMETHODIMP -nsSHEntry::RemoveChild(nsISHEntry * aChild) +nsSHEntry::RemoveChild(nsISHEntry* aChild) { NS_ENSURE_TRUE(aChild, NS_ERROR_FAILURE); bool childRemoved = false; @@ -692,7 +705,7 @@ nsSHEntry::RemoveChild(nsISHEntry * aChild) } NS_IMETHODIMP -nsSHEntry::GetChildAt(int32_t aIndex, nsISHEntry ** aResult) +nsSHEntry::GetChildAt(int32_t aIndex, nsISHEntry** aResult) { if (aIndex >= 0 && aIndex < mChildren.Count()) { *aResult = mChildren[aIndex]; @@ -727,7 +740,7 @@ nsSHEntry::ReplaceChild(nsISHEntry* aNewEntry) } NS_IMETHODIMP -nsSHEntry::AddChildShell(nsIDocShellTreeItem *aShell) +nsSHEntry::AddChildShell(nsIDocShellTreeItem* aShell) { NS_ASSERTION(aShell, "Null child shell added to history entry"); mShared->mChildShells.AppendObject(aShell); @@ -735,7 +748,7 @@ nsSHEntry::AddChildShell(nsIDocShellTreeItem *aShell) } NS_IMETHODIMP -nsSHEntry::ChildShellAt(int32_t aIndex, nsIDocShellTreeItem **aShell) +nsSHEntry::ChildShellAt(int32_t aIndex, nsIDocShellTreeItem** aShell) { NS_IF_ADDREF(*aShell = mShared->mChildShells.SafeObjectAt(aIndex)); return NS_OK; @@ -749,14 +762,14 @@ nsSHEntry::ClearChildShells() } NS_IMETHODIMP -nsSHEntry::GetRefreshURIList(nsISupportsArray **aList) +nsSHEntry::GetRefreshURIList(nsISupportsArray** aList) { NS_IF_ADDREF(*aList = mShared->mRefreshURIList); return NS_OK; } NS_IMETHODIMP -nsSHEntry::SetRefreshURIList(nsISupportsArray *aList) +nsSHEntry::SetRefreshURIList(nsISupportsArray* aList) { mShared->mRefreshURIList = aList; return NS_OK; @@ -804,7 +817,7 @@ nsSHEntry::HasDetachedEditor() } NS_IMETHODIMP -nsSHEntry::GetStateData(nsIStructuredCloneContainer **aContainer) +nsSHEntry::GetStateData(nsIStructuredCloneContainer** aContainer) { NS_ENSURE_ARG_POINTER(aContainer); NS_IF_ADDREF(*aContainer = mStateData); @@ -812,7 +825,7 @@ nsSHEntry::GetStateData(nsIStructuredCloneContainer **aContainer) } NS_IMETHODIMP -nsSHEntry::SetStateData(nsIStructuredCloneContainer *aContainer) +nsSHEntry::SetStateData(nsIStructuredCloneContainer* aContainer) { mStateData = aContainer; return NS_OK; @@ -855,9 +868,8 @@ nsSHEntry::SetDocshellID(uint64_t aID) return NS_OK; } - NS_IMETHODIMP -nsSHEntry::GetLastTouched(uint32_t *aLastTouched) +nsSHEntry::GetLastTouched(uint32_t* aLastTouched) { *aLastTouched = mShared->mLastTouched; return NS_OK; diff --git a/docshell/shistory/src/nsSHEntry.h b/docshell/shistory/src/nsSHEntry.h index 19e3827faa4..ff771cc4e02 100644 --- a/docshell/shistory/src/nsSHEntry.h +++ b/docshell/shistory/src/nsSHEntry.h @@ -26,9 +26,9 @@ class nsSHEntry final : public nsISHEntry, public nsISHContainer, public nsISHEntryInternal { -public: +public: nsSHEntry(); - nsSHEntry(const nsSHEntry &other); + nsSHEntry(const nsSHEntry& aOther); NS_DECL_ISUPPORTS NS_DECL_NSISHENTRY @@ -39,7 +39,7 @@ public: static nsresult Startup(); static void Shutdown(); - + private: ~nsSHEntry(); @@ -48,22 +48,22 @@ private: nsRefPtr mShared; // See nsSHEntry.idl for comments on these members. - nsCOMPtr mURI; - nsCOMPtr mReferrerURI; - uint32_t mReferrerPolicy; - nsString mTitle; + nsCOMPtr mURI; + nsCOMPtr mReferrerURI; + uint32_t mReferrerPolicy; + nsString mTitle; nsCOMPtr mPostData; - uint32_t mLoadType; - uint32_t mID; - int32_t mScrollPositionX; - int32_t mScrollPositionY; - nsISHEntry* mParent; - nsCOMArray mChildren; - bool mURIWasModified; + uint32_t mLoadType; + uint32_t mID; + int32_t mScrollPositionX; + int32_t mScrollPositionY; + nsISHEntry* mParent; + nsCOMArray mChildren; + bool mURIWasModified; nsCOMPtr mStateData; - bool mIsSrcdocEntry; - nsString mSrcdocData; - nsCOMPtr mBaseURI; + bool mIsSrcdocEntry; + nsString mSrcdocData; + nsCOMPtr mBaseURI; }; #endif /* nsSHEntry_h */ diff --git a/docshell/shistory/src/nsSHEntryShared.cpp b/docshell/shistory/src/nsSHEntryShared.cpp index 2c3a6fedbba..c4aba9293b9 100644 --- a/docshell/shistory/src/nsSHEntryShared.cpp +++ b/docshell/shistory/src/nsSHEntryShared.cpp @@ -29,10 +29,11 @@ uint64_t gSHEntrySharedID = 0; #define CONTENT_VIEWER_TIMEOUT_SECONDS "browser.sessionhistory.contentViewerTimeout" // Default this to time out unused content viewers after 30 minutes -#define CONTENT_VIEWER_TIMEOUT_SECONDS_DEFAULT (30*60) +#define CONTENT_VIEWER_TIMEOUT_SECONDS_DEFAULT (30 * 60) typedef nsExpirationTracker HistoryTrackerBase; -class HistoryTracker final : public HistoryTrackerBase { +class HistoryTracker final : public HistoryTrackerBase +{ public: explicit HistoryTracker(uint32_t aTimeout) : HistoryTrackerBase(1000 * aTimeout / 2) @@ -40,13 +41,14 @@ public: } protected: - virtual void NotifyExpired(nsSHEntryShared *aObj) { + virtual void NotifyExpired(nsSHEntryShared* aObj) + { RemoveObject(aObj); aObj->Expire(); } }; -static HistoryTracker *gHistoryTracker = nullptr; +static HistoryTracker* gHistoryTracker = nullptr; void nsSHEntryShared::EnsureHistoryTracker() @@ -88,10 +90,9 @@ nsSHEntryShared::~nsSHEntryShared() if (gHistoryTracker) { // Check that we're not still on track to expire. We shouldn't be, because // we just removed ourselves! - nsExpirationTracker::Iterator - iterator(gHistoryTracker); + nsExpirationTracker::Iterator iterator(gHistoryTracker); - nsSHEntryShared *elem; + nsSHEntryShared* elem; while ((elem = iterator.Next()) != nullptr) { NS_ASSERTION(elem != this, "Found dead entry still in the tracker!"); } @@ -106,7 +107,7 @@ nsSHEntryShared::~nsSHEntryShared() NS_IMPL_ISUPPORTS(nsSHEntryShared, nsIBFCacheEntry, nsIMutationObserver) already_AddRefed -nsSHEntryShared::Duplicate(nsSHEntryShared *aEntry) +nsSHEntryShared::Duplicate(nsSHEntryShared* aEntry) { nsRefPtr newEntry = new nsSHEntryShared(); @@ -124,7 +125,8 @@ nsSHEntryShared::Duplicate(nsSHEntryShared *aEntry) return newEntry.forget(); } -void nsSHEntryShared::RemoveFromExpirationTracker() +void +nsSHEntryShared::RemoveFromExpirationTracker() { if (gHistoryTracker && GetExpirationState()->IsTracked()) { gHistoryTracker->RemoveObject(this); @@ -197,7 +199,7 @@ nsSHEntryShared::Expire() } nsresult -nsSHEntryShared::SetContentViewer(nsIContentViewer *aViewer) +nsSHEntryShared::SetContentViewer(nsIContentViewer* aViewer) { NS_PRECONDITION(!aViewer || !mContentViewer, "SHEntryShared already contains viewer"); @@ -229,8 +231,7 @@ nsSHEntryShared::SetContentViewer(nsIContentViewer *aViewer) nsresult nsSHEntryShared::RemoveFromBFCacheSync() { - NS_ASSERTION(mContentViewer && mDocument, - "we're not in the bfcache!"); + NS_ASSERTION(mContentViewer && mDocument, "we're not in the bfcache!"); nsCOMPtr viewer = mContentViewer; DropPresentationState(); @@ -249,9 +250,10 @@ class DestroyViewerEvent : public nsRunnable { public: DestroyViewerEvent(nsIContentViewer* aViewer, nsIDocument* aDocument) - : mViewer(aViewer), - mDocument(aDocument) - {} + : mViewer(aViewer) + , mDocument(aDocument) + { + } NS_IMETHOD Run() { @@ -268,14 +270,12 @@ public: nsresult nsSHEntryShared::RemoveFromBFCacheAsync() { - NS_ASSERTION(mContentViewer && mDocument, - "we're not in the bfcache!"); + NS_ASSERTION(mContentViewer && mDocument, "we're not in the bfcache!"); // Release the reference to the contentviewer asynchronously so that the // document doesn't get nuked mid-mutation. - nsCOMPtr evt = - new DestroyViewerEvent(mContentViewer, mDocument); + nsCOMPtr evt = new DestroyViewerEvent(mContentViewer, mDocument); nsresult rv = NS_DispatchToCurrentThread(evt); if (NS_FAILED(rv)) { NS_WARNING("failed to dispatch DestroyViewerEvent"); @@ -293,16 +293,12 @@ nsSHEntryShared::RemoveFromBFCacheAsync() } nsresult -nsSHEntryShared::GetID(uint64_t *aID) +nsSHEntryShared::GetID(uint64_t* aID) { *aID = mID; return NS_OK; } -//***************************************************************************** -// nsSHEntryShared: nsIMutationObserver -//***************************************************************************** - void nsSHEntryShared::NodeWillBeDestroyed(const nsINode* aNode) { @@ -372,6 +368,6 @@ nsSHEntryShared::ContentRemoved(nsIDocument* aDocument, } void -nsSHEntryShared::ParentChainChanged(nsIContent *aContent) +nsSHEntryShared::ParentChainChanged(nsIContent* aContent) { } diff --git a/docshell/shistory/src/nsSHEntryShared.h b/docshell/shistory/src/nsSHEntryShared.h index 6559fa51634..5b619201b02 100644 --- a/docshell/shistory/src/nsSHEntryShared.h +++ b/docshell/shistory/src/nsSHEntryShared.h @@ -30,64 +30,65 @@ class nsISupportsArray; // back/forward cache. // // nsSHEntryShared is the vehicle for this sharing. -class nsSHEntryShared final : public nsIBFCacheEntry, - public nsIMutationObserver +class nsSHEntryShared final + : public nsIBFCacheEntry + , public nsIMutationObserver { - public: - static void EnsureHistoryTracker(); - static void Shutdown(); +public: + static void EnsureHistoryTracker(); + static void Shutdown(); - nsSHEntryShared(); + nsSHEntryShared(); - NS_DECL_ISUPPORTS - NS_DECL_NSIMUTATIONOBSERVER - NS_DECL_NSIBFCACHEENTRY + NS_DECL_ISUPPORTS + NS_DECL_NSIMUTATIONOBSERVER + NS_DECL_NSIBFCACHEENTRY - private: - ~nsSHEntryShared(); +private: + ~nsSHEntryShared(); - friend class nsSHEntry; + friend class nsSHEntry; - friend class HistoryTracker; - friend class nsExpirationTracker; - nsExpirationState *GetExpirationState() { return &mExpirationState; } + friend class HistoryTracker; + friend class nsExpirationTracker; + nsExpirationState *GetExpirationState() { return &mExpirationState; } - static already_AddRefed Duplicate(nsSHEntryShared *aEntry); + static already_AddRefed Duplicate(nsSHEntryShared* aEntry); - void RemoveFromExpirationTracker(); - void Expire(); - nsresult SyncPresentationState(); - void DropPresentationState(); + void RemoveFromExpirationTracker(); + void Expire(); + nsresult SyncPresentationState(); + void DropPresentationState(); - nsresult SetContentViewer(nsIContentViewer *aViewer); + nsresult SetContentViewer(nsIContentViewer* aViewer); - // See nsISHEntry.idl for an explanation of these members. + // See nsISHEntry.idl for an explanation of these members. - // These members are copied by nsSHEntryShared::Duplicate(). If you add a - // member here, be sure to update the Duplicate() implementation. - uint64_t mDocShellID; - nsCOMArray mChildShells; - nsCOMPtr mOwner; - nsCString mContentType; - bool mIsFrameNavigation; - bool mSaveLayoutState; - bool mSticky; - bool mDynamicallyCreated; - nsCOMPtr mCacheKey; - uint32_t mLastTouched; + // These members are copied by nsSHEntryShared::Duplicate(). If you add a + // member here, be sure to update the Duplicate() implementation. + uint64_t mDocShellID; + nsCOMArray mChildShells; + nsCOMPtr mOwner; + nsCString mContentType; + bool mIsFrameNavigation; + bool mSaveLayoutState; + bool mSticky; + bool mDynamicallyCreated; + nsCOMPtr mCacheKey; + uint32_t mLastTouched; - // These members aren't copied by nsSHEntryShared::Duplicate() because - // they're specific to a particular content viewer. - uint64_t mID; - nsCOMPtr mContentViewer; - nsCOMPtr mDocument; - nsCOMPtr mLayoutHistoryState; - bool mExpired; - nsCOMPtr mWindowState; - nsIntRect mViewerBounds; - nsCOMPtr mRefreshURIList; - nsExpirationState mExpirationState; - nsAutoPtr mEditorData; + // These members aren't copied by nsSHEntryShared::Duplicate() because + // they're specific to a particular content viewer. + uint64_t mID; + nsCOMPtr mContentViewer; + nsCOMPtr mDocument; + nsCOMPtr mLayoutHistoryState; + bool mExpired; + nsCOMPtr mWindowState; + nsIntRect mViewerBounds; + nsCOMPtr mRefreshURIList; + nsExpirationState mExpirationState; + nsAutoPtr mEditorData; }; #endif diff --git a/docshell/shistory/src/nsSHTransaction.cpp b/docshell/shistory/src/nsSHTransaction.cpp index 1768a44efdd..71c42c14150 100644 --- a/docshell/shistory/src/nsSHTransaction.cpp +++ b/docshell/shistory/src/nsSHTransaction.cpp @@ -4,80 +4,66 @@ * 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/. */ -// Local Includes #include "nsSHTransaction.h" #include "nsISHEntry.h" -//***************************************************************************** -//*** nsSHTransaction: Object Management -//***************************************************************************** - -nsSHTransaction::nsSHTransaction() : mPersist(true), mPrev(nullptr) +nsSHTransaction::nsSHTransaction() + : mPersist(true) + , mPrev(nullptr) { } - nsSHTransaction::~nsSHTransaction() { } -//***************************************************************************** -// nsSHTransaction: nsISupports -//***************************************************************************** - NS_IMPL_ADDREF(nsSHTransaction) NS_IMPL_RELEASE(nsSHTransaction) NS_INTERFACE_MAP_BEGIN(nsSHTransaction) - NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsISHTransaction) - NS_INTERFACE_MAP_ENTRY(nsISHTransaction) + NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsISHTransaction) + NS_INTERFACE_MAP_ENTRY(nsISHTransaction) NS_INTERFACE_MAP_END -//***************************************************************************** -// nsSHTransaction: nsISHTransaction -//***************************************************************************** - NS_IMETHODIMP nsSHTransaction::Create(nsISHEntry* aSHEntry, nsISHTransaction* aPrev) { - SetSHEntry(aSHEntry); - if(aPrev) - aPrev->SetNext(this); + SetSHEntry(aSHEntry); + if (aPrev) { + aPrev->SetNext(this); + } - SetPrev(aPrev); - return NS_OK; + SetPrev(aPrev); + return NS_OK; } NS_IMETHODIMP -nsSHTransaction::GetSHEntry(nsISHEntry ** aResult) +nsSHTransaction::GetSHEntry(nsISHEntry** aResult) { - NS_ENSURE_ARG_POINTER(aResult); - *aResult = mSHEntry; - NS_IF_ADDREF(*aResult); - return NS_OK; + NS_ENSURE_ARG_POINTER(aResult); + *aResult = mSHEntry; + NS_IF_ADDREF(*aResult); + return NS_OK; } - NS_IMETHODIMP -nsSHTransaction::SetSHEntry(nsISHEntry * aSHEntry) +nsSHTransaction::SetSHEntry(nsISHEntry* aSHEntry) { - mSHEntry = aSHEntry; - return NS_OK; + mSHEntry = aSHEntry; + return NS_OK; } - NS_IMETHODIMP -nsSHTransaction::GetNext(nsISHTransaction * * aResult) +nsSHTransaction::GetNext(nsISHTransaction** aResult) { - NS_ENSURE_ARG_POINTER(aResult); - *aResult = mNext; - NS_IF_ADDREF(*aResult); - return NS_OK; + NS_ENSURE_ARG_POINTER(aResult); + *aResult = mNext; + NS_IF_ADDREF(*aResult); + return NS_OK; } - NS_IMETHODIMP -nsSHTransaction::SetNext(nsISHTransaction * aNext) +nsSHTransaction::SetNext(nsISHTransaction* aNext) { if (aNext) { NS_ENSURE_SUCCESS(aNext->SetPrev(this), NS_ERROR_FAILURE); @@ -88,34 +74,34 @@ nsSHTransaction::SetNext(nsISHTransaction * aNext) } NS_IMETHODIMP -nsSHTransaction::SetPrev(nsISHTransaction * aPrev) +nsSHTransaction::SetPrev(nsISHTransaction* aPrev) { - /* This is weak reference to parent. Do not Addref it */ - mPrev = aPrev; - return NS_OK; + /* This is weak reference to parent. Do not Addref it */ + mPrev = aPrev; + return NS_OK; } nsresult -nsSHTransaction::GetPrev(nsISHTransaction ** aResult) +nsSHTransaction::GetPrev(nsISHTransaction** aResult) { - NS_ENSURE_ARG_POINTER(aResult); - *aResult = mPrev; - NS_IF_ADDREF(*aResult); - return NS_OK; + NS_ENSURE_ARG_POINTER(aResult); + *aResult = mPrev; + NS_IF_ADDREF(*aResult); + return NS_OK; } NS_IMETHODIMP nsSHTransaction::SetPersist(bool aPersist) { - mPersist = aPersist; - return NS_OK; + mPersist = aPersist; + return NS_OK; } NS_IMETHODIMP nsSHTransaction::GetPersist(bool* aPersist) { - NS_ENSURE_ARG_POINTER(aPersist); + NS_ENSURE_ARG_POINTER(aPersist); - *aPersist = mPersist; - return NS_OK; + *aPersist = mPersist; + return NS_OK; } diff --git a/docshell/shistory/src/nsSHTransaction.h b/docshell/shistory/src/nsSHTransaction.h index 8c7ba2afd5c..c4c7d0763b1 100644 --- a/docshell/shistory/src/nsSHTransaction.h +++ b/docshell/shistory/src/nsSHTransaction.h @@ -15,25 +15,23 @@ class nsISHEntry; -class nsSHTransaction: public nsISHTransaction +class nsSHTransaction : public nsISHTransaction { public: - NS_DECL_ISUPPORTS - NS_DECL_NSISHTRANSACTION + NS_DECL_ISUPPORTS + NS_DECL_NSISHTRANSACTION - nsSHTransaction(); + nsSHTransaction(); protected: - virtual ~nsSHTransaction(); - + virtual ~nsSHTransaction(); protected: - bool mPersist; + bool mPersist; - nsISHTransaction * mPrev; // Weak Reference - nsCOMPtr mNext; - nsCOMPtr mSHEntry; + nsISHTransaction* mPrev; // Weak Reference + nsCOMPtr mNext; + nsCOMPtr mSHEntry; }; - -#endif /* nsSHTransaction_h */ +#endif /* nsSHTransaction_h */ diff --git a/docshell/shistory/src/nsSHistory.cpp b/docshell/shistory/src/nsSHistory.cpp index d8f104a02e8..ccf91bb1d26 100644 --- a/docshell/shistory/src/nsSHistory.cpp +++ b/docshell/shistory/src/nsSHistory.cpp @@ -4,7 +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/. */ -// Local Includes #include "nsSHistory.h" #include @@ -47,9 +46,9 @@ static const char* kObservedPrefs[] = { nullptr }; -static int32_t gHistoryMaxSize = 50; +static int32_t gHistoryMaxSize = 50; // Max viewers allowed per SHistory objects -static const int32_t gHistoryMaxViewers = 3; +static const int32_t gHistoryMaxViewers = 3; // List of all SHistory objects, used for content viewer cache eviction static PRCList gSHistoryList; // Max viewers allowed total, across all SHistory objects - negative default @@ -65,9 +64,10 @@ static uint32_t gTouchCounter = 0; static PRLogModuleInfo* GetSHistoryLog() { - static PRLogModuleInfo *sLog; - if (!sLog) + static PRLogModuleInfo* sLog; + if (!sLog) { sLog = PR_NewLogModule("nsSHistory"); + } return sLog; } #define LOG(format) PR_LOG(GetSHistoryLog(), PR_LOG_DEBUG, format) @@ -155,20 +155,16 @@ GetSHistoryLog() } \ PR_END_MACRO -enum HistCmd{ +enum HistCmd +{ HIST_CMD_BACK, HIST_CMD_FORWARD, HIST_CMD_GOTOINDEX, HIST_CMD_RELOAD -} ; - -//***************************************************************************** -//*** nsSHistoryObserver -//***************************************************************************** +}; class nsSHistoryObserver final : public nsIObserver { - public: NS_DECL_ISUPPORTS NS_DECL_NSIOBSERVER @@ -184,8 +180,8 @@ StaticRefPtr gObserver; NS_IMPL_ISUPPORTS(nsSHistoryObserver, nsIObserver) NS_IMETHODIMP -nsSHistoryObserver::Observe(nsISupports *aSubject, const char *aTopic, - const char16_t *aData) +nsSHistoryObserver::Observe(nsISupports* aSubject, const char* aTopic, + const char16_t* aData) { if (!strcmp(aTopic, NS_PREFBRANCH_PREFCHANGE_TOPIC_ID)) { nsSHistory::UpdatePrefs(); @@ -201,7 +197,7 @@ nsSHistoryObserver::Observe(nsISupports *aSubject, const char *aTopic, namespace { already_AddRefed -GetContentViewerForTransaction(nsISHTransaction *aTrans) +GetContentViewerForTransaction(nsISHTransaction* aTrans) { nsCOMPtr entry; aTrans->GetSHEntry(getter_AddRefs(entry)); @@ -217,7 +213,7 @@ GetContentViewerForTransaction(nsISHTransaction *aTrans) } void -EvictContentViewerForTransaction(nsISHTransaction *aTrans) +EvictContentViewerForTransaction(nsISHTransaction* aTrans) { nsCOMPtr entry; aTrans->GetSHEntry(getter_AddRefs(entry)); @@ -226,12 +222,12 @@ EvictContentViewerForTransaction(nsISHTransaction *aTrans) entry->GetAnyContentViewer(getter_AddRefs(ownerEntry), getter_AddRefs(viewer)); if (viewer) { - NS_ASSERTION(ownerEntry, - "Content viewer exists but its SHEntry is null"); + NS_ASSERTION(ownerEntry, "Content viewer exists but its SHEntry is null"); LOG_SHENTRY_SPEC(("Evicting content viewer 0x%p for " "owning SHEntry 0x%p at %s.", - viewer.get(), ownerEntry.get(), _spec), ownerEntry); + viewer.get(), ownerEntry.get(), _spec), + ownerEntry); // Drop the presentation state before destroying the viewer, so that // document teardown is able to correctly persist the state. @@ -243,41 +239,31 @@ EvictContentViewerForTransaction(nsISHTransaction *aTrans) } // anonymous namespace -//***************************************************************************** -//*** nsSHistory: Object Management -//***************************************************************************** - -nsSHistory::nsSHistory() : mListRoot(nullptr), mIndex(-1), mLength(0), mRequestedIndex(-1) +nsSHistory::nsSHistory() + : mIndex(-1) + , mLength(0) + , mRequestedIndex(-1) { // Add this new SHistory object to the list PR_APPEND_LINK(this, &gSHistoryList); } - nsSHistory::~nsSHistory() { // Remove this SHistory object from the list PR_REMOVE_LINK(this); } -//***************************************************************************** -// nsSHistory: nsISupports -//***************************************************************************** - NS_IMPL_ADDREF(nsSHistory) NS_IMPL_RELEASE(nsSHistory) NS_INTERFACE_MAP_BEGIN(nsSHistory) - NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsISHistory) - NS_INTERFACE_MAP_ENTRY(nsISHistory) - NS_INTERFACE_MAP_ENTRY(nsIWebNavigation) - NS_INTERFACE_MAP_ENTRY(nsISHistoryInternal) + NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsISHistory) + NS_INTERFACE_MAP_ENTRY(nsISHistory) + NS_INTERFACE_MAP_ENTRY(nsIWebNavigation) + NS_INTERFACE_MAP_ENTRY(nsISHistoryInternal) NS_INTERFACE_MAP_END -//***************************************************************************** -// nsSHistory: nsISHistory -//***************************************************************************** - // static uint32_t nsSHistory::CalcMaxTotalViewers() @@ -301,14 +287,16 @@ nsSHistory::CalcMaxTotalViewers() // 4096 Mb 8 uint64_t bytes = PR_GetPhysicalMemorySize(); - if (bytes == 0) + if (bytes == 0) { return 0; + } // Conversion from unsigned int64_t to double doesn't work on all platforms. // We need to truncate the value at INT64_MAX to make sure we don't // overflow. - if (bytes > INT64_MAX) + if (bytes > INT64_MAX) { bytes = INT64_MAX; + } double kBytesD = (double)(bytes >> 10); @@ -316,10 +304,10 @@ nsSHistory::CalcMaxTotalViewers() // except that we divide the final memory calculation by 4, since // we assume each ContentViewer takes on average 4MB uint32_t viewers = 0; - double x = std::log(kBytesD)/std::log(2.0) - 14; + double x = std::log(kBytesD) / std::log(2.0) - 14; if (x > 0) { - viewers = (uint32_t)(x * x - x + 2.001); // add .001 for rounding - viewers /= 4; + viewers = (uint32_t)(x * x - x + 2.001); // add .001 for rounding + viewers /= 4; } // Cap it off at 8 max @@ -356,7 +344,7 @@ nsSHistory::Startup() if (gHistoryMaxSize < defaultHistoryMaxSize) { gHistoryMaxSize = defaultHistoryMaxSize; } - + // Allow the user to override the max total number of cached viewers, // but keep the per SHistory cached viewer limit constant if (!gObserver) { @@ -368,8 +356,7 @@ nsSHistory::Startup() if (obsSvc) { // Observe empty-cache notifications so tahat clearing the disk/memory // cache will also evict all content viewers. - obsSvc->AddObserver(gObserver, - "cacheservice:empty-cache", false); + obsSvc->AddObserver(gObserver, "cacheservice:empty-cache", false); // Same for memory-pressure notifications obsSvc->AddObserver(gObserver, "memory-pressure", false); @@ -397,34 +384,36 @@ nsSHistory::Shutdown() } } -/* Add an entry to the History list at mIndex and +/* Add an entry to the History list at mIndex and * increment the index to point to the new entry */ NS_IMETHODIMP -nsSHistory::AddEntry(nsISHEntry * aSHEntry, bool aPersist) +nsSHistory::AddEntry(nsISHEntry* aSHEntry, bool aPersist) { NS_ENSURE_ARG(aSHEntry); nsCOMPtr currentTxn; - if(mListRoot) + if (mListRoot) { GetTransactionAtIndex(mIndex, getter_AddRefs(currentTxn)); + } bool currentPersist = true; - if(currentTxn) + if (currentTxn) { currentTxn->GetPersist(¤tPersist); + } int32_t currentIndex = mIndex; - if(!currentPersist) - { + if (!currentPersist) { NOTIFY_LISTENERS(OnHistoryReplaceEntry, (currentIndex)); - NS_ENSURE_SUCCESS(currentTxn->SetSHEntry(aSHEntry),NS_ERROR_FAILURE); + NS_ENSURE_SUCCESS(currentTxn->SetSHEntry(aSHEntry), NS_ERROR_FAILURE); currentTxn->SetPersist(aPersist); return NS_OK; } - nsCOMPtr txn(do_CreateInstance(NS_SHTRANSACTION_CONTRACTID)); + nsCOMPtr txn( + do_CreateInstance(NS_SHTRANSACTION_CONTRACTID)); NS_ENSURE_TRUE(txn, NS_ERROR_FAILURE); nsCOMPtr uri; @@ -437,31 +426,33 @@ nsSHistory::AddEntry(nsISHEntry * aSHEntry, bool aPersist) GetTransactionAtIndex(mIndex, getter_AddRefs(currentTxn)); } - // Set the ShEntry and parent for the transaction. setting the + // Set the ShEntry and parent for the transaction. setting the // parent will properly set the parent child relationship txn->SetPersist(aPersist); NS_ENSURE_SUCCESS(txn->Create(aSHEntry, currentTxn), NS_ERROR_FAILURE); - + // A little tricky math here... Basically when adding an object regardless of // what the length was before, it should always be set back to the current and // lop off the forward. mLength = (++mIndex + 1); // If this is the very first transaction, initialize the list - if(!mListRoot) + if (!mListRoot) { mListRoot = txn; + } // Purge History list if it is too long - if ((gHistoryMaxSize >= 0) && (mLength > gHistoryMaxSize)) - PurgeHistory(mLength-gHistoryMaxSize); - + if (gHistoryMaxSize >= 0 && mLength > gHistoryMaxSize) { + PurgeHistory(mLength - gHistoryMaxSize); + } + RemoveDynEntries(mIndex - 1, mIndex); return NS_OK; } /* Get size of the history list */ NS_IMETHODIMP -nsSHistory::GetCount(int32_t * aResult) +nsSHistory::GetCount(int32_t* aResult) { NS_ENSURE_ARG_POINTER(aResult); *aResult = mLength; @@ -470,7 +461,7 @@ nsSHistory::GetCount(int32_t * aResult) /* Get index of the history list */ NS_IMETHODIMP -nsSHistory::GetIndex(int32_t * aResult) +nsSHistory::GetIndex(int32_t* aResult) { NS_PRECONDITION(aResult, "null out param?"); *aResult = mIndex; @@ -479,7 +470,7 @@ nsSHistory::GetIndex(int32_t * aResult) /* Get the requestedIndex */ NS_IMETHODIMP -nsSHistory::GetRequestedIndex(int32_t * aResult) +nsSHistory::GetRequestedIndex(int32_t* aResult) { NS_PRECONDITION(aResult, "null out param?"); *aResult = mRequestedIndex; @@ -488,7 +479,8 @@ nsSHistory::GetRequestedIndex(int32_t * aResult) /* Get the entry at a given index */ NS_IMETHODIMP -nsSHistory::GetEntryAtIndex(int32_t aIndex, bool aModifyIndex, nsISHEntry** aResult) +nsSHistory::GetEntryAtIndex(int32_t aIndex, bool aModifyIndex, + nsISHEntry** aResult) { nsresult rv; nsCOMPtr txn; @@ -496,45 +488,47 @@ nsSHistory::GetEntryAtIndex(int32_t aIndex, bool aModifyIndex, nsISHEntry** aRes /* GetTransactionAtIndex ensures aResult is valid and validates aIndex */ rv = GetTransactionAtIndex(aIndex, getter_AddRefs(txn)); if (NS_SUCCEEDED(rv) && txn) { - //Get the Entry from the transaction + // Get the Entry from the transaction rv = txn->GetSHEntry(aResult); if (NS_SUCCEEDED(rv) && (*aResult)) { // Set mIndex to the requested index, if asked to do so.. if (aModifyIndex) { mIndex = aIndex; } - } //entry - } //Transaction + } + } return rv; } /* Get the transaction at a given index */ NS_IMETHODIMP -nsSHistory::GetTransactionAtIndex(int32_t aIndex, nsISHTransaction ** aResult) +nsSHistory::GetTransactionAtIndex(int32_t aIndex, nsISHTransaction** aResult) { nsresult rv; NS_ENSURE_ARG_POINTER(aResult); - if ((mLength <= 0) || (aIndex < 0) || (aIndex >= mLength)) + if (mLength <= 0 || aIndex < 0 || aIndex >= mLength) { return NS_ERROR_FAILURE; + } - if (!mListRoot) + if (!mListRoot) { return NS_ERROR_FAILURE; + } - if (aIndex == 0) - { + if (aIndex == 0) { *aResult = mListRoot; NS_ADDREF(*aResult); return NS_OK; - } - int32_t cnt=0; - nsCOMPtr tempPtr; + } + int32_t cnt = 0; + nsCOMPtr tempPtr; rv = GetRootTransaction(getter_AddRefs(tempPtr)); - if (NS_FAILED(rv) || !tempPtr) + if (NS_FAILED(rv) || !tempPtr) { return NS_ERROR_FAILURE; + } - while(1) { + while (true) { nsCOMPtr ptr; rv = tempPtr->GetNext(getter_AddRefs(ptr)); if (NS_SUCCEEDED(rv) && ptr) { @@ -542,23 +536,22 @@ nsSHistory::GetTransactionAtIndex(int32_t aIndex, nsISHTransaction ** aResult) if (cnt == aIndex) { ptr.forget(aResult); break; - } - else { + } else { tempPtr = ptr; continue; } - } //NS_SUCCEEDED - else + } else { return NS_ERROR_FAILURE; - } // while - + } + } + return NS_OK; } - /* Get the index of a given entry */ NS_IMETHODIMP -nsSHistory::GetIndexOfEntry(nsISHEntry* aSHEntry, int32_t* aResult) { +nsSHistory::GetIndexOfEntry(nsISHEntry* aSHEntry, int32_t* aResult) +{ NS_ENSURE_ARG(aSHEntry); NS_ENSURE_ARG_POINTER(aResult); *aResult = -1; @@ -598,31 +591,32 @@ nsSHistory::GetIndexOfEntry(nsISHEntry* aSHEntry, int32_t* aResult) { return NS_OK; } - #ifdef DEBUG nsresult nsSHistory::PrintHistory() { - - nsCOMPtr txn; + nsCOMPtr txn; int32_t index = 0; nsresult rv; - if (!mListRoot) + if (!mListRoot) { return NS_ERROR_FAILURE; + } txn = mListRoot; - + while (1) { - if (!txn) + if (!txn) { break; - nsCOMPtr entry; + } + nsCOMPtr entry; rv = txn->GetSHEntry(getter_AddRefs(entry)); - if (NS_FAILED(rv) && !entry) + if (NS_FAILED(rv) && !entry) { return NS_ERROR_FAILURE; + } nsCOMPtr layoutHistoryState; - nsCOMPtr uri; + nsCOMPtr uri; nsXPIDLString title; entry->GetLayoutHistoryState(getter_AddRefs(layoutHistoryState)); @@ -631,8 +625,9 @@ nsSHistory::PrintHistory() #if 0 nsAutoCString url; - if (uri) - uri->GetSpec(url); + if (uri) { + uri->GetSpec(url); + } printf("**** SH Transaction #%d, Entry = %x\n", index, entry.get()); printf("\t\t URL = %s\n", url.get()); @@ -647,28 +642,27 @@ nsSHistory::PrintHistory() txn = next; index++; continue; - } - else + } else { break; + } } return NS_OK; } #endif - NS_IMETHODIMP -nsSHistory::GetRootTransaction(nsISHTransaction ** aResult) +nsSHistory::GetRootTransaction(nsISHTransaction** aResult) { NS_ENSURE_ARG_POINTER(aResult); - *aResult=mListRoot; + *aResult = mListRoot; NS_IF_ADDREF(*aResult); return NS_OK; } /* Get the max size of the history list */ NS_IMETHODIMP -nsSHistory::GetMaxLength(int32_t * aResult) +nsSHistory::GetMaxLength(int32_t* aResult) { NS_ENSURE_ARG_POINTER(aResult); *aResult = gHistoryMaxSize; @@ -679,23 +673,26 @@ nsSHistory::GetMaxLength(int32_t * aResult) NS_IMETHODIMP nsSHistory::SetMaxLength(int32_t aMaxSize) { - if (aMaxSize < 0) + if (aMaxSize < 0) { return NS_ERROR_ILLEGAL_VALUE; + } gHistoryMaxSize = aMaxSize; - if (mLength > aMaxSize) - PurgeHistory(mLength-aMaxSize); + if (mLength > aMaxSize) { + PurgeHistory(mLength - aMaxSize); + } return NS_OK; } NS_IMETHODIMP nsSHistory::PurgeHistory(int32_t aEntries) { - if (mLength <= 0 || aEntries <= 0) + if (mLength <= 0 || aEntries <= 0) { return NS_ERROR_FAILURE; + } aEntries = std::min(aEntries, mLength); - + bool purgeHistory = true; NOTIFY_LISTENERS_CANCELABLE(OnHistoryPurge, purgeHistory, (aEntries, &purgeHistory)); @@ -716,7 +713,7 @@ nsSHistory::PurgeHistory(int32_t aEntries) if (mListRoot) { mListRoot->SetPrev(nullptr); } - cnt++; + cnt++; } mLength -= cnt; mIndex -= cnt; @@ -727,57 +724,58 @@ nsSHistory::PurgeHistory(int32_t aEntries) mIndex = -1; } - if (mRootDocShell) + if (mRootDocShell) { mRootDocShell->HistoryPurged(cnt); + } return NS_OK; } - NS_IMETHODIMP -nsSHistory::AddSHistoryListener(nsISHistoryListener * aListener) +nsSHistory::AddSHistoryListener(nsISHistoryListener* aListener) { NS_ENSURE_ARG_POINTER(aListener); // Check if the listener supports Weak Reference. This is a must. - // This listener functionality is used by embedders and we want to + // This listener functionality is used by embedders and we want to // have the right ownership with who ever listens to SHistory nsWeakPtr listener = do_GetWeakReference(aListener); - if (!listener) return NS_ERROR_FAILURE; + if (!listener) { + return NS_ERROR_FAILURE; + } return mListeners.AppendElementUnlessExists(listener) ? NS_OK : NS_ERROR_OUT_OF_MEMORY; } - NS_IMETHODIMP -nsSHistory::RemoveSHistoryListener(nsISHistoryListener * aListener) +nsSHistory::RemoveSHistoryListener(nsISHistoryListener* aListener) { // Make sure the listener that wants to be removed is the - // one we have in store. + // one we have in store. nsWeakPtr listener = do_GetWeakReference(aListener); mListeners.RemoveElement(listener); return NS_OK; } - /* Replace an entry in the History list at a particular index. * Do not update index or count. */ NS_IMETHODIMP -nsSHistory::ReplaceEntry(int32_t aIndex, nsISHEntry * aReplaceEntry) +nsSHistory::ReplaceEntry(int32_t aIndex, nsISHEntry* aReplaceEntry) { NS_ENSURE_ARG(aReplaceEntry); nsresult rv; nsCOMPtr currentTxn; - if (!mListRoot) // Session History is not initialised. + if (!mListRoot) { + // Session History is not initialised. return NS_ERROR_FAILURE; + } rv = GetTransactionAtIndex(aIndex, getter_AddRefs(currentTxn)); - if(currentTxn) - { + if (currentTxn) { NOTIFY_LISTENERS(OnHistoryReplaceEntry, (aIndex)); // Set the replacement entry in the transaction @@ -815,35 +813,30 @@ nsSHistory::EvictAllContentViewers() while (trans) { EvictContentViewerForTransaction(trans); - nsISHTransaction *temp = trans; + nsISHTransaction* temp = trans; temp->GetNext(getter_AddRefs(trans)); } return NS_OK; } - - -//***************************************************************************** -// nsSHistory: nsIWebNavigation -//***************************************************************************** - NS_IMETHODIMP -nsSHistory::GetCanGoBack(bool * aCanGoBack) +nsSHistory::GetCanGoBack(bool* aCanGoBack) { NS_ENSURE_ARG_POINTER(aCanGoBack); *aCanGoBack = false; int32_t index = -1; NS_ENSURE_SUCCESS(GetIndex(&index), NS_ERROR_FAILURE); - if(index > 0) - *aCanGoBack = true; + if (index > 0) { + *aCanGoBack = true; + } return NS_OK; } NS_IMETHODIMP -nsSHistory::GetCanGoForward(bool * aCanGoForward) +nsSHistory::GetCanGoForward(bool* aCanGoForward) { NS_ENSURE_ARG_POINTER(aCanGoForward); *aCanGoForward = false; @@ -854,8 +847,9 @@ nsSHistory::GetCanGoForward(bool * aCanGoForward) NS_ENSURE_SUCCESS(GetIndex(&index), NS_ERROR_FAILURE); NS_ENSURE_SUCCESS(GetCount(&count), NS_ERROR_FAILURE); - if((index >= 0) && (index < (count - 1))) + if (index >= 0 && index < (count - 1)) { *aCanGoForward = true; + } return NS_OK; } @@ -866,50 +860,41 @@ nsSHistory::GoBack() bool canGoBack = false; GetCanGoBack(&canGoBack); - if (!canGoBack) // Can't go back + if (!canGoBack) { return NS_ERROR_UNEXPECTED; - return LoadEntry(mIndex-1, nsIDocShellLoadInfo::loadHistory, HIST_CMD_BACK); + } + return LoadEntry(mIndex - 1, nsIDocShellLoadInfo::loadHistory, HIST_CMD_BACK); } - NS_IMETHODIMP nsSHistory::GoForward() { bool canGoForward = false; GetCanGoForward(&canGoForward); - if (!canGoForward) // Can't go forward + if (!canGoForward) { return NS_ERROR_UNEXPECTED; - return LoadEntry(mIndex+1, nsIDocShellLoadInfo::loadHistory, HIST_CMD_FORWARD); + } + return LoadEntry(mIndex + 1, nsIDocShellLoadInfo::loadHistory, + HIST_CMD_FORWARD); } NS_IMETHODIMP nsSHistory::Reload(uint32_t aReloadFlags) { nsDocShellInfoLoadType loadType; - if (aReloadFlags & nsIWebNavigation::LOAD_FLAGS_BYPASS_PROXY && - aReloadFlags & nsIWebNavigation::LOAD_FLAGS_BYPASS_CACHE) - { + if (aReloadFlags & nsIWebNavigation::LOAD_FLAGS_BYPASS_PROXY && + aReloadFlags & nsIWebNavigation::LOAD_FLAGS_BYPASS_CACHE) { loadType = nsIDocShellLoadInfo::loadReloadBypassProxyAndCache; - } - else if (aReloadFlags & nsIWebNavigation::LOAD_FLAGS_BYPASS_PROXY) - { + } else if (aReloadFlags & nsIWebNavigation::LOAD_FLAGS_BYPASS_PROXY) { loadType = nsIDocShellLoadInfo::loadReloadBypassProxy; - } - else if (aReloadFlags & nsIWebNavigation::LOAD_FLAGS_BYPASS_CACHE) - { + } else if (aReloadFlags & nsIWebNavigation::LOAD_FLAGS_BYPASS_CACHE) { loadType = nsIDocShellLoadInfo::loadReloadBypassCache; - } - else if (aReloadFlags & nsIWebNavigation::LOAD_FLAGS_CHARSET_CHANGE) - { + } else if (aReloadFlags & nsIWebNavigation::LOAD_FLAGS_CHARSET_CHANGE) { loadType = nsIDocShellLoadInfo::loadReloadCharsetChange; - } - else if (aReloadFlags & nsIWebNavigation::LOAD_FLAGS_ALLOW_MIXED_CONTENT) - { + } else if (aReloadFlags & nsIWebNavigation::LOAD_FLAGS_ALLOW_MIXED_CONTENT) { loadType = nsIDocShellLoadInfo::loadReloadMixedContent; - } - else - { + } else { loadType = nsIDocShellLoadInfo::loadReloadNormal; } @@ -922,8 +907,9 @@ nsSHistory::Reload(uint32_t aReloadFlags) GetCurrentURI(getter_AddRefs(currentURI)); NOTIFY_LISTENERS_CANCELABLE(OnHistoryReload, canNavigate, (currentURI, aReloadFlags, &canNavigate)); - if (!canNavigate) + if (!canNavigate) { return NS_OK; + } return LoadEntry(mIndex, loadType, HIST_CMD_RELOAD); } @@ -937,8 +923,9 @@ nsSHistory::ReloadCurrentEntry() GetCurrentURI(getter_AddRefs(currentURI)); NOTIFY_LISTENERS_CANCELABLE(OnHistoryGotoIndex, canNavigate, (mIndex, currentURI, &canNavigate)); - if (!canNavigate) + if (!canNavigate) { return NS_OK; + } return LoadEntry(mIndex, nsIDocShellLoadInfo::loadHistory, HIST_CMD_RELOAD); } @@ -992,7 +979,7 @@ nsSHistory::EvictOutOfRangeWindowContentViewers(int32_t aIndex) LOG(("EvictOutOfRangeWindowContentViewers(index=%d), " "mLength=%d. Safe range [%d, %d]", - aIndex, mLength, startSafeIndex, endSafeIndex)); + aIndex, mLength, startSafeIndex, endSafeIndex)); // The content viewers in range aIndex -/+ gHistoryMaxViewers will not be // evicted. Collect a set of them so we don't accidentally evict one of them @@ -1003,7 +990,7 @@ nsSHistory::EvictOutOfRangeWindowContentViewers(int32_t aIndex) for (int32_t i = startSafeIndex; trans && i <= endSafeIndex; i++) { nsCOMPtr viewer = GetContentViewerForTransaction(trans); safeViewers.AppendObject(viewer); - nsISHTransaction *temp = trans; + nsISHTransaction* temp = trans; temp->GetNext(getter_AddRefs(trans)); } @@ -1015,7 +1002,7 @@ nsSHistory::EvictOutOfRangeWindowContentViewers(int32_t aIndex) EvictContentViewerForTransaction(trans); } - nsISHTransaction *temp = trans; + nsISHTransaction* temp = trans; temp->GetNext(getter_AddRefs(trans)); } } @@ -1025,7 +1012,7 @@ namespace { class TransactionAndDistance { public: - TransactionAndDistance(nsISHTransaction *aTrans, uint32_t aDist) + TransactionAndDistance(nsISHTransaction* aTrans, uint32_t aDist) : mTransaction(aTrans) , mDistance(aDist) { @@ -1044,7 +1031,7 @@ public: } } - bool operator<(const TransactionAndDistance &aOther) const + bool operator<(const TransactionAndDistance& aOther) const { // Compare distances first, and fall back to last-accessed times. if (aOther.mDistance != this->mDistance) { @@ -1054,7 +1041,7 @@ public: return this->mLastTouched < aOther.mLastTouched; } - bool operator==(const TransactionAndDistance &aOther) const + bool operator==(const TransactionAndDistance& aOther) const { // This is a little silly; we need == so the default comaprator can be // instantiated, but this function is never actually called when we sort @@ -1071,7 +1058,7 @@ public: } // anonymous namespace -//static +// static void nsSHistory::GloballyEvictContentViewers() { @@ -1105,7 +1092,7 @@ nsSHistory::GloballyEvictContentViewers() // int32_t startIndex = std::max(0, shist->mIndex - gHistoryMaxViewers); int32_t endIndex = std::min(shist->mLength - 1, - shist->mIndex + gHistoryMaxViewers); + shist->mIndex + gHistoryMaxViewers); nsCOMPtr trans; shist->GetTransactionAtIndex(startIndex, getter_AddRefs(trans)); for (int32_t i = startIndex; trans && i <= endIndex; i++) { @@ -1119,23 +1106,25 @@ nsSHistory::GloballyEvictContentViewers() // distance from the SHistory's index and continue. bool found = false; for (uint32_t j = 0; j < shTransactions.Length(); j++) { - TransactionAndDistance &container = shTransactions[j]; + TransactionAndDistance& container = shTransactions[j]; if (container.mViewer == contentViewer) { - container.mDistance = std::min(container.mDistance, DeprecatedAbs(i - shist->mIndex)); + container.mDistance = std::min(container.mDistance, + DeprecatedAbs(i - shist->mIndex)); found = true; break; } } - // If we didn't find a TransactionAndDistance for this content viewer, make a new - // one. + // If we didn't find a TransactionAndDistance for this content viewer, + // make a new one. if (!found) { - TransactionAndDistance container(trans, DeprecatedAbs(i - shist->mIndex)); + TransactionAndDistance container(trans, + DeprecatedAbs(i - shist->mIndex)); shTransactions.AppendElement(container); } } - nsISHTransaction *temp = trans; + nsISHTransaction* temp = trans; temp->GetNext(getter_AddRefs(trans)); } @@ -1157,20 +1146,17 @@ nsSHistory::GloballyEvictContentViewers() // so let's not worry about it.) transactions.Sort(); - for (int32_t i = transactions.Length() - 1; - i >= sHistoryMaxTotalViewers; --i) { - + for (int32_t i = transactions.Length() - 1; i >= sHistoryMaxTotalViewers; + --i) { EvictContentViewerForTransaction(transactions[i].mTransaction); - } } nsresult -nsSHistory::EvictExpiredContentViewerForEntry(nsIBFCacheEntry *aEntry) +nsSHistory::EvictExpiredContentViewerForEntry(nsIBFCacheEntry* aEntry) { int32_t startIndex = std::max(0, mIndex - gHistoryMaxViewers); - int32_t endIndex = std::min(mLength - 1, - mIndex + gHistoryMaxViewers); + int32_t endIndex = std::min(mLength - 1, mIndex + gHistoryMaxViewers); nsCOMPtr trans; GetTransactionAtIndex(startIndex, getter_AddRefs(trans)); @@ -1184,12 +1170,13 @@ nsSHistory::EvictExpiredContentViewerForEntry(nsIBFCacheEntry *aEntry) break; } - nsISHTransaction *temp = trans; + nsISHTransaction* temp = trans; temp->GetNext(getter_AddRefs(trans)); } - if (i > endIndex) + if (i > endIndex) { return NS_OK; - + } + if (i == mIndex) { NS_WARNING("How did the current SHEntry expire?"); return NS_OK; @@ -1205,7 +1192,7 @@ nsSHistory::EvictExpiredContentViewerForEntry(nsIBFCacheEntry *aEntry) // objects for each viewer to be evicted. However, this method is called // infrequently -- only when the disk or memory cache is cleared. -//static +// static void nsSHistory::GloballyEvictAllContentViewers() { @@ -1215,9 +1202,10 @@ nsSHistory::GloballyEvictAllContentViewers() sHistoryMaxTotalViewers = maxViewers; } -void GetDynamicChildren(nsISHContainer* aContainer, - nsTArray& aDocshellIDs, - bool aOnlyTopLevelDynamic) +void +GetDynamicChildren(nsISHContainer* aContainer, + nsTArray& aDocshellIDs, + bool aOnlyTopLevelDynamic) { int32_t count = 0; aContainer->GetChildCount(&count); @@ -1277,8 +1265,9 @@ RemoveFromSessionHistoryContainer(nsISHContainer* aContainer, return didRemove; } -bool RemoveChildEntries(nsISHistory* aHistory, int32_t aIndex, - nsTArray& aEntryIDs) +bool +RemoveChildEntries(nsISHistory* aHistory, int32_t aIndex, + nsTArray& aEntryIDs) { nsCOMPtr rootHE; aHistory->GetEntryAtIndex(aIndex, false, getter_AddRefs(rootHE)); @@ -1286,7 +1275,8 @@ bool RemoveChildEntries(nsISHistory* aHistory, int32_t aIndex, return root ? RemoveFromSessionHistoryContainer(root, aEntryIDs) : false; } -bool IsSameTree(nsISHEntry* aEntry1, nsISHEntry* aEntry2) +bool +IsSameTree(nsISHEntry* aEntry1, nsISHEntry* aEntry2) { if (!aEntry1 && !aEntry2) { return true; @@ -1316,7 +1306,7 @@ bool IsSameTree(nsISHEntry* aEntry1, nsISHEntry* aEntry2) return false; } } - + return true; } @@ -1391,11 +1381,13 @@ NS_IMETHODIMP_(void) nsSHistory::RemoveEntries(nsTArray& aIDs, int32_t aStartIndex) { int32_t index = aStartIndex; - while(index >= 0 && RemoveChildEntries(this, --index, aIDs)); + while (index >= 0 && RemoveChildEntries(this, --index, aIDs)) { + } int32_t minIndex = index; index = aStartIndex; - while(index >= 0 && RemoveChildEntries(this, index++, aIDs)); - + while (index >= 0 && RemoveChildEntries(this, index++, aIDs)) { + } + // We need to remove duplicate nsSHEntry trees. bool didRemove = false; while (index > minIndex) { @@ -1447,7 +1439,7 @@ nsSHistory::RemoveDynEntries(int32_t aOldIndex, int32_t aNewIndex) NS_IMETHODIMP nsSHistory::UpdateIndex() { - // Update the actual index with the right value. + // Update the actual index with the right value. if (mIndex != mRequestedIndex && mRequestedIndex != -1) { RemoveDynEntries(mIndex, mRequestedIndex); mIndex = mRequestedIndex; @@ -1460,11 +1452,10 @@ nsSHistory::UpdateIndex() NS_IMETHODIMP nsSHistory::Stop(uint32_t aStopFlags) { - //Not implemented + // Not implemented return NS_OK; } - NS_IMETHODIMP nsSHistory::GetDocument(nsIDOMDocument** aDocument) { @@ -1472,7 +1463,6 @@ nsSHistory::GetDocument(nsIDOMDocument** aDocument) return NS_OK; } - NS_IMETHODIMP nsSHistory::GetCurrentURI(nsIURI** aResultURI) { @@ -1481,12 +1471,13 @@ nsSHistory::GetCurrentURI(nsIURI** aResultURI) nsCOMPtr currentEntry; rv = GetEntryAtIndex(mIndex, false, getter_AddRefs(currentEntry)); - if (NS_FAILED(rv) && !currentEntry) return rv; + if (NS_FAILED(rv) && !currentEntry) { + return rv; + } rv = currentEntry->GetURI(aResultURI); return rv; } - NS_IMETHODIMP nsSHistory::GetReferringURI(nsIURI** aURI) { @@ -1495,7 +1486,6 @@ nsSHistory::GetReferringURI(nsIURI** aURI) return NS_OK; } - NS_IMETHODIMP nsSHistory::SetSessionHistory(nsISHistory* aSessionHistory) { @@ -1503,7 +1493,6 @@ nsSHistory::SetSessionHistory(nsISHistory* aSessionHistory) return NS_OK; } - NS_IMETHODIMP nsSHistory::GetSessionHistory(nsISHistory** aSessionHistory) { @@ -1536,11 +1525,13 @@ nsSHistory::LoadURI(const char16_t* aURI, NS_IMETHODIMP nsSHistory::GotoIndex(int32_t aIndex) { - return LoadEntry(aIndex, nsIDocShellLoadInfo::loadHistory, HIST_CMD_GOTOINDEX); + return LoadEntry(aIndex, nsIDocShellLoadInfo::loadHistory, + HIST_CMD_GOTOINDEX); } nsresult -nsSHistory::LoadNextPossibleEntry(int32_t aNewIndex, long aLoadType, uint32_t aHistCmd) +nsSHistory::LoadNextPossibleEntry(int32_t aNewIndex, long aLoadType, + uint32_t aHistCmd) { mRequestedIndex = -1; if (aNewIndex < mIndex) { @@ -1597,42 +1588,42 @@ nsSHistory::LoadEntry(int32_t aIndex, long aLoadType, uint32_t aHistCmd) } if (!canNavigate) { - // If the listener asked us not to proceed with - // the operation, simply return. + // If the listener asked us not to proceed with + // the operation, simply return. mRequestedIndex = -1; return NS_OK; // XXX Maybe I can return some other error code? } nsCOMPtr nexturi; - int32_t pCount=0, nCount=0; + int32_t pCount = 0; + int32_t nCount = 0; nsCOMPtr prevAsContainer(do_QueryInterface(prevEntry)); nsCOMPtr nextAsContainer(do_QueryInterface(nextEntry)); if (prevAsContainer && nextAsContainer) { prevAsContainer->GetChildCount(&pCount); nextAsContainer->GetChildCount(&nCount); } - + nsCOMPtr loadInfo; if (mRequestedIndex == mIndex) { - // Possibly a reload case + // Possibly a reload case docShell = mRootDocShell; - } - else { + } else { // Going back or forward. - if ((pCount > 0) && (nCount > 0)) { - /* THis is a subframe navigation. Go find + if (pCount > 0 && nCount > 0) { + /* THis is a subframe navigation. Go find * the docshell in which load should happen */ bool frameFound = false; - nsresult rv = CompareFrames(prevEntry, nextEntry, mRootDocShell, aLoadType, &frameFound); + nsresult rv = CompareFrames(prevEntry, nextEntry, mRootDocShell, + aLoadType, &frameFound); if (!frameFound) { // We did not successfully find the subframe in which // the new url was to be loaded. Go further in the history. return LoadNextPossibleEntry(aIndex, aLoadType, aHistCmd); } return rv; - } // (pCount >0) - else { + } else { // Loading top level page. uint32_t prevID = 0; uint32_t nextID = 0; @@ -1659,10 +1650,13 @@ nsSHistory::LoadEntry(int32_t aIndex, long aLoadType, uint32_t aHistCmd) } nsresult -nsSHistory::CompareFrames(nsISHEntry * aPrevEntry, nsISHEntry * aNextEntry, nsIDocShell * aParent, long aLoadType, bool * aIsFrameFound) +nsSHistory::CompareFrames(nsISHEntry* aPrevEntry, nsISHEntry* aNextEntry, + nsIDocShell* aParent, long aLoadType, + bool* aIsFrameFound) { - if (!aPrevEntry || !aNextEntry || !aParent) + if (!aPrevEntry || !aNextEntry || !aParent) { return NS_ERROR_FAILURE; + } // We should be comparing only entries which were created for the // same docshell. This is here to just prevent anything strange happening. @@ -1677,27 +1671,29 @@ nsSHistory::CompareFrames(nsISHEntry * aPrevEntry, nsISHEntry * aNextEntry, nsID aPrevEntry->GetID(&prevID); aNextEntry->GetID(&nextID); - + // Check the IDs to verify if the pages are different. if (prevID != nextID) { - if (aIsFrameFound) + if (aIsFrameFound) { *aIsFrameFound = true; + } // Set the Subframe flag of the entry to indicate that - // it is subframe navigation + // it is subframe navigation aNextEntry->SetIsSubFrame(true); InitiateLoad(aNextEntry, aParent, aLoadType); return NS_OK; } - /* The root entries are the same, so compare any child frames */ - int32_t pcnt=0, ncnt=0, dsCount=0; - nsCOMPtr prevContainer(do_QueryInterface(aPrevEntry)); - nsCOMPtr nextContainer(do_QueryInterface(aNextEntry)); + // The root entries are the same, so compare any child frames + int32_t pcnt = 0; + int32_t ncnt = 0; + int32_t dsCount = 0; + nsCOMPtr prevContainer(do_QueryInterface(aPrevEntry)); + nsCOMPtr nextContainer(do_QueryInterface(aNextEntry)); - if (!aParent) - return NS_ERROR_FAILURE; - if (!prevContainer || !nextContainer) + if (!aParent || !prevContainer || !nextContainer) { return NS_ERROR_FAILURE; + } prevContainer->GetChildCount(&pcnt); nextContainer->GetChildCount(&ncnt); @@ -1761,13 +1757,13 @@ nsSHistory::CompareFrames(nsISHEntry * aPrevEntry, nsISHEntry * aNextEntry, nsID // This will either load a new page to shell or some subshell or // do nothing. CompareFrames(pChild, nChild, dsChild, aLoadType, aIsFrameFound); - } + } return result; } - -nsresult -nsSHistory::InitiateLoad(nsISHEntry * aFrameEntry, nsIDocShell * aFrameDS, long aLoadType) +nsresult +nsSHistory::InitiateLoad(nsISHEntry* aFrameEntry, nsIDocShell* aFrameDS, + long aLoadType) { NS_ENSURE_STATE(aFrameDS && aFrameEntry); @@ -1777,8 +1773,8 @@ nsSHistory::InitiateLoad(nsISHEntry * aFrameEntry, nsIDocShell * aFrameDS, long * This will be passed on to child subframes later in nsDocShell, * so that proper loadType is maintained through out a frameset */ - aFrameEntry->SetLoadType(aLoadType); - aFrameDS->CreateLoadInfo (getter_AddRefs(loadInfo)); + aFrameEntry->SetLoadType(aLoadType); + aFrameDS->CreateLoadInfo(getter_AddRefs(loadInfo)); loadInfo->SetLoadType(aLoadType); loadInfo->SetSHEntry(aFrameEntry); @@ -1786,12 +1782,13 @@ nsSHistory::InitiateLoad(nsISHEntry * aFrameEntry, nsIDocShell * aFrameDS, long nsCOMPtr nextURI; aFrameEntry->GetURI(getter_AddRefs(nextURI)); // Time to initiate a document load - return aFrameDS->LoadURI(nextURI, loadInfo, nsIWebNavigation::LOAD_FLAGS_NONE, false); + return aFrameDS->LoadURI(nextURI, loadInfo, + nsIWebNavigation::LOAD_FLAGS_NONE, false); } NS_IMETHODIMP -nsSHistory::SetRootDocShell(nsIDocShell * aDocShell) +nsSHistory::SetRootDocShell(nsIDocShell* aDocShell) { mRootDocShell = aDocShell; return NS_OK; @@ -1806,12 +1803,7 @@ nsSHistory::GetSHistoryEnumerator(nsISimpleEnumerator** aEnumerator) return NS_OK; } - -//***************************************************************************** -//*** nsSHEnumerator: Object Management -//***************************************************************************** - -nsSHEnumerator::nsSHEnumerator(nsSHistory * aSHistory):mIndex(-1) +nsSHEnumerator::nsSHEnumerator(nsSHistory* aSHistory) : mIndex(-1) { mSHistory = aSHistory; } @@ -1824,32 +1816,32 @@ nsSHEnumerator::~nsSHEnumerator() NS_IMPL_ISUPPORTS(nsSHEnumerator, nsISimpleEnumerator) NS_IMETHODIMP -nsSHEnumerator::HasMoreElements(bool * aReturn) +nsSHEnumerator::HasMoreElements(bool* aReturn) { int32_t cnt; *aReturn = false; mSHistory->GetCount(&cnt); - if (mIndex >= -1 && mIndex < (cnt-1) ) { + if (mIndex >= -1 && mIndex < (cnt - 1)) { *aReturn = true; } return NS_OK; } - -NS_IMETHODIMP -nsSHEnumerator::GetNext(nsISupports **aItem) +NS_IMETHODIMP +nsSHEnumerator::GetNext(nsISupports** aItem) { NS_ENSURE_ARG_POINTER(aItem); - int32_t cnt= 0; + int32_t cnt = 0; - nsresult result = NS_ERROR_FAILURE; + nsresult result = NS_ERROR_FAILURE; mSHistory->GetCount(&cnt); - if (mIndex < (cnt-1)) { + if (mIndex < (cnt - 1)) { mIndex++; nsCOMPtr hEntry; result = mSHistory->GetEntryAtIndex(mIndex, false, getter_AddRefs(hEntry)); - if (hEntry) + if (hEntry) { result = CallQueryInterface(hEntry, aItem); + } } return result; } diff --git a/docshell/shistory/src/nsSHistory.h b/docshell/shistory/src/nsSHistory.h index 36af8855f68..245e1ebc913 100644 --- a/docshell/shistory/src/nsSHistory.h +++ b/docshell/shistory/src/nsSHistory.h @@ -7,10 +7,7 @@ #ifndef nsSHistory_h #define nsSHistory_h -// Helper Classes #include "nsCOMPtr.h" - -//Interfaces Needed #include "nsISHistory.h" #include "nsISHistoryInternal.h" #include "nsIWebNavigation.h" @@ -18,7 +15,6 @@ #include "nsTObserverArray.h" #include "nsWeakPtr.h" -// Needed to maintain global list of all SHistory objects #include "prclist.h" class nsIDocShell; @@ -34,7 +30,6 @@ class nsSHistory final : public PRCList, { public: nsSHistory(); - NS_DECL_ISUPPORTS NS_DECL_NSISHISTORY NS_DECL_NSISHISTORYINTERNAL @@ -56,15 +51,18 @@ protected: friend class nsSHEnumerator; friend class nsSHistoryObserver; - // Could become part of nsIWebNavigation - NS_IMETHOD GetTransactionAtIndex(int32_t aIndex, nsISHTransaction ** aResult); - nsresult CompareFrames(nsISHEntry * prevEntry, nsISHEntry * nextEntry, nsIDocShell * rootDocShell, long aLoadType, bool * aIsFrameFound); - nsresult InitiateLoad(nsISHEntry * aFrameEntry, nsIDocShell * aFrameDS, long aLoadType); + // Could become part of nsIWebNavigation + NS_IMETHOD GetTransactionAtIndex(int32_t aIndex, nsISHTransaction** aResult); + nsresult CompareFrames(nsISHEntry* aPrevEntry, nsISHEntry* aNextEntry, + nsIDocShell* aRootDocShell, long aLoadType, + bool* aIsFrameFound); + nsresult InitiateLoad(nsISHEntry* aFrameEntry, nsIDocShell* aFrameDS, + long aLoadType); - NS_IMETHOD LoadEntry(int32_t aIndex, long aLoadType, uint32_t histCmd); + NS_IMETHOD LoadEntry(int32_t aIndex, long aLoadType, uint32_t aHistCmd); #ifdef DEBUG - nsresult PrintHistory(); + nsresult PrintHistory(); #endif // Evict content viewers in this window which don't lie in the "safe" range @@ -79,7 +77,9 @@ protected: void RemoveDynEntries(int32_t aOldIndex, int32_t aNewIndex); - nsresult LoadNextPossibleEntry(int32_t aNewIndex, long aLoadType, uint32_t aHistCmd); + nsresult LoadNextPossibleEntry(int32_t aNewIndex, long aLoadType, + uint32_t aHistCmd); + protected: // aIndex is the index of the transaction which may be removed. // If aKeepNext is true, aIndex is compared to aIndex + 1, @@ -93,29 +93,27 @@ protected: // Session History listeners nsAutoTObserverArray mListeners; // Weak reference. Do not refcount this. - nsIDocShell * mRootDocShell; + nsIDocShell* mRootDocShell; // Max viewers allowed total, across all SHistory objects - static int32_t sHistoryMaxTotalViewers; + static int32_t sHistoryMaxTotalViewers; }; -//***************************************************************************** -//*** nsSHEnumerator: Object Management -//***************************************************************************** + class nsSHEnumerator : public nsISimpleEnumerator { public: - NS_DECL_ISUPPORTS NS_DECL_NSISIMPLEENUMERATOR - explicit nsSHEnumerator(nsSHistory * aHistory); - + explicit nsSHEnumerator(nsSHistory* aHistory); + protected: friend class nsSHistory; virtual ~nsSHEnumerator(); + private: - int32_t mIndex; - nsSHistory * mSHistory; + int32_t mIndex; + nsSHistory* mSHistory; }; -#endif /* nsSHistory */ +#endif /* nsSHistory */ diff --git a/dom/base/nsDocument.cpp b/dom/base/nsDocument.cpp index 44e39e0b60a..582d93ee65f 100644 --- a/dom/base/nsDocument.cpp +++ b/dom/base/nsDocument.cpp @@ -270,14 +270,14 @@ nsIdentifierMapEntry::Traverse(nsCycleCollectionTraversalCallback* aCallback) bool nsIdentifierMapEntry::IsEmpty() { - return mIdContentList.Count() == 0 && !mNameContentList && + return mIdContentList.IsEmpty() && !mNameContentList && !mChangeCallbacks && !mImageElement; } Element* nsIdentifierMapEntry::GetIdElement() { - return static_cast(mIdContentList.SafeElementAt(0)); + return mIdContentList.SafeElementAt(0); } Element* @@ -289,8 +289,8 @@ nsIdentifierMapEntry::GetImageIdElement() void nsIdentifierMapEntry::AppendAllIdContent(nsCOMArray* aElements) { - for (int32_t i = 0; i < mIdContentList.Count(); ++i) { - aElements->AppendObject(static_cast(mIdContentList[i])); + for (size_t i = 0; i < mIdContentList.Length(); ++i) { + aElements->AppendObject(mIdContentList[i]); } } @@ -592,16 +592,15 @@ bool nsIdentifierMapEntry::AddIdElement(Element* aElement) { NS_PRECONDITION(aElement, "Must have element"); - NS_PRECONDITION(mIdContentList.IndexOf(nullptr) < 0, + NS_PRECONDITION(!mIdContentList.Contains(nullptr), "Why is null in our list?"); #ifdef DEBUG - Element* currentElement = - static_cast(mIdContentList.SafeElementAt(0)); + Element* currentElement = mIdContentList.SafeElementAt(0); #endif // Common case - if (mIdContentList.Count() == 0) { + if (mIdContentList.IsEmpty()) { if (!mIdContentList.AppendElement(aElement)) return false; NS_ASSERTION(currentElement == nullptr, "How did that happen?"); @@ -613,7 +612,7 @@ nsIdentifierMapEntry::AddIdElement(Element* aElement) // with us. Search for the right place to insert the content. size_t idx; - if (BinarySearchIf(mIdContentList, 0, mIdContentList.Count(), + if (BinarySearchIf(mIdContentList, 0, mIdContentList.Length(), PositionComparator(aElement), &idx)) { // Already in the list, so already in the right spot. Get out of here. // XXXbz this only happens because XUL does all sorts of random @@ -621,12 +620,12 @@ nsIdentifierMapEntry::AddIdElement(Element* aElement) return true; } - if (!mIdContentList.InsertElementAt(aElement, idx)) + if (!mIdContentList.InsertElementAt(idx, aElement)) { return false; + } if (idx == 0) { - Element* oldElement = - static_cast(mIdContentList.SafeElementAt(1)); + Element* oldElement = mIdContentList.SafeElementAt(1); NS_ASSERTION(currentElement == oldElement, "How did that happen?"); FireChangeCallbacks(oldElement, aElement); } @@ -645,17 +644,15 @@ nsIdentifierMapEntry::RemoveIdElement(Element* aElement) // Only assert this in HTML documents for now as XUL does all sorts of weird // crap. NS_ASSERTION(!aElement->OwnerDoc()->IsHTMLDocument() || - mIdContentList.IndexOf(aElement) >= 0, + mIdContentList.Contains(aElement), "Removing id entry that doesn't exist"); // XXXbz should this ever Compact() I guess when all the content is gone // we'll just get cleaned up in the natural order of things... - Element* currentElement = - static_cast(mIdContentList.SafeElementAt(0)); + Element* currentElement = mIdContentList.SafeElementAt(0); mIdContentList.RemoveElement(aElement); if (currentElement == aElement) { - FireChangeCallbacks(currentElement, - static_cast(mIdContentList.SafeElementAt(0))); + FireChangeCallbacks(currentElement, mIdContentList.SafeElementAt(0)); } } @@ -5048,7 +5045,7 @@ nsDocument::GetElementById(const nsAString& aElementId) return entry ? entry->GetIdElement() : nullptr; } -const nsSmallVoidArray* +const nsTArray* nsDocument::GetAllElementsForId(const nsAString& aElementId) const { if (aElementId.IsEmpty()) { @@ -5056,7 +5053,7 @@ nsDocument::GetAllElementsForId(const nsAString& aElementId) const } nsIdentifierMapEntry *entry = mIdentifierMap.GetEntry(aElementId); - return entry ? entry->GetIdElements() : nullptr; + return entry ? &entry->GetIdElements() : nullptr; } NS_IMETHODIMP diff --git a/dom/base/nsDocument.h b/dom/base/nsDocument.h index 8771395d788..288bf41c3a3 100644 --- a/dom/base/nsDocument.h +++ b/dom/base/nsDocument.h @@ -18,7 +18,6 @@ #include "nsCRT.h" #include "nsWeakReference.h" #include "nsWeakPtr.h" -#include "nsVoidArray.h" #include "nsTArray.h" #include "nsIDOMXMLDocument.h" #include "nsIDOMDocumentXBL.h" @@ -151,8 +150,8 @@ public: /** * Returns the list of all elements associated with this id. */ - const nsSmallVoidArray* GetIdElements() const { - return &mIdContentList; + const nsTArray& GetIdElements() const { + return mIdContentList; } /** * If this entry has a non-null image element set (using SetImageElement), @@ -228,7 +227,7 @@ private: // empty if there are no elements with this ID. // The elements are stored as weak pointers. - nsSmallVoidArray mIdContentList; + nsTArray mIdContentList; nsRefPtr mNameContentList; nsAutoPtr > mChangeCallbacks; nsRefPtr mImageElement; @@ -1141,7 +1140,7 @@ public: virtual void SetChangeScrollPosWhenScrollingToRef(bool aValue) override; virtual Element *GetElementById(const nsAString& aElementId) override; - virtual const nsSmallVoidArray* GetAllElementsForId(const nsAString& aElementId) const override; + virtual const nsTArray* GetAllElementsForId(const nsAString& aElementId) const override; virtual Element *LookupImageElement(const nsAString& aElementId) override; virtual void MozSetImageElement(const nsAString& aImageElementId, diff --git a/dom/base/nsIDocument.h b/dom/base/nsIDocument.h index d095ae06740..df79a833a49 100644 --- a/dom/base/nsIDocument.h +++ b/dom/base/nsIDocument.h @@ -78,7 +78,6 @@ class nsSMILAnimationController; class nsStyleSet; class nsTextNode; class nsWindowSizes; -class nsSmallVoidArray; class nsDOMCaretPosition; class nsViewportInfo; class nsIGlobalObject; @@ -2078,9 +2077,8 @@ public: /** * This method returns _all_ the elements in this document which * have id aElementId, if there are any. Otherwise it returns null. - * The entries of the nsSmallVoidArray are Element* */ - virtual const nsSmallVoidArray* GetAllElementsForId(const nsAString& aElementId) const = 0; + virtual const nsTArray* GetAllElementsForId(const nsAString& aElementId) const = 0; /** * Lookup an image element using its associated ID, which is usually provided diff --git a/dom/base/nsINode.cpp b/dom/base/nsINode.cpp index 6bcf1bd59e5..af9f7207b01 100644 --- a/dom/base/nsINode.cpp +++ b/dom/base/nsINode.cpp @@ -2478,8 +2478,7 @@ FindMatchingElementsWithId(const nsAString& aId, nsINode* aRoot, "document if it's in the document. Note that document fragments " "can't be IsInDoc(), so should never show up here."); - const nsSmallVoidArray* elements = aRoot->OwnerDoc()->GetAllElementsForId(aId); - + const nsTArray* elements = aRoot->OwnerDoc()->GetAllElementsForId(aId); if (!elements) { // Nothing to do; we're done return; @@ -2487,8 +2486,8 @@ FindMatchingElementsWithId(const nsAString& aId, nsINode* aRoot, // XXXbz: Should we fall back to the tree walk if aRoot is not the // document and |elements| is long, for some value of "long"? - for (int32_t i = 0; i < elements->Count(); ++i) { - Element *element = static_cast(elements->ElementAt(i)); + for (size_t i = 0; i < elements->Length(); ++i) { + Element* element = (*elements)[i]; if (!aRoot->IsElement() || (element != aRoot && nsContentUtils::ContentIsDescendantOf(element, aRoot))) { diff --git a/dom/ipc/ContentChild.cpp b/dom/ipc/ContentChild.cpp index b97e02b43e7..a2b43f7aab7 100644 --- a/dom/ipc/ContentChild.cpp +++ b/dom/ipc/ContentChild.cpp @@ -54,7 +54,6 @@ #include "mozilla/net/NeckoChild.h" #include "mozilla/plugins/PluginInstanceParent.h" #include "mozilla/plugins/PluginModuleParent.h" -#include "mozilla/media/webrtc/WebrtcGlobalChild.h" #include "mozilla/widget/WidgetMessageUtils.h" #if defined(MOZ_CONTENT_SANDBOX) @@ -121,6 +120,10 @@ #include "nsIScriptSecurityManager.h" +#ifdef MOZ_WEBRTC +#include "signaling/src/peerconnection/WebrtcGlobalChild.h" +#endif + #ifdef MOZ_PERMISSIONS #include "nsPermission.h" #include "nsPermissionManager.h" @@ -1821,15 +1824,23 @@ ContentChild::DeallocPSpeechSynthesisChild(PSpeechSynthesisChild* aActor) PWebrtcGlobalChild * ContentChild::AllocPWebrtcGlobalChild() { +#ifdef MOZ_WEBRTC WebrtcGlobalChild *child = new WebrtcGlobalChild(); return child; +#else + return nullptr; +#endif } bool ContentChild::DeallocPWebrtcGlobalChild(PWebrtcGlobalChild *aActor) { +#ifdef MOZ_WEBRTC delete static_cast(aActor); return true; +#else + return false; +#endif } diff --git a/dom/ipc/ContentParent.cpp b/dom/ipc/ContentParent.cpp index 76656801da2..1bdc40a7e56 100755 --- a/dom/ipc/ContentParent.cpp +++ b/dom/ipc/ContentParent.cpp @@ -87,7 +87,6 @@ #include "mozilla/StaticPtr.h" #include "mozilla/Telemetry.h" #include "mozilla/unused.h" -#include "mozilla/media/webrtc/WebrtcGlobalParent.h" #include "nsAnonymousTemporaryFile.h" #include "nsAppRunner.h" #include "nsAutoPtr.h" @@ -167,6 +166,10 @@ #include "nsIBidiKeyboard.h" +#ifdef MOZ_WEBRTC +#include "signaling/src/peerconnection/WebrtcGlobalParent.h" +#endif + #if defined(ANDROID) || defined(LINUX) #include "nsSystemInfo.h" #endif @@ -4950,14 +4953,22 @@ ContentParent::DeallocPOfflineCacheUpdateParent(POfflineCacheUpdateParent* aActo PWebrtcGlobalParent * ContentParent::AllocPWebrtcGlobalParent() { +#ifdef MOZ_WEBRTC return WebrtcGlobalParent::Alloc(); +#else + return nullptr; +#endif } bool ContentParent::DeallocPWebrtcGlobalParent(PWebrtcGlobalParent *aActor) { +#ifdef MOZ_WEBRTC WebrtcGlobalParent::Dealloc(static_cast(aActor)); return true; +#else + return false; +#endif } bool diff --git a/dom/ipc/moz.build b/dom/ipc/moz.build index 3a8111613f7..7a4b40a96d2 100644 --- a/dom/ipc/moz.build +++ b/dom/ipc/moz.build @@ -139,6 +139,7 @@ LOCAL_INCLUDES += [ '/gfx/2d', '/hal/sandbox', '/layout/base', + '/media/webrtc', '/netwerk/base', '/toolkit/xre', '/uriloader/exthandler', diff --git a/dom/media/Intervals.h b/dom/media/Intervals.h new file mode 100644 index 00000000000..a589ad51bea --- /dev/null +++ b/dom/media/Intervals.h @@ -0,0 +1,525 @@ +/* -*- 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 INTERVALS_H +#define INTERVALS_H + +#include +#include "mozilla/TypeTraits.h" +#include "nsTArray.h" + +namespace mozilla { +namespace media { + +/* Interval defines an interval between two points. Unlike a traditional + interval [A,B] where A <= x <= B, the upper boundary B is exclusive: A <= x < B + (e.g [A,B[ or [A,B) depending on where you're living) + It provides basic interval arithmetic and fuzzy edges. + The type T must provides a default constructor and +, -, <, <= and == + operators. + */ +template +class Interval +{ +public: + typedef Interval SelfType; + + Interval() + : mStart(T()) + , mEnd(T()) + , mFuzz(T()) + {} + + template + Interval(StartArg&& aStart, EndArg&& aEnd) + : mStart(Forward(aStart)) + , mEnd(Forward(aEnd)) + , mFuzz() + { + MOZ_ASSERT(aStart <= aEnd); + } + + template + Interval(StartArg&& aStart, EndArg&& aEnd, FuzzArg&& aFuzz) + : mStart(Forward(aStart)) + , mEnd(Forward(aEnd)) + , mFuzz(Forward(aFuzz)) + { + MOZ_ASSERT(aStart <= aEnd); + } + + Interval(const SelfType& aOther) + : mStart(aOther.mStart) + , mEnd(aOther.mEnd) + , mFuzz(aOther.mFuzz) + {} + + Interval(SelfType&& aOther) + : mStart(Move(aOther.mStart)) + , mEnd(Move(aOther.mEnd)) + , mFuzz(Move(aOther.mFuzz)) + { } + + SelfType& operator= (const SelfType& aOther) + { + mStart = aOther.mStart; + mEnd = aOther.mEnd; + mFuzz = aOther.mFuzz; + return *this; + } + + SelfType& operator= (SelfType&& aOther) + { + MOZ_ASSERT(&aOther != this, "self-moves are prohibited"); + this->~Interval(); + new(this) Interval(Move(aOther)); + return *this; + } + + // Basic interval arithmetic operator definition. + SelfType operator+ (const SelfType& aOther) const + { + return SelfType(mStart + aOther.mStart, + mEnd + aOther.mEnd, + mFuzz + aOther.mFuzz); + } + + // Basic interval arithmetic operator definition. + SelfType operator- (const SelfType& aOther) const + { + return SelfType(mStart - aOther.mEnd, + mEnd - aOther.mStart, + mFuzz + aOther.mFuzz); + } + + bool operator== (const SelfType& aOther) const + { + return mStart == aOther.mStart && mEnd == aOther.mEnd; + } + + bool operator!= (const SelfType& aOther) const + { + return !(*this == aOther); + } + + bool Contains(const T& aX) const + { + return mStart - mFuzz <= aX && aX < mEnd + mFuzz; + } + + bool ContainsStrict(const T& aX) const + { + return mStart <= aX && aX < mEnd; + } + + bool Contains(const SelfType& aOther) const + { + return (mStart - mFuzz <= aOther.mStart + aOther.mFuzz) && + (aOther.mEnd + aOther.mFuzz <= mEnd - mFuzz); + } + + bool ContainsStrict(const SelfType& aOther) const + { + return mStart <= aOther.mStart && aOther.mEnd <= mEnd; + } + + bool Intersects(const SelfType& aOther) const + { + return (mStart - mFuzz <= aOther.mEnd + aOther.mFuzz) && + (aOther.mStart - aOther.mFuzz <= mEnd + mFuzz); + } + + // Returns true if aOther is strictly to the right of this and contiguous. + // This operation isn't commutative. + bool Contiguous(const SelfType& aOther) const + { + return mEnd <= aOther.mStart && aOther.mStart - mEnd <= mFuzz + aOther.mFuzz; + } + + SelfType Union(const SelfType& aOther) const + { + SelfType result(*this); + if (aOther.mStart < mStart) { + result.mStart = aOther.mStart; + } + if (mEnd < aOther.mEnd) { + result.mEnd = aOther.mEnd; + } + if (mFuzz < aOther.mFuzz) { + result.mFuzz = aOther.mFuzz; + } + return result; + } + + SelfType Intersection(const SelfType& aOther) const + { + const T& s = std::max(mStart, aOther.mStart); + const T& e = std::min(mEnd, aOther.mEnd); + const T& f = std::max(mFuzz, aOther.mFuzz); + if (s < e) { + return SelfType(s, e, f); + } + // Return an empty interval. + return SelfType(); + } + + T Length() const + { + return mEnd - mStart; + } + + bool IsEmpty() const + { + return mStart == mEnd; + } + + T mStart; + T mEnd; + T mFuzz; + +private: +}; + +template +class IntervalSet +{ +public: + typedef IntervalSet SelfType; + typedef Interval ElemType; + typedef nsAutoTArray ContainerType; + typedef typename ContainerType::index_type IndexType; + + IntervalSet() + { + } + ~IntervalSet() + { + } + + IntervalSet(const SelfType& aOther) + : mIntervals(aOther.mIntervals) + { + } + + IntervalSet(SelfType&& aOther) + : mIntervals(Move(aOther.mIntervals)) + { + } + + explicit IntervalSet(const ElemType& aOther) + { + mIntervals.AppendElement(aOther); + } + + explicit IntervalSet(ElemType&& aOther) + { + mIntervals.AppendElement(Move(aOther)); + } + + SelfType& operator= (const SelfType& aOther) + { + mIntervals = aOther.mIntervals; + return *this; + } + + SelfType& operator= (SelfType&& aOther) + { + MOZ_ASSERT(&aOther != this, "self-moves are prohibited"); + this->~IntervalSet(); + new(this) IntervalSet(Move(aOther)); + return *this; + } + + SelfType& operator= (const ElemType& aInterval) + { + mIntervals.Clear(); + mIntervals.AppendElement(aInterval); + return *this; + } + + SelfType& operator= (ElemType&& aInterval) + { + mIntervals.Clear(); + mIntervals.AppendElement(Move(aInterval)); + return *this; + } + + // + and += operator will append the provided interval or intervalset. + // Note that the result is not normalized. Call Normalize() as required. + // Alternatively, use Union() + + SelfType& Add(const SelfType& aIntervals) + { + mIntervals.AppendElements(aIntervals.mIntervals); + return *this; + } + + SelfType& Add(const ElemType& aInterval) + { + mIntervals.AppendElement(aInterval); + return *this; + } + + SelfType& operator+= (const SelfType& aIntervals) + { + Add(aIntervals); + return *this; + } + + SelfType& operator+= (const ElemType& aInterval) + { + Add(aInterval); + return *this; + } + + SelfType operator+ (const SelfType& aIntervals) const + { + SelfType intervals(*this); + intervals.Add(aIntervals); + return intervals; + } + + SelfType operator+ (const ElemType& aInterval) + { + SelfType intervals(*this); + intervals.Add(aInterval); + return intervals; + } + + friend SelfType operator+ (const ElemType& aInterval, + const SelfType& aIntervals) + { + SelfType intervals; + intervals.Add(aInterval); + intervals.Add(aIntervals); + return intervals; + } + + // Mutate this IntervalSet to be the union of this and aOther. + // Resulting IntervalSet is normalized. + SelfType& Union(const SelfType& aOther) + { + Add(aOther); + Normalize(); + return *this; + } + + SelfType& Union(const ElemType& aInterval) + { + Add(aInterval); + Normalize(); + return *this; + } + + // Mutate this TimeRange to be the intersection of this and aOther. + SelfType& Intersection(const SelfType& aOther) + { + ContainerType intersection; + + const ContainerType& other = aOther.mIntervals; + IndexType i = 0, j = 0; + for (; i < mIntervals.Length() && j < other.Length();) { + if (mIntervals[i].Intersects(other[j])) { + intersection.AppendElement(mIntervals[i].Intersection(other[j])); + } + if (mIntervals[i].mEnd < other[j].mEnd) { + i++; + } else { + j++; + } + } + + mIntervals = intersection; + return *this; + } + + SelfType& Intersection(const ElemType& aInterval) + { + SelfType intervals(aInterval); + return Intersection(intervals); + } + + const ElemType& operator[] (IndexType aIndex) const + { + return mIntervals[aIndex]; + } + + // Returns the start boundary of the first interval. Or a default constructed + // T if IntervalSet is empty (and aExists if provided will be set to false). + T GetStart(bool* aExists = nullptr) const + { + bool exists = !mIntervals.IsEmpty(); + + if (aExists) { + *aExists = exists; + } + + if (exists) { + return mIntervals[0].mStart; + } else { + return T(); + } + } + + // Returns the end boundary of the last interval. Or a default constructed T + // if IntervalSet is empty (and aExists if provided will be set to false). + T GetEnd(bool* aExists = nullptr) const + { + bool exists = !mIntervals.IsEmpty(); + if (aExists) { + *aExists = exists; + } + + if (exists) { + return mIntervals.LastElement().mEnd; + } else { + return T(); + } + } + + IndexType Length() const + { + return mIntervals.Length(); + } + + T Start(IndexType aIndex) const + { + return mIntervals[aIndex].mStart; + } + + T Start(IndexType aIndex, bool& aExists) const + { + aExists = aIndex < mIntervals.Length(); + + if (aExists) { + return mIntervals[aIndex].mStart; + } else { + return T(); + } + } + + T End(IndexType aIndex) const + { + return mIntervals[aIndex].mEnd; + } + + T End(IndexType aIndex, bool& aExists) const + { + aExists = aIndex < mIntervals.Length(); + + if (aExists) { + return mIntervals[aIndex].mEnd; + } else { + return T(); + } + } + + bool Contains(const T& aX) { + for (const auto& interval : mIntervals) { + if (interval.Contains(aX)) { + return true; + } + } + return false; + } + + bool ContainsStrict(const T& aX) { + for (const auto& interval : mIntervals) { + if (interval.ContainsStrict(aX)) { + return true; + } + } + return false; + } + + void Normalize() + { + if (mIntervals.Length() >= 2) { + ContainerType normalized; + + mIntervals.Sort(CompareIntervals()); + + // This merges the intervals. + ElemType current(mIntervals[0]); + for (IndexType i = 1; i < mIntervals.Length(); i++) { + if (current.Contains(mIntervals[i])) { + continue; + } + if (current.Intersects(mIntervals[i])) { + current = current.Union(mIntervals[i]); + } else { + normalized.AppendElement(current); + current = mIntervals[i]; + } + } + + normalized.AppendElement(current); + + mIntervals = normalized; + } + } + + // Shift all values by aOffset. + void Shift(T aOffset) + { + for (auto& interval : mIntervals) { + interval.mStart += aOffset; + interval.mEnd += aOffset; + } + } + + static const IndexType NoIndex = IndexType(-1); + + IndexType Find(T aValue) const + { + for (IndexType i = 0; i < mIntervals.Length(); i++) { + if (mIntervals[i].Contains(aValue)) { + return i; + } + } + return NoIndex; + } + +protected: + ContainerType mIntervals; + +private: + struct CompareIntervals + { + bool Equals(const ElemType& aT1, const ElemType& aT2) const + { + return aT1.mStart == aT2.mStart && aT1.mEnd == aT2.mEnd; + } + + bool LessThan(const ElemType& aT1, const ElemType& aT2) const { + return aT1.mStart - aT1.mFuzz < aT2.mStart + aT2.mFuzz; + } + }; +}; + + // clang doesn't allow for this to be defined inline of IntervalSet. +template +IntervalSet Union(const IntervalSet& aIntervals1, + const IntervalSet& aIntervals2) +{ + IntervalSet intervals(aIntervals1); + intervals.Union(aIntervals2); + return intervals; +} + +template +IntervalSet Intersection(const IntervalSet& aIntervals1, + const IntervalSet& aIntervals2) +{ + IntervalSet intersection(aIntervals1); + intersection.Intersection(aIntervals2); + return intersection; +} + +} // namespace media +} // namespace mozilla + +#endif // INTERVALS_H diff --git a/dom/media/TimeUnits.h b/dom/media/TimeUnits.h index 1af4be2033a..0380b7dc088 100644 --- a/dom/media/TimeUnits.h +++ b/dom/media/TimeUnits.h @@ -7,9 +7,11 @@ #ifndef TIME_UNITS_H #define TIME_UNITS_H +#include "Intervals.h" #include "VideoUtils.h" #include "mozilla/CheckedInt.h" #include "mozilla/FloatingPoint.h" +#include "mozilla/dom/TimeRanges.h" namespace mozilla { namespace media { @@ -40,6 +42,9 @@ struct Microseconds { } } + bool operator == (const Microseconds& aOther) const { + return mValue == aOther.mValue; + } bool operator > (const Microseconds& aOther) const { return mValue > aOther.mValue; } @@ -87,6 +92,10 @@ public: return double(mValue.value()) / USECS_PER_S; } + bool operator == (const TimeUnit& aOther) const { + MOZ_ASSERT(IsValid() && aOther.IsValid()); + return mValue.value() == aOther.mValue.value(); + } bool operator >= (const TimeUnit& aOther) const { MOZ_ASSERT(IsValid() && aOther.IsValid()); return mValue.value() >= aOther.mValue.value(); @@ -113,9 +122,18 @@ public: return mValue.isValid(); } + TimeUnit() + : mValue(CheckedInt64(0)) + {} + explicit TimeUnit(const Microseconds& aMicroseconds) : mValue(aMicroseconds.mValue) {} + TimeUnit& operator = (const Microseconds& aMicroseconds) + { + mValue = aMicroseconds.mValue; + return *this; + } TimeUnit(const TimeUnit&) = default; @@ -130,6 +148,64 @@ private: CheckedInt64 mValue; }; +typedef Interval TimeInterval; + +class TimeIntervals : public IntervalSet +{ +public: + typedef IntervalSet BaseType; + + // We can't use inherited constructors yet. So we have to duplicate all the + // constructors found in IntervalSet base class. + // all this could be later replaced with: + // using IntervalSet::IntervalSet; + + // MOZ_IMPLICIT as we want to enable initialization in the form: + // TimeIntervals i = ... like we would do with IntervalSet i = ... + MOZ_IMPLICIT TimeIntervals(const BaseType& aOther) + : BaseType(aOther) + {} + MOZ_IMPLICIT TimeIntervals(BaseType&& aOther) + : BaseType(Move(aOther)) + {} + explicit TimeIntervals(const BaseType::ElemType& aOther) + : BaseType(aOther) + {} + explicit TimeIntervals(BaseType::ElemType&& aOther) + : BaseType(Move(aOther)) + {} + + TimeIntervals() = default; + + // Make TimeIntervals interchangeable with dom::TimeRanges. + explicit TimeIntervals(dom::TimeRanges* aRanges) + { + for (uint32_t i = 0; i < aRanges->Length(); i++) { + ErrorResult rv; + *this += + TimeInterval(TimeUnit::FromSeconds(aRanges->Start(i, rv)), + TimeUnit::FromSeconds(aRanges->End(i, rv))); + } + } + TimeIntervals& operator = (dom::TimeRanges* aRanges) + { + *this = TimeIntervals(aRanges); + return *this; + } + + static TimeIntervals FromTimeRanges(dom::TimeRanges* aRanges) + { + return TimeIntervals(aRanges); + } + + void ToTimeRanges(dom::TimeRanges* aRanges) const + { + for (IndexType i = 0; i < Length(); i++) { + aRanges->Add(Start(i).ToSeconds(), End(i).ToSeconds()); + } + } +}; + } // namespace media } // namespace mozilla diff --git a/dom/media/fmp4/MP4Reader.h b/dom/media/fmp4/MP4Reader.h index d683e3f8bb2..886e7b53740 100644 --- a/dom/media/fmp4/MP4Reader.h +++ b/dom/media/fmp4/MP4Reader.h @@ -164,6 +164,9 @@ private: virtual void ReleaseMediaResources() override { mReader->ReleaseMediaResources(); } + virtual bool OnReaderTaskQueue() override { + return mReader->OnTaskQueue(); + } private: MP4Reader* mReader; TrackType mType; diff --git a/dom/media/fmp4/PlatformDecoderModule.h b/dom/media/fmp4/PlatformDecoderModule.h index 6d2ef5c77a1..e1b6b71ac0a 100644 --- a/dom/media/fmp4/PlatformDecoderModule.h +++ b/dom/media/fmp4/PlatformDecoderModule.h @@ -182,6 +182,8 @@ public: virtual void NotifyResourcesStatusChanged() {}; virtual void ReleaseMediaResources() {}; + + virtual bool OnReaderTaskQueue() = 0; }; // MediaDataDecoder is the interface exposed by decoders created by the @@ -189,9 +191,13 @@ public: // media data that the decoder accepts as valid input and produces as // output is determined when the MediaDataDecoder is created. // -// All functions are only called on the decode task queue. Don't block -// inside these functions, unless it's explicitly noted that you should -// (like in Flush() and Drain()). +// Unless otherwise noted, all functions are only called on the decode task +// queue. An exception is the MediaDataDecoder in +// MP4Reader::IsVideoAccelerated() for which all calls (Init(), +// IsHardwareAccelerated(), and Shutdown()) are from the main thread. +// +// Don't block inside these functions, unless it's explicitly noted that you +// should (like in Flush()). // // Decoding is done asynchronously. Any async work can be done on the // MediaTaskQueue passed into the PlatformDecoderModules's Create*Decoder() @@ -245,6 +251,7 @@ public: // returned. virtual nsresult Shutdown() = 0; + // Called from the state machine task queue or main thread. virtual bool IsHardwareAccelerated() const { return false; } // ConfigurationChanged will be called to inform the video or audio decoder diff --git a/dom/media/fmp4/SharedDecoderManager.cpp b/dom/media/fmp4/SharedDecoderManager.cpp index 7c35f02d724..a906f0f05ae 100644 --- a/dom/media/fmp4/SharedDecoderManager.cpp +++ b/dom/media/fmp4/SharedDecoderManager.cpp @@ -52,6 +52,11 @@ public: mManager->mActiveCallback->ReleaseMediaResources(); } } + virtual bool OnReaderTaskQueue() override + { + MOZ_ASSERT(mManager->mActiveCallback); + return mManager->mActiveCallback->OnReaderTaskQueue(); + } SharedDecoderManager* mManager; }; @@ -186,6 +191,9 @@ SharedDecoderManager::DrainComplete() void SharedDecoderManager::Shutdown() { + // Shutdown() should have been called on any proxies. + MOZ_ASSERT(!mActiveProxy); + if (mDecoder) { mDecoder->Shutdown(); mDecoder = nullptr; diff --git a/dom/media/fmp4/gmp/MediaDataDecoderProxy.h b/dom/media/fmp4/gmp/MediaDataDecoderProxy.h index e6a20477788..54f72bedf82 100644 --- a/dom/media/fmp4/gmp/MediaDataDecoderProxy.h +++ b/dom/media/fmp4/gmp/MediaDataDecoderProxy.h @@ -116,6 +116,11 @@ public: virtual void FlushComplete(); + virtual bool OnReaderTaskQueue() override + { + return mProxyCallback->OnReaderTaskQueue(); + } + private: MediaDataDecoderProxy* mProxyDecoder; MediaDataDecoderCallback* mProxyCallback; diff --git a/dom/media/fmp4/wmf/WMFMediaDataDecoder.cpp b/dom/media/fmp4/wmf/WMFMediaDataDecoder.cpp index d8d18c86a70..fd37503a245 100644 --- a/dom/media/fmp4/wmf/WMFMediaDataDecoder.cpp +++ b/dom/media/fmp4/wmf/WMFMediaDataDecoder.cpp @@ -30,6 +30,7 @@ WMFMediaDataDecoder::WMFMediaDataDecoder(MFTManager* aMFTManager, , mMonitor("WMFMediaDataDecoder") , mIsDecodeTaskDispatched(false) , mIsFlushing(false) + , mIsShutDown(false) { } @@ -40,6 +41,9 @@ WMFMediaDataDecoder::~WMFMediaDataDecoder() nsresult WMFMediaDataDecoder::Init() { + MOZ_ASSERT(!mDecoder); + MOZ_ASSERT(!mIsShutDown); + mDecoder = mMFTManager->Init(); NS_ENSURE_TRUE(mDecoder, NS_ERROR_FAILURE); @@ -49,6 +53,8 @@ WMFMediaDataDecoder::Init() nsresult WMFMediaDataDecoder::Shutdown() { + MOZ_DIAGNOSTIC_ASSERT(!mIsShutDown); + if (mTaskQueue) { mTaskQueue->Dispatch( NS_NewRunnableMethod(this, &WMFMediaDataDecoder::ProcessShutdown)); @@ -62,6 +68,7 @@ WMFMediaDataDecoder::Shutdown() MOZ_ASSERT(!mIsDecodeTaskDispatched); } #endif + mIsShutDown = true; return NS_OK; } @@ -91,6 +98,9 @@ WMFMediaDataDecoder::EnsureDecodeTaskDispatched() nsresult WMFMediaDataDecoder::Input(MediaRawData* aSample) { + MOZ_ASSERT(mCallback->OnReaderTaskQueue()); + MOZ_DIAGNOSTIC_ASSERT(!mIsShutDown); + MonitorAutoLock mon(mMonitor); mInput.push(aSample); EnsureDecodeTaskDispatched(); @@ -172,6 +182,9 @@ WMFMediaDataDecoder::PurgeInputQueue() nsresult WMFMediaDataDecoder::Flush() { + MOZ_ASSERT(mCallback->OnReaderTaskQueue()); + MOZ_DIAGNOSTIC_ASSERT(!mIsShutDown); + MonitorAutoLock mon(mMonitor); PurgeInputQueue(); mIsFlushing = true; @@ -199,12 +212,17 @@ WMFMediaDataDecoder::ProcessDrain() nsresult WMFMediaDataDecoder::Drain() { + MOZ_ASSERT(mCallback->OnReaderTaskQueue()); + MOZ_DIAGNOSTIC_ASSERT(!mIsShutDown); + mTaskQueue->Dispatch(NS_NewRunnableMethod(this, &WMFMediaDataDecoder::ProcessDrain)); return NS_OK; } bool WMFMediaDataDecoder::IsHardwareAccelerated() const { + MOZ_ASSERT(!mIsShutDown); + return mMFTManager && mMFTManager->IsHardwareAccelerated(); } diff --git a/dom/media/fmp4/wmf/WMFMediaDataDecoder.h b/dom/media/fmp4/wmf/WMFMediaDataDecoder.h index 8e2547d76f6..3c1b1911565 100644 --- a/dom/media/fmp4/wmf/WMFMediaDataDecoder.h +++ b/dom/media/fmp4/wmf/WMFMediaDataDecoder.h @@ -101,6 +101,7 @@ private: std::queue> mInput; bool mIsDecodeTaskDispatched; bool mIsFlushing; + bool mIsShutDown; }; } // namespace mozilla diff --git a/dom/media/gtest/TestIntervalSet.cpp b/dom/media/gtest/TestIntervalSet.cpp new file mode 100644 index 00000000000..db6ac360778 --- /dev/null +++ b/dom/media/gtest/TestIntervalSet.cpp @@ -0,0 +1,591 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* 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 "gtest/gtest.h" +#include "mozilla/dom/TimeRanges.h" +#include "TimeUnits.h" +#include "Intervals.h" +#include +#include + +using namespace mozilla; + +typedef media::Interval ByteInterval; +typedef media::Interval IntInterval; + +ByteInterval CreateByteInterval(int32_t aStart, int32_t aEnd) +{ + ByteInterval test(aStart, aEnd); + return test; +} + +media::IntervalSet CreateByteIntervalSet(int32_t aStart, int32_t aEnd) +{ + media::IntervalSet test; + test += ByteInterval(aStart, aEnd); + return test; +} + +TEST(IntervalSet, Constructors) +{ + const int32_t start = 1; + const int32_t end = 2; + const int32_t fuzz = 0; + + // Compiler exercise. + ByteInterval test1(start, end); + ByteInterval test2(test1); + ByteInterval test3(start, end, fuzz); + ByteInterval test4(test3); + ByteInterval test5 = CreateByteInterval(start, end); + + media::IntervalSet blah1(test1); + media::IntervalSet blah2 = blah1; + media::IntervalSet blah3 = blah1 + test1; + media::IntervalSet blah4 = test1 + blah1; + media::IntervalSet blah5 = CreateByteIntervalSet(start, end); + (void)test1; (void)test2; (void)test3; (void)test4; (void)test5; + (void)blah1; (void)blah2; (void)blah3; (void)blah4; (void)blah5; +} + +media::TimeInterval CreateTimeInterval(int32_t aStart, int32_t aEnd) +{ + // Copy constructor test + media::Microseconds startus(aStart); + media::TimeUnit start(startus); + media::TimeUnit end; + // operator= test + end = media::Microseconds(aEnd); + media::TimeInterval ti(start, end); + return ti; +} + +media::TimeIntervals CreateTimeIntervals(int32_t aStart, int32_t aEnd) +{ + media::TimeIntervals test; + test += CreateTimeInterval(aStart, aEnd); + return test; +} + +TEST(IntervalSet, TimeIntervalsConstructors) +{ + const media::Microseconds start(1); + const media::Microseconds end(2); + const media::Microseconds fuzz; + + // Compiler exercise. + media::TimeInterval test1(start, end); + media::TimeInterval test2(test1); + media::TimeInterval test3(start, end, fuzz); + media::TimeInterval test4(test3); + media::TimeInterval test5 = CreateTimeInterval(start.mValue, end.mValue); + + media::TimeIntervals blah1(test1); + media::TimeIntervals blah2(blah1); + media::TimeIntervals blah3 = blah1 + test1; + media::TimeIntervals blah4 = test1 + blah1; + media::TimeIntervals blah5 = CreateTimeIntervals(start.mValue, end.mValue); + (void)test1; (void)test2; (void)test3; (void)test4; (void)test5; + (void)blah1; (void)blah2; (void)blah3; (void)blah4; (void)blah5; +} + +TEST(IntervalSet, Length) +{ + IntInterval i(15, 25); + EXPECT_EQ(10, i.Length()); +} + +TEST(IntervalSet, Intersection) +{ + IntInterval i0(10, 20); + IntInterval i1(15, 25); + IntInterval i = i0.Intersection(i1); + EXPECT_EQ(15, i.mStart); + EXPECT_EQ(20, i.mEnd); +} + +TEST(IntervalSet, Equals) +{ + IntInterval i0(10, 20); + IntInterval i1(10, 20); + EXPECT_EQ(i0, i1); + + IntInterval i2(5, 20); + EXPECT_NE(i0, i2); + + IntInterval i3(10, 15); + EXPECT_NE(i0, i2); +} + +TEST(IntervalSet, IntersectionIntervalSet) +{ + media::IntervalSet i0; + i0 += IntInterval(5, 10); + i0 += IntInterval(20, 25); + i0 += IntInterval(40, 60); + + media::IntervalSet i1; + i1.Add(IntInterval(7, 15)); + i1.Add(IntInterval(16, 27)); + i1.Add(IntInterval(45, 50)); + i1.Add(IntInterval(53, 57)); + + media::IntervalSet i = media::Intersection(i0, i1); + + EXPECT_EQ(4u, i.Length()); + + EXPECT_EQ(7, i[0].mStart); + EXPECT_EQ(10, i[0].mEnd); + + EXPECT_EQ(20, i[1].mStart); + EXPECT_EQ(25, i[1].mEnd); + + EXPECT_EQ(45, i[2].mStart); + EXPECT_EQ(50, i[2].mEnd); + + EXPECT_EQ(53, i[3].mStart); + EXPECT_EQ(57, i[3].mEnd); +} + +template +static void Compare(media::IntervalSet aI1, media::IntervalSet aI2) +{ + media::IntervalSet i1(aI1); + media::IntervalSet i2(aI1); + EXPECT_EQ(i1.Length(), i2.Length()); + if (i1.Length() != i2.Length()) { + return; + } + for (uint32_t i = 0; i < i1.Length(); i++) { + EXPECT_EQ(i1[i].mStart, i2[i].mStart); + EXPECT_EQ(i1[i].mEnd, i2[i].mEnd); + } +} + +TEST(IntervalSet, IntersectionNormalizedIntervalSet) +{ + media::IntervalSet i0; + i0 += IntInterval(5, 10); + i0 += IntInterval(8, 25); + i0 += IntInterval(24, 60); + + media::IntervalSet i1; + i1.Add(IntInterval(7, 15)); + i1.Add(IntInterval(10, 27)); + i1.Add(IntInterval(45, 50)); + i1.Add(IntInterval(53, 57)); + + // Compare intersections to ensure an intersection of normalized intervalsets + // is equal to the intersection of non-normalized intervalsets. + media::IntervalSet intersection = media::Intersection(i0, i1); + + media::IntervalSet i0_normalize(i0); + i0_normalize.Normalize(); + media::IntervalSet i1_normalize(i1); + i1_normalize.Normalize(); + media::IntervalSet intersection_normalize = + media::Intersection(i0_normalize, i1_normalize); + Compare(intersection, intersection_normalize); +} + +static void GeneratePermutations(media::IntervalSet aI1, + media::IntervalSet aI2) +{ + media::IntervalSet i_ref = media::Intersection(aI1, aI2); + // Test all permutations possible + std::vector comb1; + for (uint32_t i = 0; i < aI1.Length(); i++) { + comb1.push_back(i); + } + std::vector comb2; + for (uint32_t i = 0; i < aI2.Length(); i++) { + comb2.push_back(i); + } + + do { + do { + // Create intervals according to new indexes. + media::IntervalSet i_0; + for (uint32_t i = 0; i < comb1.size(); i++) { + i_0 += aI1[comb1[i]]; + } + media::IntervalSet i_1; + for (uint32_t i = 0; i < comb2.size(); i++) { + i_1 += aI2[comb2[i]]; + } + // Check intersections yield the same result. + Compare(i_0.Intersection(i_1), i_ref); + } while (std::next_permutation(comb2.begin(), comb2.end())); + } while (std::next_permutation(comb1.begin(), comb1.end())); +} + +TEST(IntervalSet, IntersectionUnorderedIntervalSet) +{ + media::IntervalSet i0; + i0 += IntInterval(5, 10); + i0 += IntInterval(20, 25); + i0 += IntInterval(40, 60); + + media::IntervalSet i1; + i1.Add(IntInterval(7, 15)); + i1.Add(IntInterval(16, 27)); + i1.Add(IntInterval(45, 50)); + i1.Add(IntInterval(53, 57)); + + GeneratePermutations(i0, i1); +} + +TEST(IntervalSet, IntersectionUnorderedNonNormalizedIntervalSet) +{ + media::IntervalSet i0; + i0 += IntInterval(5, 10); + i0 += IntInterval(8, 25); + i0 += IntInterval(24, 60); + + media::IntervalSet i1; + i1.Add(IntInterval(7, 15)); + i1.Add(IntInterval(10, 27)); + i1.Add(IntInterval(45, 50)); + i1.Add(IntInterval(53, 57)); + + GeneratePermutations(i0, i1); +} + +static media::IntervalSet Duplicate(const media::IntervalSet& aValue) +{ + media::IntervalSet value(aValue); + return value; +} + +TEST(IntervalSet, Normalize) +{ + media::IntervalSet i; + // Test IntervalSet + Interval operator. + i = i + IntInterval(20, 30); + // Test Internal + IntervalSet operator. + i = IntInterval(2, 7) + i; + // Test Interval + IntervalSet operator + i = IntInterval(1, 8) + i; + media::IntervalSet interval; + interval += IntInterval(5, 10); + // Test += with move. + i += Duplicate(interval); + // Test = with move and add with move. + i = Duplicate(interval) + i; + + media::IntervalSet o(i); + o.Normalize(); + + EXPECT_EQ(2u, o.Length()); + + EXPECT_EQ(1, o[0].mStart); + EXPECT_EQ(10, o[0].mEnd); + + EXPECT_EQ(20, o[1].mStart); + EXPECT_EQ(30, o[1].mEnd); +} + +TEST(IntervalSet, Union) +{ + media::IntervalSet i0; + i0 += IntInterval(5, 10); + i0 += IntInterval(20, 25); + i0 += IntInterval(40, 60); + + media::IntervalSet i1; + i1.Add(IntInterval(7, 15)); + i1.Add(IntInterval(16, 27)); + i1.Add(IntInterval(45, 50)); + i1.Add(IntInterval(53, 57)); + + media::IntervalSet i = media::Union(i0, i1); + + EXPECT_EQ(3u, i.Length()); + + EXPECT_EQ(5, i[0].mStart); + EXPECT_EQ(15, i[0].mEnd); + + EXPECT_EQ(16, i[1].mStart); + EXPECT_EQ(27, i[1].mEnd); + + EXPECT_EQ(40, i[2].mStart); + EXPECT_EQ(60, i[2].mEnd); +} + +TEST(IntervalSet, UnionNotOrdered) +{ + media::IntervalSet i0; + i0 += IntInterval(20, 25); + i0 += IntInterval(40, 60); + i0 += IntInterval(5, 10); + + media::IntervalSet i1; + i1.Add(IntInterval(16, 27)); + i1.Add(IntInterval(7, 15)); + i1.Add(IntInterval(53, 57)); + i1.Add(IntInterval(45, 50)); + + media::IntervalSet i = media::Union(i0, i1); + + EXPECT_EQ(3u, i.Length()); + + EXPECT_EQ(5, i[0].mStart); + EXPECT_EQ(15, i[0].mEnd); + + EXPECT_EQ(16, i[1].mStart); + EXPECT_EQ(27, i[1].mEnd); + + EXPECT_EQ(40, i[2].mStart); + EXPECT_EQ(60, i[2].mEnd); +} + +TEST(IntervalSet, NormalizeFuzz) +{ + media::IntervalSet i0; + i0 += IntInterval(11, 25, 0); + i0 += IntInterval(5, 10, 1); + i0 += IntInterval(40, 60, 1); + i0.Normalize(); + + EXPECT_EQ(2u, i0.Length()); + + EXPECT_EQ(5, i0[0].mStart); + EXPECT_EQ(25, i0[0].mEnd); + + EXPECT_EQ(40, i0[1].mStart); + EXPECT_EQ(60, i0[1].mEnd); +} + +TEST(IntervalSet, UnionFuzz) +{ + media::IntervalSet i0; + i0 += IntInterval(5, 10, 1); + i0 += IntInterval(11, 25, 0); + i0 += IntInterval(40, 60, 1); + + media::IntervalSet i1; + i1.Add(IntInterval(7, 15, 1)); + i1.Add(IntInterval(16, 27, 1)); + i1.Add(IntInterval(45, 50, 1)); + i1.Add(IntInterval(53, 57, 1)); + + media::IntervalSet i = media::Union(i0, i1); + + EXPECT_EQ(2u, i.Length()); + + EXPECT_EQ(5, i[0].mStart); + EXPECT_EQ(27, i[0].mEnd); + + EXPECT_EQ(40, i[1].mStart); + EXPECT_EQ(60, i[1].mEnd); + + i0.Normalize(); + EXPECT_EQ(2u, i0.Length()); + EXPECT_EQ(5, i0[0].mStart); + EXPECT_EQ(25, i0[0].mEnd); + EXPECT_EQ(40, i0[1].mStart); + EXPECT_EQ(60, i0[1].mEnd); +} + +TEST(IntervalSet, Contiguous) +{ + EXPECT_FALSE(IntInterval(5, 10).Contiguous(IntInterval(11, 25))); + EXPECT_TRUE(IntInterval(5, 10).Contiguous(IntInterval(10, 25))); + EXPECT_TRUE(IntInterval(5, 10, 1).Contiguous(IntInterval(11, 25))); + EXPECT_TRUE(IntInterval(5, 10).Contiguous(IntInterval(11, 25, 1))); +} + +TEST(IntervalSet, TimeRangesSeconds) +{ + media::TimeIntervals i0; + i0 += media::TimeInterval(media::TimeUnit::FromSeconds(20), media::TimeUnit::FromSeconds(25)); + i0 += media::TimeInterval(media::TimeUnit::FromSeconds(40), media::TimeUnit::FromSeconds(60)); + i0 += media::TimeInterval(media::TimeUnit::FromSeconds(5), media::TimeUnit::FromSeconds(10)); + + media::TimeIntervals i1; + i1.Add(media::TimeInterval(media::TimeUnit::FromSeconds(16), media::TimeUnit::FromSeconds(27))); + i1.Add(media::TimeInterval(media::TimeUnit::FromSeconds(7), media::TimeUnit::FromSeconds(15))); + i1.Add(media::TimeInterval(media::TimeUnit::FromSeconds(53), media::TimeUnit::FromSeconds(57))); + i1.Add(media::TimeInterval(media::TimeUnit::FromSeconds(45), media::TimeUnit::FromSeconds(50))); + + media::TimeIntervals i(i0 + i1); + nsRefPtr tr = new dom::TimeRanges(); + i.ToTimeRanges(tr); + EXPECT_EQ(tr->Length(), i.Length()); + for (dom::TimeRanges::index_type index = 0; index < tr->Length(); index++) { + ErrorResult rv; + EXPECT_EQ(tr->Start(index, rv), i[index].mStart.ToSeconds()); + EXPECT_EQ(tr->Start(index, rv), i.Start(index).ToSeconds()); + EXPECT_EQ(tr->End(index, rv), i[index].mEnd.ToSeconds()); + EXPECT_EQ(tr->End(index, rv), i.End(index).ToSeconds()); + } + + i.Normalize(); + tr->Normalize(); + EXPECT_EQ(tr->Length(), i.Length()); + for (dom::TimeRanges::index_type index = 0; index < tr->Length(); index++) { + ErrorResult rv; + EXPECT_EQ(tr->Start(index, rv), i[index].mStart.ToSeconds()); + EXPECT_EQ(tr->Start(index, rv), i.Start(index).ToSeconds()); + EXPECT_EQ(tr->End(index, rv), i[index].mEnd.ToSeconds()); + EXPECT_EQ(tr->End(index, rv), i.End(index).ToSeconds()); + } +} + +static void CheckTimeRanges(dom::TimeRanges* aTr, const media::TimeIntervals& aTi) +{ + EXPECT_EQ(aTr->Length(), aTi.Length()); + for (dom::TimeRanges::index_type i = 0; i < aTr->Length(); i++) { + ErrorResult rv; + EXPECT_EQ(aTr->Start(i, rv), aTi[i].mStart.ToSeconds()); + EXPECT_EQ(aTr->Start(i, rv), aTi.Start(i).ToSeconds()); + EXPECT_EQ(aTr->End(i, rv), aTi[i].mEnd.ToSeconds()); + EXPECT_EQ(aTr->End(i, rv), aTi.End(i).ToSeconds()); + } +} + +TEST(IntervalSet, TimeRangesConversion) +{ + nsRefPtr tr = new dom::TimeRanges(); + tr->Add(20, 25); + tr->Add(40, 60); + tr->Add(5, 10); + tr->Add(16, 27); + tr->Add(53, 57); + tr->Add(45, 50); + + // explicit copy constructor + media::TimeIntervals i1(tr); + CheckTimeRanges(tr, i1); + + // static FromTimeRanges + media::TimeIntervals i2 = media::TimeIntervals::FromTimeRanges(tr); + CheckTimeRanges(tr, i2); + + media::TimeIntervals i3; + // operator=(TimeRanges*) + i3 = tr; + CheckTimeRanges(tr, i3); + + i1.Normalize(); + tr->Normalize(); + + CheckTimeRanges(tr, i1); + + // operator= test + i1 = tr.get(); + CheckTimeRanges(tr, i1); +} + +TEST(IntervalSet, TimeRangesMicroseconds) +{ + media::TimeIntervals i0; + + // Test media::Microseconds and TimeUnit interchangeability (compilation only) + media::TimeUnit time1{media::Microseconds(5)}; + media::Microseconds microseconds(5); + media::TimeUnit time2 = media::TimeUnit(microseconds); + EXPECT_EQ(time1, time2); + + i0 += media::TimeInterval(media::Microseconds(20), media::Microseconds(25)); + i0 += media::TimeInterval(media::Microseconds(40), media::Microseconds(60)); + i0 += media::TimeInterval(media::Microseconds(5), media::Microseconds(10)); + + media::TimeIntervals i1; + i1.Add(media::TimeInterval(media::Microseconds(16), media::Microseconds(27))); + i1.Add(media::TimeInterval(media::Microseconds(7), media::Microseconds(15))); + i1.Add(media::TimeInterval(media::Microseconds(53), media::Microseconds(57))); + i1.Add(media::TimeInterval(media::Microseconds(45), media::Microseconds(50))); + + media::TimeIntervals i(i0 + i1); + nsRefPtr tr = new dom::TimeRanges(); + i.ToTimeRanges(tr); + EXPECT_EQ(tr->Length(), i.Length()); + for (dom::TimeRanges::index_type index = 0; index < tr->Length(); index++) { + ErrorResult rv; + EXPECT_EQ(tr->Start(index, rv), i[index].mStart.ToSeconds()); + EXPECT_EQ(tr->Start(index, rv), i.Start(index).ToSeconds()); + EXPECT_EQ(tr->End(index, rv), i[index].mEnd.ToSeconds()); + EXPECT_EQ(tr->End(index, rv), i.End(index).ToSeconds()); + } + + i.Normalize(); + tr->Normalize(); + EXPECT_EQ(tr->Length(), i.Length()); + for (dom::TimeRanges::index_type index = 0; index < tr->Length(); index++) { + ErrorResult rv; + EXPECT_EQ(tr->Start(index, rv), i[index].mStart.ToSeconds()); + EXPECT_EQ(tr->Start(index, rv), i.Start(index).ToSeconds()); + EXPECT_EQ(tr->End(index, rv), i[index].mEnd.ToSeconds()); + EXPECT_EQ(tr->End(index, rv), i.End(index).ToSeconds()); + } +} + +template +class Foo +{ +public: + Foo() + : mArg1(1) + , mArg2(2) + , mArg3(3) + {} + + Foo(T a1, T a2, T a3) + : mArg1(a1) + , mArg2(a2) + , mArg3(a3) + {} + + Foo operator+ (const Foo& aOther) const + { + Foo blah; + blah.mArg1 += aOther.mArg1; + blah.mArg2 += aOther.mArg2; + blah.mArg3 += aOther.mArg3; + return blah; + } + Foo operator- (const Foo& aOther) const + { + Foo blah; + blah.mArg1 -= aOther.mArg1; + blah.mArg2 -= aOther.mArg2; + blah.mArg3 -= aOther.mArg3; + return blah; + } + bool operator< (const Foo& aOther) const + { + return mArg1 < aOther.mArg1; + } + bool operator== (const Foo& aOther) const + { + return mArg1 == aOther.mArg1; + } + bool operator<= (const Foo& aOther) const + { + return mArg1 <= aOther.mArg1; + } + +private: + int32_t mArg1; + int32_t mArg2; + int32_t mArg3; +}; + +TEST(IntervalSet, FooIntervalSet) +{ + media::Interval> i(Foo(), Foo(4,5,6)); + media::IntervalSet> is; + is += i; + is += i; + is.Add(i); + is = is + i; + is = i + is; + EXPECT_EQ(5u, is.Length()); + is.Normalize(); + EXPECT_EQ(1u, is.Length()); + EXPECT_EQ(Foo(), is[0].mStart); + EXPECT_EQ(Foo(4,5,6), is[0].mEnd); +} diff --git a/dom/media/gtest/moz.build b/dom/media/gtest/moz.build index 5abc1bb1901..7311123ec8d 100644 --- a/dom/media/gtest/moz.build +++ b/dom/media/gtest/moz.build @@ -9,6 +9,7 @@ UNIFIED_SOURCES += [ 'TestAudioCompactor.cpp', 'TestGMPCrossOrigin.cpp', 'TestGMPRemoveAndDelete.cpp', + 'TestIntervalSet.cpp', 'TestMP4Demuxer.cpp', 'TestMP4Reader.cpp', 'TestTrackEncoder.cpp', diff --git a/dom/media/moz.build b/dom/media/moz.build index fdc6fe67494..8ccd120ba1b 100644 --- a/dom/media/moz.build +++ b/dom/media/moz.build @@ -113,6 +113,7 @@ EXPORTS += [ 'EncodedBufferCache.h', 'FileBlockCache.h', 'GraphDriver.h', + 'Intervals.h', 'Latency.h', 'MediaCache.h', 'MediaData.h', @@ -156,6 +157,14 @@ EXPORTS.mozilla += [ 'MediaManager.h', ] +EXPORTS.mozilla.media.webrtc += [ + 'webrtc/WebrtcGlobal.h', +] + +IPDL_SOURCES += [ + 'webrtc/PWebrtcGlobal.ipdl' +] + if CONFIG['MOZ_B2G']: EXPORTS.mozilla += [ 'MediaPermissionGonk.h', diff --git a/dom/media/webm/IntelWebMVideoDecoder.h b/dom/media/webm/IntelWebMVideoDecoder.h index cc342847c80..13e7409bc9d 100644 --- a/dom/media/webm/IntelWebMVideoDecoder.h +++ b/dom/media/webm/IntelWebMVideoDecoder.h @@ -43,6 +43,11 @@ public: virtual void InputExhausted() override; virtual void Error() override; + virtual bool OnReaderTaskQueue() override + { + return mReader->OnTaskQueue(); + } + IntelWebMVideoDecoder(WebMReader* aReader); ~IntelWebMVideoDecoder(); diff --git a/media/webrtc/signaling/src/peerconnection/PWebrtcGlobal.ipdl b/dom/media/webrtc/PWebrtcGlobal.ipdl similarity index 100% rename from media/webrtc/signaling/src/peerconnection/PWebrtcGlobal.ipdl rename to dom/media/webrtc/PWebrtcGlobal.ipdl diff --git a/media/webrtc/signaling/src/peerconnection/WebrtcGlobal.h b/dom/media/webrtc/WebrtcGlobal.h similarity index 100% rename from media/webrtc/signaling/src/peerconnection/WebrtcGlobal.h rename to dom/media/webrtc/WebrtcGlobal.h diff --git a/dom/plugins/ipc/PluginInstanceChild.cpp b/dom/plugins/ipc/PluginInstanceChild.cpp index e978307323c..cc9a24d5e4d 100644 --- a/dom/plugins/ipc/PluginInstanceChild.cpp +++ b/dom/plugins/ipc/PluginInstanceChild.cpp @@ -394,7 +394,9 @@ PluginInstanceChild::NPN_GetValue(NPNVariable aVar, if (!CallNPN_GetValue_NPNVdocumentOrigin(&v, &result)) { return NPERR_GENERIC_ERROR; } - if (result == NPERR_NO_ERROR) { + if (result == NPERR_NO_ERROR || + (GetQuirks() & + PluginModuleChild::QUIRK_FLASH_RETURN_EMPTY_DOCUMENT_ORIGIN)) { *static_cast(aValue) = ToNewCString(v); } return result; diff --git a/dom/plugins/ipc/PluginModuleChild.cpp b/dom/plugins/ipc/PluginModuleChild.cpp index 54d1ef22663..6fdb97144b7 100644 --- a/dom/plugins/ipc/PluginModuleChild.cpp +++ b/dom/plugins/ipc/PluginModuleChild.cpp @@ -2124,15 +2124,18 @@ PluginModuleChild::InitQuirksModes(const nsCString& aMimeType) #endif } -#ifdef OS_WIN if (specialType == nsPluginHost::eSpecialType_Flash) { + mQuirks |= QUIRK_FLASH_RETURN_EMPTY_DOCUMENT_ORIGIN; +#ifdef OS_WIN mQuirks |= QUIRK_WINLESS_TRACKPOPUP_HOOK; mQuirks |= QUIRK_FLASH_THROTTLE_WMUSER_EVENTS; mQuirks |= QUIRK_FLASH_HOOK_SETLONGPTR; mQuirks |= QUIRK_FLASH_HOOK_GETWINDOWINFO; mQuirks |= QUIRK_FLASH_FIXUP_MOUSE_CAPTURE; +#endif } +#ifdef OS_WIN // QuickTime plugin usually loaded with audio/mpeg mimetype NS_NAMED_LITERAL_CSTRING(quicktime, "npqtplugin"); if (FindInReadable(quicktime, mPluginFilename)) { diff --git a/dom/plugins/ipc/PluginModuleChild.h b/dom/plugins/ipc/PluginModuleChild.h index ded7f426a44..47a9d940167 100644 --- a/dom/plugins/ipc/PluginModuleChild.h +++ b/dom/plugins/ipc/PluginModuleChild.h @@ -282,6 +282,10 @@ public: // CGContextRef we pass to it in NPP_HandleEvent(NPCocoaEventDrawRect) // outside of that call. See bug 804606. QUIRK_FLASH_AVOID_CGMODE_CRASHES = 1 << 10, + // Work around a Flash bug where it fails to check the error code of a + // NPN_GetValue(NPNVdocumentOrigin) call before trying to dereference + // its char* output. + QUIRK_FLASH_RETURN_EMPTY_DOCUMENT_ORIGIN = 1 << 11, }; int GetQuirks() { return mQuirks; } diff --git a/dom/xul/XULDocument.cpp b/dom/xul/XULDocument.cpp index be7f08b9a26..cea57fe6324 100644 --- a/dom/xul/XULDocument.cpp +++ b/dom/xul/XULDocument.cpp @@ -135,35 +135,37 @@ PRLogModuleInfo* XULDocument::gXULLog; //---------------------------------------------------------------------- -struct BroadcasterMapEntry : public PLDHashEntryHdr { - Element* mBroadcaster; // [WEAK] - nsSmallVoidArray mListeners; // [OWNING] of BroadcastListener objects -}; - struct BroadcastListener { nsWeakPtr mListener; nsCOMPtr mAttribute; }; +struct BroadcasterMapEntry : public PLDHashEntryHdr +{ + Element* mBroadcaster; // [WEAK] + nsTArray mListeners; // [OWNING] of BroadcastListener objects +}; + Element* nsRefMapEntry::GetFirstElement() { - return static_cast(mRefContentList.SafeElementAt(0)); + return mRefContentList.SafeElementAt(0); } void nsRefMapEntry::AppendAll(nsCOMArray* aElements) { - for (int32_t i = 0; i < mRefContentList.Count(); ++i) { - aElements->AppendObject(static_cast(mRefContentList[i])); + for (size_t i = 0; i < mRefContentList.Length(); ++i) { + aElements->AppendObject(mRefContentList[i]); } } bool nsRefMapEntry::AddElement(Element* aElement) { - if (mRefContentList.IndexOf(aElement) >= 0) + if (mRefContentList.Contains(aElement)) { return true; + } return mRefContentList.AppendElement(aElement); } @@ -171,7 +173,7 @@ bool nsRefMapEntry::RemoveElement(Element* aElement) { mRefContentList.RemoveElement(aElement); - return mRefContentList.Count() == 0; + return mRefContentList.IsEmpty(); } //---------------------------------------------------------------------- @@ -618,13 +620,14 @@ ClearBroadcasterMapEntry(PLDHashTable* aTable, PLDHashEntryHdr* aEntry) { BroadcasterMapEntry* entry = static_cast(aEntry); - for (int32_t i = entry->mListeners.Count() - 1; i >= 0; --i) { - delete (BroadcastListener*)entry->mListeners[i]; + for (size_t i = entry->mListeners.Length() - 1; i != (size_t)-1; --i) { + delete entry->mListeners[i]; } + entry->mListeners.Clear(); // N.B. that we need to manually run the dtor because we - // constructed the nsSmallVoidArray object in-place. - entry->mListeners.~nsSmallVoidArray(); + // constructed the nsTArray object in-place. + entry->mListeners.~nsTArray(); } static bool @@ -786,26 +789,22 @@ XULDocument::AddBroadcastListenerFor(Element& aBroadcaster, Element& aListener, entry->mBroadcaster = &aBroadcaster; - // N.B. placement new to construct the nsSmallVoidArray object - // in-place - new (&entry->mListeners) nsSmallVoidArray(); + // N.B. placement new to construct the nsTArray object in-place + new (&entry->mListeners) nsTArray(); } // Only add the listener if it's not there already! nsCOMPtr attr = do_GetAtom(aAttr); - BroadcastListener* bl; - for (int32_t i = entry->mListeners.Count() - 1; i >= 0; --i) { - bl = static_cast(entry->mListeners[i]); - + for (size_t i = entry->mListeners.Length() - 1; i != (size_t)-1; --i) { + BroadcastListener* bl = entry->mListeners[i]; nsCOMPtr blListener = do_QueryReferent(bl->mListener); if (blListener == &aListener && bl->mAttribute == attr) return; } - bl = new BroadcastListener; - + BroadcastListener* bl = new BroadcastListener; bl->mListener = do_GetWeakReference(&aListener); bl->mAttribute = attr; @@ -842,17 +841,15 @@ XULDocument::RemoveBroadcastListenerFor(Element& aBroadcaster, if (entry) { nsCOMPtr attr = do_GetAtom(aAttr); - for (int32_t i = entry->mListeners.Count() - 1; i >= 0; --i) { - BroadcastListener* bl = - static_cast(entry->mListeners[i]); - + for (size_t i = entry->mListeners.Length() - 1; i != (size_t)-1; --i) { + BroadcastListener* bl = entry->mListeners[i]; nsCOMPtr blListener = do_QueryReferent(bl->mListener); if (blListener == &aListener && bl->mAttribute == attr) { entry->mListeners.RemoveElementAt(i); delete bl; - if (entry->mListeners.Count() == 0) + if (entry->mListeners.IsEmpty()) PL_DHashTableRemove(mBroadcasterMap, &aBroadcaster); break; @@ -967,11 +964,8 @@ XULDocument::AttributeChanged(nsIDocument* aDocument, nsAutoString value; bool attrSet = aElement->GetAttr(kNameSpaceID_None, aAttribute, value); - int32_t i; - for (i = entry->mListeners.Count() - 1; i >= 0; --i) { - BroadcastListener* bl = - static_cast(entry->mListeners[i]); - + for (size_t i = entry->mListeners.Length() - 1; i != (size_t)-1; --i) { + BroadcastListener* bl = entry->mListeners[i]; if ((bl->mAttribute == aAttribute) || (bl->mAttribute == nsGkAtoms::_asterisk)) { nsCOMPtr listenerEl @@ -4157,10 +4151,8 @@ XULDocument::BroadcastAttributeChangeFromOverlay(nsIContent* aNode, return rv; // We've got listeners: push the value. - int32_t i; - for (i = entry->mListeners.Count() - 1; i >= 0; --i) { - BroadcastListener* bl = static_cast - (entry->mListeners[i]); + for (size_t i = entry->mListeners.Length() - 1; i != (size_t)-1; --i) { + BroadcastListener* bl = entry->mListeners[i]; if ((bl->mAttribute != aAttribute) && (bl->mAttribute != nsGkAtoms::_asterisk)) diff --git a/dom/xul/XULDocument.h b/dom/xul/XULDocument.h index a3e08c2b5fe..4275a728e84 100644 --- a/dom/xul/XULDocument.h +++ b/dom/xul/XULDocument.h @@ -75,7 +75,7 @@ public: bool RemoveElement(mozilla::dom::Element* aElement); private: - nsSmallVoidArray mRefContentList; + nsTArray mRefContentList; }; /** diff --git a/gfx/2d/DrawTargetD2D1.cpp b/gfx/2d/DrawTargetD2D1.cpp index 3e3ea376335..32e21701f90 100644 --- a/gfx/2d/DrawTargetD2D1.cpp +++ b/gfx/2d/DrawTargetD2D1.cpp @@ -788,9 +788,21 @@ DrawTargetD2D1::Init(ID3D11Texture2D* aTexture, SurfaceFormat aFormat) return false; } + // This single solid color brush system is not very 'threadsafe', however, + // issueing multiple drawing commands simultaneously to a single drawtarget + // from multiple threads is unexpected since there's no way to guarantee + // ordering in that situation anyway. + hr = mDC->CreateSolidColorBrush(D2D1::ColorF(0, 0), byRef(mSolidColorBrush)); + + if (FAILED(hr)) { + gfxCriticalError() << "[D2D1.1] Failure creating solid color brush."; + return false; + } + mDC->SetTarget(mBitmap); mDC->BeginDraw(); + return true; } @@ -843,6 +855,13 @@ DrawTargetD2D1::Init(const IntSize &aSize, SurfaceFormat aFormat) mDC->SetTarget(mBitmap); + hr = mDC->CreateSolidColorBrush(D2D1::ColorF(0, 0), byRef(mSolidColorBrush)); + + if (FAILED(hr)) { + gfxCriticalError() << "[D2D1.1] Failure creating solid color brush."; + return false; + } + mDC->BeginDraw(); mDC->Clear(); @@ -1262,8 +1281,14 @@ DrawTargetD2D1::PopClipsFromDC(ID2D1DeviceContext *aDC) TemporaryRef DrawTargetD2D1::CreateTransparentBlackBrush() { - RefPtr brush; - mDC->CreateSolidColorBrush(D2D1::ColorF(0, 0), byRef(brush)); + return GetSolidColorBrush(D2D1::ColorF(0, 0)); +} + +TemporaryRef +DrawTargetD2D1::GetSolidColorBrush(const D2D_COLOR_F& aColor) +{ + RefPtr brush = mSolidColorBrush; + brush->SetColor(aColor); return brush; } @@ -1271,19 +1296,12 @@ TemporaryRef DrawTargetD2D1::CreateBrushForPattern(const Pattern &aPattern, Float aAlpha) { if (!IsPatternSupportedByD2D(aPattern)) { - RefPtr colBrush; - mDC->CreateSolidColorBrush(D2D1::ColorF(1.0f, 1.0f, 1.0f, 1.0f), byRef(colBrush)); - return colBrush.forget(); + return GetSolidColorBrush(D2D1::ColorF(1.0f, 1.0f, 1.0f, 1.0f)); } if (aPattern.GetType() == PatternType::COLOR) { - RefPtr colBrush; Color color = static_cast(&aPattern)->mColor; - mDC->CreateSolidColorBrush(D2D1::ColorF(color.r, color.g, - color.b, color.a), - D2D1::BrushProperties(aAlpha), - byRef(colBrush)); - return colBrush.forget(); + return GetSolidColorBrush(D2D1::ColorF(color.r, color.g, color.b, color.a * aAlpha)); } if (aPattern.GetType() == PatternType::LINEAR_GRADIENT) { RefPtr gradBrush; @@ -1298,14 +1316,11 @@ DrawTargetD2D1::CreateBrushForPattern(const Pattern &aPattern, Float aAlpha) } if (pat->mBegin == pat->mEnd) { - RefPtr colBrush; uint32_t stopCount = stops->mStopCollection->GetGradientStopCount(); vector d2dStops(stopCount); stops->mStopCollection->GetGradientStops(&d2dStops.front(), stopCount); - mDC->CreateSolidColorBrush(d2dStops.back().color, - D2D1::BrushProperties(aAlpha), - byRef(colBrush)); - return colBrush.forget(); + d2dStops.back().color.a *= aAlpha; + return GetSolidColorBrush(d2dStops.back().color); } mDC->CreateLinearGradientBrush(D2D1::LinearGradientBrushProperties(D2DPoint(pat->mBegin), @@ -1391,6 +1406,12 @@ DrawTargetD2D1::CreateBrushForPattern(const Pattern &aPattern, Float aAlpha) D2DInterpolationMode(pat->mFilter)), D2D1::BrushProperties(aAlpha, D2DMatrix(mat)), byRef(imageBrush)); + + if (!imageBrush) { + gfxWarning() << "Couldn't create image brush!"; + return CreateTransparentBlackBrush(); + } + return imageBrush.forget(); } diff --git a/gfx/2d/DrawTargetD2D1.h b/gfx/2d/DrawTargetD2D1.h index b7f941dcfc7..f6252150d13 100644 --- a/gfx/2d/DrawTargetD2D1.h +++ b/gfx/2d/DrawTargetD2D1.h @@ -183,6 +183,7 @@ private: void PopClipsFromDC(ID2D1DeviceContext *aDC); TemporaryRef CreateTransparentBlackBrush(); + TemporaryRef GetSolidColorBrush(const D2D_COLOR_F& aColor); TemporaryRef CreateBrushForPattern(const Pattern &aPattern, Float aAlpha = 1.0f); void PushD2DLayer(ID2D1DeviceContext *aDC, ID2D1Geometry *aGeometry, const D2D1_MATRIX_3X2_F &aTransform); @@ -201,6 +202,8 @@ private: RefPtr mTempBitmap; RefPtr mBlendEffect; + RefPtr mSolidColorBrush; + // We store this to prevent excessive SetTextRenderingParams calls. RefPtr mTextRenderingParams; diff --git a/gfx/layers/ipc/CompositorParent.cpp b/gfx/layers/ipc/CompositorParent.cpp index a9cc1647352..9c8f7985721 100644 --- a/gfx/layers/ipc/CompositorParent.cpp +++ b/gfx/layers/ipc/CompositorParent.cpp @@ -661,7 +661,14 @@ CompositorParent::CompositorParent(nsIWidget* aWidget, sIndirectLayerTrees[mRootLayerTreeID].mParent = this; } - if (gfxPrefs::AsyncPanZoomEnabled()) { + if (gfxPrefs::AsyncPanZoomEnabled() && +#if defined(XP_WIN) || defined(MOZ_WIDGET_COCOA) || defined(MOZ_WIDGET_GTK) + // For desktop platforms we only want to use APZ in e10s-enabled windows. + // If we ever get input events off the main thread we can consider + // relaxing this requirement. + aWidget->IsMultiProcessWindow() && +#endif + (aWidget->WindowType() == eWindowType_toplevel || aWidget->WindowType() == eWindowType_child)) { mApzcTreeManager = new APZCTreeManager(); } diff --git a/gfx/src/FilterSupport.cpp b/gfx/src/FilterSupport.cpp index 88f5f34c50a..e324bc4ca13 100644 --- a/gfx/src/FilterSupport.cpp +++ b/gfx/src/FilterSupport.cpp @@ -1435,7 +1435,7 @@ FilterSupport::PostFilterExtentsForPrimitive(const FilterPrimitiveDescription& a switch (aDescription.Type()) { case PrimitiveType::Empty: - return nsIntRect(); + return IntRect(); case PrimitiveType::Composite: { @@ -1472,7 +1472,7 @@ FilterSupport::PostFilterExtentsForPrimitive(const FilterPrimitiveDescription& a case PrimitiveType::Flood: { if (atts.GetColor(eFloodColor).a == 0.0f) { - return nsIntRect(); + return IntRect(); } return aDescription.PrimitiveSubregion(); } @@ -1583,7 +1583,7 @@ SourceNeededRegionForPrimitive(const FilterPrimitiveDescription& aDescription, } case PrimitiveType::Tile: - return nsIntRect(INT32_MIN/2, INT32_MIN/2, INT32_MAX, INT32_MAX); + return IntRect(INT32_MIN/2, INT32_MIN/2, INT32_MAX, INT32_MAX); case PrimitiveType::ConvolveMatrix: { diff --git a/gfx/src/nsRect.cpp b/gfx/src/nsRect.cpp index d1a3dd63914..b94d844e43e 100644 --- a/gfx/src/nsRect.cpp +++ b/gfx/src/nsRect.cpp @@ -16,7 +16,7 @@ static_assert((int(NS_SIDE_TOP) == 0) && "The mozilla::css::Side sequence must match the nsMargin nscoord sequence"); nsRect -ToAppUnits(const nsIntRect& aRect, nscoord aAppUnitsPerPixel) +ToAppUnits(const mozilla::gfx::IntRect& aRect, nscoord aAppUnitsPerPixel) { return nsRect(NSIntPixelsToAppUnits(aRect.x, aAppUnitsPerPixel), NSIntPixelsToAppUnits(aRect.y, aAppUnitsPerPixel), @@ -24,8 +24,8 @@ ToAppUnits(const nsIntRect& aRect, nscoord aAppUnitsPerPixel) NSIntPixelsToAppUnits(aRect.height, aAppUnitsPerPixel)); } -const nsIntRect& GetMaxSizedIntRect() { - static const nsIntRect r(0, 0, INT32_MAX, INT32_MAX); +const mozilla::gfx::IntRect& GetMaxSizedIntRect() { + static const mozilla::gfx::IntRect r(0, 0, INT32_MAX, INT32_MAX); return r; } diff --git a/gfx/src/nsRect.h b/gfx/src/nsRect.h index c840386dc24..ee62a0af078 100644 --- a/gfx/src/nsRect.h +++ b/gfx/src/nsRect.h @@ -149,27 +149,27 @@ struct NS_GFX nsRect : MOZ_WARN_UNUSED_RESULT inline nsRect ScaleToOtherAppUnitsRoundIn(int32_t aFromAPP, int32_t aToAPP) const; - MOZ_WARN_UNUSED_RESULT inline nsIntRect + MOZ_WARN_UNUSED_RESULT inline mozilla::gfx::IntRect ScaleToNearestPixels(float aXScale, float aYScale, nscoord aAppUnitsPerPixel) const; - MOZ_WARN_UNUSED_RESULT inline nsIntRect + MOZ_WARN_UNUSED_RESULT inline mozilla::gfx::IntRect ToNearestPixels(nscoord aAppUnitsPerPixel) const; // Note: this can turn an empty rectangle into a non-empty rectangle - MOZ_WARN_UNUSED_RESULT inline nsIntRect + MOZ_WARN_UNUSED_RESULT inline mozilla::gfx::IntRect ScaleToOutsidePixels(float aXScale, float aYScale, nscoord aAppUnitsPerPixel) const; // Note: this can turn an empty rectangle into a non-empty rectangle - MOZ_WARN_UNUSED_RESULT inline nsIntRect + MOZ_WARN_UNUSED_RESULT inline mozilla::gfx::IntRect ToOutsidePixels(nscoord aAppUnitsPerPixel) const; - MOZ_WARN_UNUSED_RESULT inline nsIntRect + MOZ_WARN_UNUSED_RESULT inline mozilla::gfx::IntRect ScaleToInsidePixels(float aXScale, float aYScale, nscoord aAppUnitsPerPixel) const; - MOZ_WARN_UNUSED_RESULT inline nsIntRect + MOZ_WARN_UNUSED_RESULT inline mozilla::gfx::IntRect ToInsidePixels(nscoord aAppUnitsPerPixel) const; // This is here only to keep IPDL-generated code happy. DO NOT USE. @@ -220,11 +220,11 @@ nsRect::ScaleToOtherAppUnitsRoundIn(int32_t aFromAPP, int32_t aToAPP) const } // scale the rect but round to preserve centers -inline nsIntRect +inline mozilla::gfx::IntRect nsRect::ScaleToNearestPixels(float aXScale, float aYScale, nscoord aAppUnitsPerPixel) const { - nsIntRect rect; + mozilla::gfx::IntRect rect; rect.x = NSToIntRoundUp(NSAppUnitsToDoublePixels(x, aAppUnitsPerPixel) * aXScale); rect.y = NSToIntRoundUp(NSAppUnitsToDoublePixels(y, aAppUnitsPerPixel) * aYScale); // Avoid negative widths and heights due to overflow @@ -236,11 +236,11 @@ nsRect::ScaleToNearestPixels(float aXScale, float aYScale, } // scale the rect but round to smallest containing rect -inline nsIntRect +inline mozilla::gfx::IntRect nsRect::ScaleToOutsidePixels(float aXScale, float aYScale, nscoord aAppUnitsPerPixel) const { - nsIntRect rect; + mozilla::gfx::IntRect rect; rect.x = NSToIntFloor(NSAppUnitsToFloatPixels(x, float(aAppUnitsPerPixel)) * aXScale); rect.y = NSToIntFloor(NSAppUnitsToFloatPixels(y, float(aAppUnitsPerPixel)) * aYScale); // Avoid negative widths and heights due to overflow @@ -252,11 +252,11 @@ nsRect::ScaleToOutsidePixels(float aXScale, float aYScale, } // scale the rect but round to largest contained rect -inline nsIntRect +inline mozilla::gfx::IntRect nsRect::ScaleToInsidePixels(float aXScale, float aYScale, nscoord aAppUnitsPerPixel) const { - nsIntRect rect; + mozilla::gfx::IntRect rect; rect.x = NSToIntCeil(NSAppUnitsToFloatPixels(x, float(aAppUnitsPerPixel)) * aXScale); rect.y = NSToIntCeil(NSAppUnitsToFloatPixels(y, float(aAppUnitsPerPixel)) * aYScale); // Avoid negative widths and heights due to overflow @@ -267,29 +267,29 @@ nsRect::ScaleToInsidePixels(float aXScale, float aYScale, return rect; } -inline nsIntRect +inline mozilla::gfx::IntRect nsRect::ToNearestPixels(nscoord aAppUnitsPerPixel) const { return ScaleToNearestPixels(1.0f, 1.0f, aAppUnitsPerPixel); } -inline nsIntRect +inline mozilla::gfx::IntRect nsRect::ToOutsidePixels(nscoord aAppUnitsPerPixel) const { return ScaleToOutsidePixels(1.0f, 1.0f, aAppUnitsPerPixel); } -inline nsIntRect +inline mozilla::gfx::IntRect nsRect::ToInsidePixels(nscoord aAppUnitsPerPixel) const { return ScaleToInsidePixels(1.0f, 1.0f, aAppUnitsPerPixel); } -const nsIntRect& GetMaxSizedIntRect(); +const mozilla::gfx::IntRect& GetMaxSizedIntRect(); // app units are integer multiples of pixels, so no rounding needed nsRect -ToAppUnits(const nsIntRect& aRect, nscoord aAppUnitsPerPixel); +ToAppUnits(const mozilla::gfx::IntRect& aRect, nscoord aAppUnitsPerPixel); #ifdef DEBUG // Diagnostics diff --git a/gfx/src/nsRegion.cpp b/gfx/src/nsRegion.cpp index 67e6630df80..f00a8b1122c 100644 --- a/gfx/src/nsRegion.cpp +++ b/gfx/src/nsRegion.cpp @@ -606,20 +606,20 @@ nsRegion& nsRegion::ScaleInverseRoundOut (float aXScale, float aYScale) return *this; } -static nsIntRect -TransformRect(const nsIntRect& aRect, const gfx3DMatrix& aTransform) +static mozilla::gfx::IntRect +TransformRect(const mozilla::gfx::IntRect& aRect, const gfx3DMatrix& aTransform) { if (aRect.IsEmpty()) { - return nsIntRect(); + return mozilla::gfx::IntRect(); } gfxRect rect(aRect.x, aRect.y, aRect.width, aRect.height); rect = aTransform.TransformBounds(rect); rect.RoundOut(); - nsIntRect intRect; + mozilla::gfx::IntRect intRect; if (!gfxUtils::GfxRectToIntRect(rect, &intRect)) { - return nsIntRect(); + return mozilla::gfx::IntRect(); } return intRect; @@ -699,7 +699,7 @@ nsIntRegion nsRegion::ToPixels (nscoord aAppUnitsPerPixel, bool aOutsidePixels) pixman_box32_t *boxes = pixman_region32_rectangles(®ion.mImpl, &n); for (int i=0; iScaleToNearestPixels(aScaleX, aScaleY, aAppUnitsPerPixel); result.Or(result, deviceRect); } @@ -747,7 +747,7 @@ nsIntRegion nsRegion::ScaleToOutsidePixels (float aScaleX, float aScaleY, nsRegionRectIterator rgnIter(*this); const nsRect* currentRect; while ((currentRect = rgnIter.Next())) { - nsIntRect deviceRect = + mozilla::gfx::IntRect deviceRect = currentRect->ScaleToOutsidePixels(aScaleX, aScaleY, aAppUnitsPerPixel); result.Or(result, deviceRect); } @@ -778,14 +778,14 @@ nsIntRegion nsRegion::ScaleToInsidePixels (float aScaleX, float aScaleY, nsIntRegion intRegion; if (n) { nsRect first = BoxToRect(boxes[0]); - nsIntRect firstDeviceRect = + mozilla::gfx::IntRect firstDeviceRect = first.ScaleToInsidePixels(aScaleX, aScaleY, aAppUnitsPerPixel); for (int i=1; i +class NS_GFX nsIntRegion : public mozilla::gfx::BaseIntRegion { public: // Forward constructors. nsIntRegion() {} - MOZ_IMPLICIT nsIntRegion(const nsIntRect& aRect) : BaseIntRegion(aRect) {} + MOZ_IMPLICIT nsIntRegion(const mozilla::gfx::IntRect& aRect) : BaseIntRegion(aRect) {} nsIntRegion(const nsIntRegion& aRegion) : BaseIntRegion(aRegion) {} nsIntRegion(nsIntRegion&& aRegion) : BaseIntRegion(mozilla::Move(aRegion)) {} diff --git a/gfx/src/nsScriptableRegion.cpp b/gfx/src/nsScriptableRegion.cpp index a861e08e25e..c0452b6d077 100644 --- a/gfx/src/nsScriptableRegion.cpp +++ b/gfx/src/nsScriptableRegion.cpp @@ -13,7 +13,7 @@ #include "mozilla/Assertions.h" // for MOZ_ASSERT_HELPER2 #include "nsError.h" // for NS_OK, NS_ERROR_FAILURE, etc #include "nsID.h" -#include "nsRect.h" // for nsIntRect +#include "nsRect.h" // for mozilla::gfx::IntRect #include "nscore.h" // for NS_IMETHODIMP class JSObject; @@ -38,7 +38,7 @@ NS_IMETHODIMP nsScriptableRegion::SetToRegion(nsIScriptableRegion *aRegion) NS_IMETHODIMP nsScriptableRegion::SetToRect(int32_t aX, int32_t aY, int32_t aWidth, int32_t aHeight) { - mRegion = nsIntRect(aX, aY, aWidth, aHeight); + mRegion = mozilla::gfx::IntRect(aX, aY, aWidth, aHeight); return NS_OK; } @@ -52,7 +52,7 @@ NS_IMETHODIMP nsScriptableRegion::IntersectRegion(nsIScriptableRegion *aRegion) NS_IMETHODIMP nsScriptableRegion::IntersectRect(int32_t aX, int32_t aY, int32_t aWidth, int32_t aHeight) { - mRegion.And(mRegion, nsIntRect(aX, aY, aWidth, aHeight)); + mRegion.And(mRegion, mozilla::gfx::IntRect(aX, aY, aWidth, aHeight)); return NS_OK; } @@ -66,7 +66,7 @@ NS_IMETHODIMP nsScriptableRegion::UnionRegion(nsIScriptableRegion *aRegion) NS_IMETHODIMP nsScriptableRegion::UnionRect(int32_t aX, int32_t aY, int32_t aWidth, int32_t aHeight) { - mRegion.Or(mRegion, nsIntRect(aX, aY, aWidth, aHeight)); + mRegion.Or(mRegion, mozilla::gfx::IntRect(aX, aY, aWidth, aHeight)); return NS_OK; } @@ -80,7 +80,7 @@ NS_IMETHODIMP nsScriptableRegion::SubtractRegion(nsIScriptableRegion *aRegion) NS_IMETHODIMP nsScriptableRegion::SubtractRect(int32_t aX, int32_t aY, int32_t aWidth, int32_t aHeight) { - mRegion.Sub(mRegion, nsIntRect(aX, aY, aWidth, aHeight)); + mRegion.Sub(mRegion, mozilla::gfx::IntRect(aX, aY, aWidth, aHeight)); return NS_OK; } @@ -100,7 +100,7 @@ NS_IMETHODIMP nsScriptableRegion::IsEqualRegion(nsIScriptableRegion *aRegion, bo NS_IMETHODIMP nsScriptableRegion::GetBoundingBox(int32_t *aX, int32_t *aY, int32_t *aWidth, int32_t *aHeight) { - nsIntRect boundRect = mRegion.GetBounds(); + mozilla::gfx::IntRect boundRect = mRegion.GetBounds(); *aX = boundRect.x; *aY = boundRect.y; *aWidth = boundRect.width; @@ -116,7 +116,7 @@ NS_IMETHODIMP nsScriptableRegion::Offset(int32_t aXOffset, int32_t aYOffset) NS_IMETHODIMP nsScriptableRegion::ContainsRect(int32_t aX, int32_t aY, int32_t aWidth, int32_t aHeight, bool *containsRect) { - *containsRect = mRegion.Contains(nsIntRect(aX, aY, aWidth, aHeight)); + *containsRect = mRegion.Contains(mozilla::gfx::IntRect(aX, aY, aWidth, aHeight)); return NS_OK; } @@ -145,7 +145,7 @@ NS_IMETHODIMP nsScriptableRegion::GetRects(JSContext* aCx, JS::MutableHandlex, JSPROP_ENUMERATE) || diff --git a/gfx/thebes/gfxPrefs.h b/gfx/thebes/gfxPrefs.h index c9020cfa7d8..8e3622c688e 100644 --- a/gfx/thebes/gfxPrefs.h +++ b/gfx/thebes/gfxPrefs.h @@ -250,7 +250,7 @@ private: DECL_GFX_PREF(Once, "image.cache.timeweight", ImageCacheTimeWeight, int32_t, 500); DECL_GFX_PREF(Live, "image.decode-only-on-draw.enabled", ImageDecodeOnlyOnDrawEnabled, bool, true); DECL_GFX_PREF(Live, "image.decode-immediately.enabled", ImageDecodeImmediatelyEnabled, bool, false); - DECL_GFX_PREF(Live, "image.downscale-during-decode.enabled", ImageDownscaleDuringDecodeEnabled, bool, false); + DECL_GFX_PREF(Live, "image.downscale-during-decode.enabled", ImageDownscaleDuringDecodeEnabled, bool, true); DECL_GFX_PREF(Live, "image.high_quality_downscaling.enabled", ImageHQDownscalingEnabled, bool, false); DECL_GFX_PREF(Live, "image.high_quality_downscaling.min_factor", ImageHQDownscalingMinFactor, uint32_t, 1000); DECL_GFX_PREF(Live, "image.high_quality_upscaling.max_size", ImageHQUpscalingMaxSize, uint32_t, 20971520); diff --git a/image/public/ImageLogging.h b/image/ImageLogging.h similarity index 100% rename from image/public/ImageLogging.h rename to image/ImageLogging.h diff --git a/image/public/imgICache.idl b/image/imgICache.idl similarity index 100% rename from image/public/imgICache.idl rename to image/imgICache.idl diff --git a/image/public/imgIContainer.idl b/image/imgIContainer.idl similarity index 100% rename from image/public/imgIContainer.idl rename to image/imgIContainer.idl diff --git a/image/public/imgIContainerDebug.idl b/image/imgIContainerDebug.idl similarity index 100% rename from image/public/imgIContainerDebug.idl rename to image/imgIContainerDebug.idl diff --git a/image/public/imgIEncoder.idl b/image/imgIEncoder.idl similarity index 100% rename from image/public/imgIEncoder.idl rename to image/imgIEncoder.idl diff --git a/image/public/imgILoader.idl b/image/imgILoader.idl similarity index 100% rename from image/public/imgILoader.idl rename to image/imgILoader.idl diff --git a/image/public/imgINotificationObserver.idl b/image/imgINotificationObserver.idl similarity index 100% rename from image/public/imgINotificationObserver.idl rename to image/imgINotificationObserver.idl diff --git a/image/public/imgIOnloadBlocker.idl b/image/imgIOnloadBlocker.idl similarity index 100% rename from image/public/imgIOnloadBlocker.idl rename to image/imgIOnloadBlocker.idl diff --git a/image/public/imgIRequest.idl b/image/imgIRequest.idl similarity index 100% rename from image/public/imgIRequest.idl rename to image/imgIRequest.idl diff --git a/image/public/imgIScriptedNotificationObserver.idl b/image/imgIScriptedNotificationObserver.idl similarity index 100% rename from image/public/imgIScriptedNotificationObserver.idl rename to image/imgIScriptedNotificationObserver.idl diff --git a/image/public/imgITools.idl b/image/imgITools.idl similarity index 100% rename from image/public/imgITools.idl rename to image/imgITools.idl diff --git a/image/moz.build b/image/moz.build index 19c155e0f5c..4baf4aeadeb 100644 --- a/image/moz.build +++ b/image/moz.build @@ -4,8 +4,7 @@ # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. -DIRS += ['public', 'src', 'decoders', 'encoders'] -DIRS += ['build'] +DIRS += ['build', 'src', 'decoders', 'encoders'] with Files('**'): BUG_COMPONENT = ('Core', 'ImageLib') @@ -17,3 +16,23 @@ MOCHITEST_MANIFESTS += ['test/mochitest/mochitest.ini'] MOCHITEST_CHROME_MANIFESTS += ['test/mochitest/chrome.ini'] XPCSHELL_TESTS_MANIFESTS += ['test/unit/xpcshell.ini'] + +XPIDL_SOURCES += [ + 'imgICache.idl', + 'imgIContainer.idl', + 'imgIContainerDebug.idl', + 'imgIEncoder.idl', + 'imgILoader.idl', + 'imgINotificationObserver.idl', + 'imgIOnloadBlocker.idl', + 'imgIRequest.idl', + 'imgIScriptedNotificationObserver.idl', + 'imgITools.idl', + 'nsIIconURI.idl', +] + +XPIDL_MODULE = 'imglib2' + +EXPORTS += [ + 'ImageLogging.h', +] diff --git a/image/public/nsIIconURI.idl b/image/nsIIconURI.idl similarity index 100% rename from image/public/nsIIconURI.idl rename to image/nsIIconURI.idl diff --git a/image/public/moz.build b/image/public/moz.build deleted file mode 100644 index 4f663db925e..00000000000 --- a/image/public/moz.build +++ /dev/null @@ -1,26 +0,0 @@ -# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*- -# vim: set filetype=python: -# 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/. - -XPIDL_SOURCES += [ - 'imgICache.idl', - 'imgIContainer.idl', - 'imgIContainerDebug.idl', - 'imgIEncoder.idl', - 'imgILoader.idl', - 'imgINotificationObserver.idl', - 'imgIOnloadBlocker.idl', - 'imgIRequest.idl', - 'imgIScriptedNotificationObserver.idl', - 'imgITools.idl', - 'nsIIconURI.idl', -] - -XPIDL_MODULE = 'imglib2' - -EXPORTS += [ - 'ImageLogging.h', -] - diff --git a/image/src/SurfaceCache.cpp b/image/src/SurfaceCache.cpp index ead7bf2e87a..a9bfc6dd381 100644 --- a/image/src/SurfaceCache.cpp +++ b/image/src/SurfaceCache.cpp @@ -528,8 +528,8 @@ public: } else { // Our call to AddObject must have failed in StartTracking; most likely // we're in XPCOM shutdown right now. - NS_WARN_IF_FALSE(ShutdownTracker::ShutdownHasStarted(), - "Not expiration-tracking an unlocked surface!"); + NS_ASSERTION(ShutdownTracker::ShutdownHasStarted(), + "Not expiration-tracking an unlocked surface!"); } DebugOnly foundInCosts = mCosts.RemoveElementSorted(costEntry); diff --git a/image/test/crashtests/crashtests.list b/image/test/crashtests/crashtests.list index d914a54964b..b03a27a299a 100644 --- a/image/test/crashtests/crashtests.list +++ b/image/test/crashtests/crashtests.list @@ -46,4 +46,4 @@ load multiple-png-hassize.ico # Asserts in the debug build load 856616.gif -skip-if(AddressSanitizer) load 944353.jpg +skip-if(AddressSanitizer) skip-if(B2G) load 944353.jpg diff --git a/js/public/GCAPI.h b/js/public/GCAPI.h index 23eaf429716..4ddaa125af9 100644 --- a/js/public/GCAPI.h +++ b/js/public/GCAPI.h @@ -422,9 +422,6 @@ WasIncrementalGC(JSRuntime* rt); class JS_PUBLIC_API(AutoDisableGenerationalGC) { js::gc::GCRuntime* gc; -#ifdef JS_GC_ZEAL - bool restartVerifier; -#endif public: explicit AutoDisableGenerationalGC(JSRuntime* rt); diff --git a/js/public/TracingAPI.h b/js/public/TracingAPI.h index f792b5b24f9..34bcf5d39ca 100644 --- a/js/public/TracingAPI.h +++ b/js/public/TracingAPI.h @@ -98,12 +98,14 @@ class JS_PUBLIC_API(JSTracer) WeakMapTraceKind eagerlyTraceWeakMaps() const { return eagerlyTraceWeakMaps_; } // An intermediate state on the road from C to C++ style dispatch. - enum TracerKindTag { - MarkingTracer, - CallbackTracer + enum class TracerKindTag { + Marking, + Tenuring, + Callback }; - bool isMarkingTracer() const { return tag_ == MarkingTracer; } - bool isCallbackTracer() const { return tag_ == CallbackTracer; } + bool isMarkingTracer() const { return tag_ == TracerKindTag::Marking; } + bool isTenuringTracer() const { return tag_ == TracerKindTag::Tenuring; } + bool isCallbackTracer() const { return tag_ == TracerKindTag::Callback; } inline JS::CallbackTracer* asCallbackTracer(); protected: @@ -123,16 +125,14 @@ namespace JS { class AutoTracingName; class AutoTracingIndex; class AutoTracingCallback; -class AutoOriginalTraceLocation; class JS_PUBLIC_API(CallbackTracer) : public JSTracer { public: CallbackTracer(JSRuntime* rt, JSTraceCallback traceCallback, WeakMapTraceKind weakTraceKind = TraceWeakMapValues) - : JSTracer(rt, JSTracer::CallbackTracer, weakTraceKind), callback(traceCallback), - contextName_(nullptr), contextIndex_(InvalidIndex), contextFunctor_(nullptr), - contextRealLocation_(nullptr) + : JSTracer(rt, JSTracer::TracerKindTag::Callback, weakTraceKind), callback(traceCallback), + contextName_(nullptr), contextIndex_(InvalidIndex), contextFunctor_(nullptr) {} // Update the trace callback. @@ -195,14 +195,6 @@ class JS_PUBLIC_API(CallbackTracer) : public JSTracer virtual void operator()(CallbackTracer* trc, char* buf, size_t bufsize) = 0; }; - // Return the original heap tracing location if the raw thingp reference - // has been moved. This is generally only useful for heap analyses that - // need to build an accurate model of the heap, and thus is only accurate - // when built with JS_GC_ZEAL. - void*const* tracingLocation(void** thingp) { - return contextRealLocation_ ? contextRealLocation_ : thingp; - } - private: // Exposed publicly for several callers that need to check if the tracer // calling them is of the right type. @@ -216,9 +208,6 @@ class JS_PUBLIC_API(CallbackTracer) : public JSTracer friend class AutoTracingDetails; ContextFunctor* contextFunctor_; - - friend class AutoOriginalTraceLocation; - void*const* contextRealLocation_; }; // Set the name portion of the tracer's context for the current edge. @@ -288,37 +277,6 @@ class AutoTracingDetails } }; -// Some dynamic analyses depend on knowing the edge source location as it -// exists in the object graph. When marking some types of things, e.g. Value -// edges, it is necessary to copy into a temporary on the stack. This class -// records the original location if we need to copy the tracee, so that the -// relevant analyses can continue to operate correctly. -class AutoOriginalTraceLocation -{ -#ifdef JS_GC_ZEAL - CallbackTracer* trc_; - - public: - template - AutoOriginalTraceLocation(JSTracer* trc, T*const* realLocation) : trc_(nullptr) { - if (trc->isCallbackTracer() && trc->asCallbackTracer()->contextRealLocation_ == nullptr) { - trc_ = trc->asCallbackTracer(); - trc_->contextRealLocation_ = reinterpret_cast(realLocation); - } - } - ~AutoOriginalTraceLocation() { - if (trc_) { - MOZ_ASSERT(trc_->contextRealLocation_); - trc_->contextRealLocation_ = nullptr; - } - } -#else - public: - template - AutoOriginalTraceLocation(JSTracer* trc, T*const* realLocation) {} -#endif -}; - } // namespace JS JS::CallbackTracer* @@ -381,7 +339,6 @@ inline void JS_CallHashSetObjectTracer(JSTracer* trc, HashSetEnum& e, JSObject* const& key, const char* name) { JSObject* updated = key; - JS::AutoOriginalTraceLocation reloc(trc, &key); JS_CallUnbarrieredObjectTracer(trc, &updated, name); if (updated != key) e.rekeyFront(updated); diff --git a/js/src/builtin/MapObject.cpp b/js/src/builtin/MapObject.cpp index 4d37edffae9..c63eea72aa7 100644 --- a/js/src/builtin/MapObject.cpp +++ b/js/src/builtin/MapObject.cpp @@ -839,7 +839,6 @@ HashableValue HashableValue::mark(JSTracer* trc) const { HashableValue hv(*this); - JS::AutoOriginalTraceLocation reloc(trc, (void**)this); TraceEdge(trc, &hv.value, "key"); return hv; } diff --git a/js/src/gc/Barrier.h b/js/src/gc/Barrier.h index 2bfed126d04..0c3f26c80d0 100644 --- a/js/src/gc/Barrier.h +++ b/js/src/gc/Barrier.h @@ -127,14 +127,13 @@ * There are also special classes HeapValue and HeapId, which barrier js::Value * and jsid, respectively. * - * One additional note: not all object writes need to be barriered. Writes to - * newly allocated objects do not need a pre-barrier. In these cases, we use + * One additional note: not all object writes need to be pre-barriered. Writes + * to newly allocated objects do not need a pre-barrier. In these cases, we use * the "obj->field.init(value)" method instead of "obj->field = value". We use * the init naming idiom in many places to signify that a field is being * assigned for the first time. * - * For each of pointers, Values and jsids this file implements four classes, - * illustrated here for the pointer (Ptr) classes: + * This file implements four classes, illustrated here: * * BarrieredBase abstract base class which provides common operations * | | | @@ -144,9 +143,27 @@ * | * RelocatablePtr provides pre- and post-barriers and is relocatable * + * The implementation of the barrier logic is implemented on T::writeBarrier.*, + * via: + * + * BarrieredBase::pre + * -> InternalGCMethods::preBarrier + * -> T::writeBarrierPre + * -> InternalGCMethods::preBarrier + * -> InternalGCMethods::preBarrier + * -> InternalGCMethods::preBarrier + * -> T::writeBarrierPre + * + * HeapPtr::post and RelocatablePtr::post + * -> InternalGCMethods::postBarrier + * -> T::writeBarrierPost + * -> InternalGCMethods::postBarrier + * -> StoreBuffer::put + * * These classes are designed to be used by the internals of the JS engine. - * Barriers designed to be used externally are provided in - * js/public/RootingAPI.h. + * Barriers designed to be used externally are provided in js/RootingAPI.h. + * These external barriers call into the same post-barrier implementations at + * InternalGCMethods::post via an indirect call to Heap(.+)Barrier. */ class JSAtom; diff --git a/js/src/gc/GCInternals.h b/js/src/gc/GCInternals.h index ef4019b8752..88dbd9f60cb 100644 --- a/js/src/gc/GCInternals.h +++ b/js/src/gc/GCInternals.h @@ -93,7 +93,6 @@ class AutoStopVerifyingBarriers { GCRuntime* gc; bool restartPreVerifier; - bool restartPostVerifier; MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER public: @@ -102,8 +101,6 @@ class AutoStopVerifyingBarriers : gc(&rt->gc) { restartPreVerifier = gc->endVerifyPreBarriers() && !isShutdown; - restartPostVerifier = gc->endVerifyPostBarriers() && !isShutdown && - JS::IsGenerationalGCEnabled(rt); MOZ_GUARD_OBJECT_NOTIFIER_INIT; } @@ -121,8 +118,6 @@ class AutoStopVerifyingBarriers if (restartPreVerifier) gc->startVerifyPreBarriers(); - if (restartPostVerifier) - gc->startVerifyPostBarriers(); if (outer != gcstats::PHASE_NONE) gc->stats.beginPhase(outer); diff --git a/js/src/gc/GCRuntime.h b/js/src/gc/GCRuntime.h index 4940ffb7704..6c9f0990be4 100644 --- a/js/src/gc/GCRuntime.h +++ b/js/src/gc/GCRuntime.h @@ -656,9 +656,7 @@ class GCRuntime bool parseAndSetZeal(const char* str); void setNextScheduled(uint32_t count); void verifyPreBarriers(); - void verifyPostBarriers(); void maybeVerifyPreBarriers(bool always); - void maybeVerifyPostBarriers(bool always); bool selectForMarking(JSObject* object); void clearSelectedForMarking(); void setDeterministic(bool enable); @@ -826,8 +824,6 @@ class GCRuntime #ifdef JS_GC_ZEAL void startVerifyPreBarriers(); bool endVerifyPreBarriers(); - void startVerifyPostBarriers(); - bool endVerifyPostBarriers(); void finishVerifier(); bool isVerifyPreBarriersEnabled() const { return !!verifyPreData; } #else diff --git a/js/src/gc/Marking.cpp b/js/src/gc/Marking.cpp index 2e3bd839dc2..6960006f93c 100644 --- a/js/src/gc/Marking.cpp +++ b/js/src/gc/Marking.cpp @@ -8,6 +8,7 @@ #include "mozilla/DebugOnly.h" #include "mozilla/IntegerRange.h" +#include "mozilla/ReentrancyGuard.h" #include "mozilla/TypeTraits.h" #include "jsgc.h" @@ -33,6 +34,7 @@ using namespace js; using namespace js::gc; +using mozilla::ArrayLength; using mozilla::DebugOnly; using mozilla::IsBaseOf; using mozilla::IsSame; @@ -172,7 +174,7 @@ js::CheckTracedThing(JSTracer* trc, T thing) if (IsInsideNursery(thing)) return; - MOZ_ASSERT_IF(!MovingTracer::IsMovingTracer(trc) && !Nursery::IsMinorCollectionTracer(trc), + MOZ_ASSERT_IF(!MovingTracer::IsMovingTracer(trc) && !trc->isTenuringTracer(), !IsForwarded(thing)); /* @@ -302,23 +304,39 @@ ShouldMarkCrossCompartment(JSTracer* trc, JSObject* src, Value val) return val.isMarkable() && ShouldMarkCrossCompartment(trc, src, (Cell*)val.toGCThing()); } -template -static bool -ZoneIsAtomsZoneForString(JSRuntime* rt, T* thing) +static void +AssertZoneIsMarking(Cell* thing) { - JSGCTraceKind kind = GetGCThingTraceKind(thing); - if (kind == JSTRACE_STRING || kind == JSTRACE_SYMBOL) - return rt->isAtomsZone(thing->zone()); - return false; + MOZ_ASSERT(TenuredCell::fromPointer(thing)->zone()->isGCMarking()); } -#define JS_COMPARTMENT_ASSERT(rt, thing) \ - MOZ_ASSERT((thing)->zone()->isGCMarking() || ZoneIsAtomsZoneForString((rt), (thing))) +static void +AssertZoneIsMarking(JSString* str) +{ +#ifdef DEBUG + Zone* zone = TenuredCell::fromPointer(str)->zone(); + JSRuntime* rt = str->runtimeFromMainThread(); + MOZ_ASSERT(zone->isGCMarking() || rt->isAtomsZone(zone)); +#endif +} -#define JS_ROOT_MARKING_ASSERT(trc) \ - MOZ_ASSERT_IF(trc->isMarkingTracer(), \ - trc->runtime()->gc.state() == NO_INCREMENTAL || \ +static void +AssertZoneIsMarking(JS::Symbol* sym) +{ +#ifdef DEBUG + Zone* zone = TenuredCell::fromPointer(sym)->zone(); + JSRuntime* rt = sym->runtimeFromMainThread(); + MOZ_ASSERT(zone->isGCMarking() || rt->isAtomsZone(zone)); +#endif +} + +static void +AssertRootMarkingPhase(JSTracer* trc) +{ + MOZ_ASSERT_IF(trc->isMarkingTracer(), + trc->runtime()->gc.state() == NO_INCREMENTAL || trc->runtime()->gc.state() == MARK_ROOTS); +} /*** Tracing Interface ***************************************************************************/ @@ -410,6 +428,7 @@ ConvertToBase(T* thingp) template void DispatchToTracer(JSTracer* trc, T* thingp, const char* name); template T DoCallback(JS::CallbackTracer* trc, T* thingp, const char* name); +template void DoTenuring(TenuringTracer& mover, T* thingp); template void DoMarking(GCMarker* gcmarker, T thing); template @@ -430,7 +449,7 @@ template void js::TraceRoot(JSTracer* trc, T* thingp, const char* name) { - JS_ROOT_MARKING_ASSERT(trc); + AssertRootMarkingPhase(trc); DispatchToTracer(trc, ConvertToBase(thingp), name); } @@ -450,7 +469,7 @@ template void js::TraceRootRange(JSTracer* trc, size_t len, T* vec, const char* name) { - JS_ROOT_MARKING_ASSERT(trc); + AssertRootMarkingPhase(trc); JS::AutoTracingIndex index(trc); for (auto i : MakeRange(len)) { if (InternalGCMethods::isMarkable(vec[i])) @@ -496,7 +515,7 @@ template void js::TraceProcessGlobalRoot(JSTracer* trc, T* thing, const char* name) { - JS_ROOT_MARKING_ASSERT(trc); + AssertRootMarkingPhase(trc); MOZ_ASSERT(ThingIsPermanentAtomOrWellKnownSymbol(thing)); // We have to mark permanent atoms and well-known symbols through a special @@ -578,6 +597,9 @@ DispatchToTracer(JSTracer* trc, T* thingp, const char* name) #undef IS_SAME_TYPE_OR if (trc->isMarkingTracer()) return DoMarking(static_cast(trc), *thingp); + if (trc->isTenuringTracer()) + return DoTenuring(*static_cast(trc), thingp); + MOZ_ASSERT(trc->isCallbackTracer()); DoCallback(trc->asCallbackTracer(), thingp, name); } @@ -765,7 +787,7 @@ bool js::GCMarker::mark(T* thing) { CheckTracedThing(this, thing); - JS_COMPARTMENT_ASSERT(runtime(), thing); + AssertZoneIsMarking(thing); MOZ_ASSERT(!IsInsideNursery(gc::TenuredCell::fromPointer(thing))); return gc::ParticipatesInCC::value ? gc::TenuredCell::fromPointer(thing)->markIfUnmarked(markColor()) @@ -889,7 +911,7 @@ JSString::traceBase(JSTracer* trc) inline void js::GCMarker::eagerlyMarkChildren(JSLinearString* linearStr) { - JS_COMPARTMENT_ASSERT(runtime(), linearStr); + AssertZoneIsMarking(linearStr); MOZ_ASSERT(linearStr->isMarked()); MOZ_ASSERT(linearStr->JSString::isLinear()); @@ -899,7 +921,7 @@ js::GCMarker::eagerlyMarkChildren(JSLinearString* linearStr) MOZ_ASSERT(linearStr->JSString::isLinear()); if (linearStr->isPermanentAtom()) break; - JS_COMPARTMENT_ASSERT(runtime(), linearStr); + AssertZoneIsMarking(linearStr); if (!mark(static_cast(linearStr))) break; } @@ -926,7 +948,7 @@ js::GCMarker::eagerlyMarkChildren(JSRope* rope) while (true) { JS_DIAGNOSTICS_ASSERT(GetGCThingTraceKind(rope) == JSTRACE_STRING); JS_DIAGNOSTICS_ASSERT(rope->JSString::isRope()); - JS_COMPARTMENT_ASSERT(runtime(), rope); + AssertZoneIsMarking(rope); MOZ_ASSERT(rope->isMarked()); JSRope* next = nullptr; @@ -1121,7 +1143,7 @@ GCMarker::processMarkStackTop(SliceBudget& budget) case ObjectTag: { obj = reinterpret_cast(addr); - JS_COMPARTMENT_ASSERT(runtime(), obj); + AssertZoneIsMarking(obj); goto scan_obj; } @@ -1135,11 +1157,11 @@ GCMarker::processMarkStackTop(SliceBudget& budget) case SavedValueArrayTag: { MOZ_ASSERT(!(addr & CellMask)); - NativeObject* obj = reinterpret_cast(addr); + JSObject* obj = reinterpret_cast(addr); HeapValue* vp; HeapValue* end; if (restoreValueArray(obj, (void**)&vp, (void**)&end)) - pushValueArray(obj, vp, end); + pushValueArray(&obj->as(), vp, end); else repush(obj); return; @@ -1208,7 +1230,7 @@ GCMarker::processMarkStackTop(SliceBudget& budget) scan_obj: { - JS_COMPARTMENT_ASSERT(runtime(), obj); + AssertZoneIsMarking(obj); budget.step(); if (budget.isOverBudget()) { @@ -1363,11 +1385,15 @@ GCMarker::saveValueRanges() } bool -GCMarker::restoreValueArray(NativeObject* obj, void** vpp, void** endp) +GCMarker::restoreValueArray(JSObject* objArg, void** vpp, void** endp) { uintptr_t start = stack.pop(); HeapSlot::Kind kind = (HeapSlot::Kind) stack.pop(); + if (!objArg->isNative()) + return false; + NativeObject* obj = &objArg->as(); + if (kind == HeapSlot::Element) { if (!obj->is()) return false; @@ -1509,7 +1535,7 @@ MarkStack::sizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf) const * so we delay visting entries. */ GCMarker::GCMarker(JSRuntime* rt) - : JSTracer(rt, JSTracer::MarkingTracer, DoNotTraceWeakMaps), + : JSTracer(rt, JSTracer::TracerKindTag::Marking, DoNotTraceWeakMaps), stack(size_t(-1)), color(BLACK), unmarkedArenaStackTop(nullptr), @@ -1702,11 +1728,426 @@ GCMarker::sizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf) const return size; } + +/*** Tenuring Tracer *****************************************************************************/ + +template void -js::SetMarkStackLimit(JSRuntime* rt, size_t limit) +DoTenuring(TenuringTracer& mover, T* thingp) { - rt->gc.setMarkStackLimit(limit); + // Non-JSObject types are not in the nursery, so do not need to be tenured. + MOZ_ASSERT(!IsInsideNursery(*thingp)); } + +template <> +void +DoTenuring(TenuringTracer& mover, JSObject** objp) +{ + // Only roots and store buffer entries should be marked via this path; all + // internal pointers are marked via collectToFixedPoint. + MOZ_ASSERT(!mover.nursery().isInside(objp)); + + if (IsInsideNursery(*objp) && !mover.nursery().getForwardedPointer(objp)) + *objp = mover.moveToTenured(*objp); +} + +template <> +void +DoTenuring(TenuringTracer& mover, Value* valp) +{ + if (valp->isObject()) { + JSObject *obj = &valp->toObject(); + DoTenuring(mover, &obj); + valp->setObject(*obj); + } else { + MOZ_ASSERT_IF(valp->isMarkable(), !IsInsideNursery(valp->toGCThing())); + } +} + +template <> +void +DoTenuring(TenuringTracer& mover, jsid* idp) +{ + MOZ_ASSERT_IF(JSID_IS_GCTHING(*idp), !IsInsideNursery(JSID_TO_GCTHING(*idp).asCell())); +} + +template +void +StoreBuffer::MonoTypeBuffer::mark(StoreBuffer* owner, TenuringTracer& mover) +{ + mozilla::ReentrancyGuard g(*owner); + MOZ_ASSERT(owner->isEnabled()); + MOZ_ASSERT(stores_.initialized()); + sinkStores(owner); + for (typename StoreSet::Range r = stores_.all(); !r.empty(); r.popFront()) + r.front().mark(mover); +} + +void +StoreBuffer::SlotsEdge::mark(TenuringTracer& mover) const +{ + NativeObject* obj = object(); + + // Beware JSObject::swap exchanging a native object for a non-native one. + if (!obj->isNative()) + return; + + if (IsInsideNursery(obj)) + return; + + if (kind() == ElementKind) { + int32_t initLen = obj->getDenseInitializedLength(); + int32_t clampedStart = Min(start_, initLen); + int32_t clampedEnd = Min(start_ + count_, initLen); + TraceRange(&mover, clampedEnd - clampedStart, + static_cast(obj->getDenseElements() + clampedStart), "element"); + } else { + int32_t start = Min(uint32_t(start_), obj->slotSpan()); + int32_t end = Min(uint32_t(start_) + count_, obj->slotSpan()); + MOZ_ASSERT(end >= start); + TraceObjectSlots(&mover, obj, start, end - start); + } +} + +void +StoreBuffer::WholeCellEdges::mark(TenuringTracer& mover) const +{ + MOZ_ASSERT(edge->isTenured()); + JSGCTraceKind kind = GetGCThingTraceKind(edge); + if (kind <= JSTRACE_OBJECT) { + JSObject* object = static_cast(edge); + + // FIXME: bug 1161664 -- call the inline path below, now that it is accessable. + object->traceChildren(&mover); + + // Additionally trace the expando object attached to any unboxed plain + // objects. Baseline and Ion can write properties to the expando while + // only adding a post barrier to the owning unboxed object. Note that + // it isn't possible for a nursery unboxed object to have a tenured + // expando, so that adding a post barrier on the original object will + // capture any tenured->nursery edges in the expando as well. + if (object->is()) { + if (UnboxedExpandoObject* expando = object->as().maybeExpando()) + expando->traceChildren(&mover); + } + + return; + } + MOZ_ASSERT(kind == JSTRACE_JITCODE); + static_cast(edge)->traceChildren(&mover); +} + +void +StoreBuffer::CellPtrEdge::mark(TenuringTracer& mover) const +{ + if (!*edge) + return; + + MOZ_ASSERT(GetGCThingTraceKind(*edge) == JSTRACE_OBJECT); + DoTenuring(mover, reinterpret_cast(edge)); +} + +void +StoreBuffer::ValueEdge::mark(TenuringTracer& mover) const +{ + if (deref()) + DoTenuring(mover, edge); +} + +/* Insert the given relocation entry into the list of things to visit. */ +void +TenuringTracer::insertIntoFixupList(RelocationOverlay* entry) { + *tail = entry; + tail = &entry->next_; + *tail = nullptr; +} + +JSObject* +TenuringTracer::moveToTenured(JSObject* obj) { + return (JSObject*)nursery_.moveToTenured(*this, obj); +} + +void* +js::Nursery::moveToTenured(TenuringTracer& mover, JSObject* src) +{ + AllocKind dstKind = src->allocKindForTenure(*this); + Zone* zone = src->zone(); + JSObject* dst = reinterpret_cast(allocateFromTenured(zone, dstKind)); + if (!dst) + CrashAtUnhandlableOOM("Failed to allocate object while tenuring."); + + mover.tenuredSize += moveObjectToTenured(mover, dst, src, dstKind); + + RelocationOverlay* overlay = RelocationOverlay::fromCell(src); + overlay->forwardTo(dst); + mover.insertIntoFixupList(overlay); + + TracePromoteToTenured(src, dst); + return static_cast(dst); +} + +MOZ_ALWAYS_INLINE TenuredCell* +js::Nursery::allocateFromTenured(Zone* zone, AllocKind thingKind) +{ + TenuredCell* t = zone->arenas.allocateFromFreeList(thingKind, Arena::thingSize(thingKind)); + if (t) + return t; + zone->arenas.checkEmptyFreeList(thingKind); + AutoMaybeStartBackgroundAllocation maybeStartBackgroundAllocation; + return zone->arenas.allocateFromArena(zone, thingKind, maybeStartBackgroundAllocation); +} + +// Structure for counting how many times objects in a particular group have +// been tenured during a minor collection. +struct TenureCount +{ + ObjectGroup* group; + int count; +}; + +// Keep rough track of how many times we tenure objects in particular groups +// during minor collections, using a fixed size hash for efficiency at the cost +// of potential collisions. +struct Nursery::TenureCountCache +{ + TenureCount entries[16]; + + TenureCountCache() { PodZero(this); } + + TenureCount& findEntry(ObjectGroup* group) { + return entries[PointerHasher::hash(group) % ArrayLength(entries)]; + } +}; + +void +js::Nursery::collectToFixedPoint(TenuringTracer& mover, TenureCountCache& tenureCounts) +{ + for (RelocationOverlay* p = mover.head; p; p = p->next()) { + JSObject* obj = static_cast(p->forwardingAddress()); + traceObject(mover, obj); + + TenureCount& entry = tenureCounts.findEntry(obj->group()); + if (entry.group == obj->group()) { + entry.count++; + } else if (!entry.group) { + entry.group = obj->group(); + entry.count = 1; + } + } +} + +MOZ_ALWAYS_INLINE void +js::Nursery::traceObject(TenuringTracer& mover, JSObject* obj) +{ + const Class* clasp = obj->getClass(); + if (clasp->trace) { + if (clasp->trace == InlineTypedObject::obj_trace) { + TypeDescr* descr = &obj->as().typeDescr(); + if (descr->hasTraceList()) { + markTraceList(mover, descr->traceList(), + obj->as().inlineTypedMem()); + } + return; + } + if (clasp == &UnboxedPlainObject::class_) { + JSObject** pexpando = obj->as().addressOfExpando(); + if (*pexpando) + markObject(mover, pexpando); + const UnboxedLayout& layout = obj->as().layoutDontCheckGeneration(); + if (layout.traceList()) { + markTraceList(mover, layout.traceList(), + obj->as().data()); + } + return; + } + clasp->trace(&mover, obj); + } + + MOZ_ASSERT(obj->isNative() == clasp->isNative()); + if (!clasp->isNative()) + return; + NativeObject* nobj = &obj->as(); + + // Note: the contents of copy on write elements pointers are filled in + // during parsing and cannot contain nursery pointers. + if (!nobj->hasEmptyElements() && !nobj->denseElementsAreCopyOnWrite()) + markSlots(mover, nobj->getDenseElements(), nobj->getDenseInitializedLength()); + + HeapSlot* fixedStart; + HeapSlot* fixedEnd; + HeapSlot* dynStart; + HeapSlot* dynEnd; + nobj->getSlotRange(0, nobj->slotSpan(), &fixedStart, &fixedEnd, &dynStart, &dynEnd); + markSlots(mover, fixedStart, fixedEnd); + markSlots(mover, dynStart, dynEnd); +} + +MOZ_ALWAYS_INLINE void +js::Nursery::markSlots(TenuringTracer& mover, HeapSlot* vp, uint32_t nslots) +{ + markSlots(mover, vp, vp + nslots); +} + +MOZ_ALWAYS_INLINE void +js::Nursery::markSlots(TenuringTracer& mover, HeapSlot* vp, HeapSlot* end) +{ + for (; vp != end; ++vp) + markSlot(mover, vp); +} + +MOZ_ALWAYS_INLINE void +js::Nursery::markSlot(TenuringTracer& mover, HeapSlot* slotp) +{ + if (!slotp->isObject()) + return; + + JSObject* obj = &slotp->toObject(); + if (markObject(mover, &obj)) + slotp->unsafeGet()->setObject(*obj); +} + +MOZ_ALWAYS_INLINE void +js::Nursery::markTraceList(TenuringTracer& mover, const int32_t* traceList, uint8_t* memory) +{ + while (*traceList != -1) { + // Strings are not in the nursery and do not need tracing. + traceList++; + } + traceList++; + while (*traceList != -1) { + JSObject** pobj = reinterpret_cast(memory + *traceList); + markObject(mover, pobj); + traceList++; + } + traceList++; + while (*traceList != -1) { + HeapSlot* pslot = reinterpret_cast(memory + *traceList); + markSlot(mover, pslot); + traceList++; + } +} + +MOZ_ALWAYS_INLINE bool +js::Nursery::markObject(TenuringTracer& mover, JSObject** pobj) +{ + if (!IsInsideNursery(*pobj)) + return false; + + if (getForwardedPointer(pobj)) + return true; + + *pobj = static_cast(moveToTenured(mover, *pobj)); + return true; +} + + +MOZ_ALWAYS_INLINE size_t +js::Nursery::moveObjectToTenured(TenuringTracer& mover, + JSObject* dst, JSObject* src, AllocKind dstKind) +{ + size_t srcSize = Arena::thingSize(dstKind); + size_t tenuredSize = srcSize; + + /* + * Arrays do not necessarily have the same AllocKind between src and dst. + * We deal with this by copying elements manually, possibly re-inlining + * them if there is adequate room inline in dst. + * + * For Arrays we're reducing tenuredSize to the smaller srcSize + * because moveElementsToTenured() accounts for all Array elements, + * even if they are inlined. + */ + if (src->is()) + tenuredSize = srcSize = sizeof(NativeObject); + + js_memcpy(dst, src, srcSize); + if (src->isNative()) { + NativeObject* ndst = &dst->as(); + NativeObject* nsrc = &src->as(); + tenuredSize += moveSlotsToTenured(ndst, nsrc, dstKind); + tenuredSize += moveElementsToTenured(ndst, nsrc, dstKind); + + // The shape's list head may point into the old object. This can only + // happen for dictionaries, which are native objects. + if (&nsrc->shape_ == ndst->shape_->listp) { + MOZ_ASSERT(nsrc->shape_->inDictionary()); + ndst->shape_->listp = &ndst->shape_; + } + } + + if (src->is()) { + InlineTypedObject::objectMovedDuringMinorGC(&mover, dst, src); + } else if (src->is()) { + tenuredSize += UnboxedArrayObject::objectMovedDuringMinorGC(&mover, dst, src, dstKind); + } else { + // Objects with JSCLASS_SKIP_NURSERY_FINALIZE need to be handled above + // to ensure any additional nursery buffers they hold are moved. + MOZ_ASSERT(!(src->getClass()->flags & JSCLASS_SKIP_NURSERY_FINALIZE)); + } + + return tenuredSize; +} + +MOZ_ALWAYS_INLINE size_t +js::Nursery::moveSlotsToTenured(NativeObject* dst, NativeObject* src, AllocKind dstKind) +{ + /* Fixed slots have already been copied over. */ + if (!src->hasDynamicSlots()) + return 0; + + if (!isInside(src->slots_)) { + removeMallocedBuffer(src->slots_); + return 0; + } + + Zone* zone = src->zone(); + size_t count = src->numDynamicSlots(); + dst->slots_ = zone->pod_malloc(count); + if (!dst->slots_) + CrashAtUnhandlableOOM("Failed to allocate slots while tenuring."); + PodCopy(dst->slots_, src->slots_, count); + setSlotsForwardingPointer(src->slots_, dst->slots_, count); + return count * sizeof(HeapSlot); +} + +MOZ_ALWAYS_INLINE size_t +js::Nursery::moveElementsToTenured(NativeObject* dst, NativeObject* src, AllocKind dstKind) +{ + if (src->hasEmptyElements() || src->denseElementsAreCopyOnWrite()) + return 0; + + Zone* zone = src->zone(); + ObjectElements* srcHeader = src->getElementsHeader(); + ObjectElements* dstHeader; + + /* TODO Bug 874151: Prefer to put element data inline if we have space. */ + if (!isInside(srcHeader)) { + MOZ_ASSERT(src->elements_ == dst->elements_); + removeMallocedBuffer(srcHeader); + return 0; + } + + size_t nslots = ObjectElements::VALUES_PER_HEADER + srcHeader->capacity; + + /* Unlike other objects, Arrays can have fixed elements. */ + if (src->is() && nslots <= GetGCKindSlots(dstKind)) { + dst->as().setFixedElements(); + dstHeader = dst->as().getElementsHeader(); + js_memcpy(dstHeader, srcHeader, nslots * sizeof(HeapSlot)); + setElementsForwardingPointer(srcHeader, dstHeader, nslots); + return nslots * sizeof(HeapSlot); + } + + MOZ_ASSERT(nslots >= 2); + dstHeader = reinterpret_cast(zone->pod_malloc(nslots)); + if (!dstHeader) + CrashAtUnhandlableOOM("Failed to allocate elements while tenuring."); + js_memcpy(dstHeader, srcHeader, nslots * sizeof(HeapSlot)); + setElementsForwardingPointer(srcHeader, dstHeader, nslots); + dst->elements_ = dstHeader->elements(); + return nslots * sizeof(HeapSlot); +} + /*** IsMarked / IsAboutToBeFinalized **************************************************************/ @@ -1732,15 +2173,10 @@ CheckIsMarkedThing(T* thingp) template static bool -IsMarkedInternal(T* thingp) +IsMarkedInternalCommon(T* thingp) { CheckIsMarkedThing(thingp); - JSRuntime* rt = (*thingp)->runtimeFromAnyThread(); - - if (IsInsideNursery(*thingp)) { - MOZ_ASSERT(CurrentThreadCanAccessRuntime(rt)); - return rt->gc.nursery.getForwardedPointer(thingp); - } + MOZ_ASSERT(!IsInsideNursery(*thingp)); Zone* zone = (*thingp)->asTenured().zoneFromAnyThread(); if (!zone->isCollectingFromAnyThread() || zone->isGCFinished()) @@ -1750,6 +2186,25 @@ IsMarkedInternal(T* thingp) return (*thingp)->asTenured().isMarked(); } +template +static bool +IsMarkedInternal(T* thingp) +{ + return IsMarkedInternalCommon(thingp); +} + +template +static bool +IsMarkedInternal(JSObject** thingp) +{ + if (IsInsideNursery(*thingp)) { + JSRuntime* rt = (*thingp)->runtimeFromAnyThread(); + MOZ_ASSERT(CurrentThreadCanAccessRuntime(rt)); + return rt->gc.nursery.getForwardedPointer(thingp); + } + return IsMarkedInternalCommon(thingp); +} + template struct IsMarkedFunctor : public IdentityDefaultAdaptor { template S operator()(T* t, bool* rv) { @@ -1792,7 +2247,7 @@ IsAboutToBeFinalizedInternal(T* thingp) MOZ_ASSERT_IF(!rt->isHeapMinorCollecting(), !IsInsideNursery(thing)); if (rt->isHeapMinorCollecting()) { if (IsInsideNursery(thing)) - return !nursery.getForwardedPointer(thingp); + return !nursery.getForwardedPointer(reinterpret_cast(thingp)); return false; } @@ -1901,7 +2356,7 @@ FOR_EACH_GC_POINTER_TYPE(INSTANTIATE_ALL_VALID_TRACE_FUNCTIONS) void TypeSet::MarkTypeRoot(JSTracer* trc, TypeSet::Type* v, const char* name) { - JS_ROOT_MARKING_ASSERT(trc); + AssertRootMarkingPhase(trc); MarkTypeUnbarriered(trc, v, name); } diff --git a/js/src/gc/Marking.h b/js/src/gc/Marking.h index 41155c32b76..78325a3d289 100644 --- a/js/src/gc/Marking.h +++ b/js/src/gc/Marking.h @@ -277,7 +277,7 @@ class GCMarker : public JSTracer return stack.isEmpty(); } - bool restoreValueArray(NativeObject* obj, void** vpp, void** endp); + bool restoreValueArray(JSObject* obj, void** vpp, void** endp); void saveValueRanges(); inline void processMarkStackTop(SliceBudget& budget); @@ -300,14 +300,9 @@ class GCMarker : public JSTracer mozilla::DebugOnly strictCompartmentChecking; }; -void -SetMarkStackLimit(JSRuntime* rt, size_t limit); - bool IsBufferingGrayRoots(JSTracer* trc); -} /* namespace js */ -namespace js { namespace gc { /*** Special Cases ***/ @@ -388,7 +383,6 @@ class HashKeyRef : public BufferableRef typename Map::Ptr p = map->lookup(key); if (!p) return; - JS::AutoOriginalTraceLocation reloc(trc, (void**)&*p); TraceManuallyBarrieredEdge(trc, &key, "HashKeyRef"); map->rekeyIfMoved(prior, key); } diff --git a/js/src/gc/Nursery-inl.h b/js/src/gc/Nursery-inl.h index 591f9a05787..59011edc310 100644 --- a/js/src/gc/Nursery-inl.h +++ b/js/src/gc/Nursery-inl.h @@ -14,11 +14,8 @@ #include "js/TracingAPI.h" #include "vm/Runtime.h" -namespace js { - -template MOZ_ALWAYS_INLINE bool -Nursery::getForwardedPointer(T** ref) +js::Nursery::getForwardedPointer(JSObject** ref) const { MOZ_ASSERT(ref); MOZ_ASSERT(isInside((void*)*ref)); @@ -26,10 +23,12 @@ Nursery::getForwardedPointer(T** ref) if (!overlay->isForwarded()) return false; /* This static cast from Cell* restricts T to valid (GC thing) types. */ - *ref = static_cast(overlay->forwardingAddress()); + *ref = static_cast(overlay->forwardingAddress()); return true; } +namespace js { + // The allocation methods below will not run the garbage collector. If the // nursery cannot accomodate the allocation, the malloc heap will be used // instead. diff --git a/js/src/gc/Nursery.cpp b/js/src/gc/Nursery.cpp index 289584033e5..b730422aa74 100644 --- a/js/src/gc/Nursery.cpp +++ b/js/src/gc/Nursery.cpp @@ -300,81 +300,6 @@ js::Nursery::freeBuffer(void* buffer) } } -namespace js { -namespace gc { - -class MinorCollectionTracer : public JS::CallbackTracer -{ - public: - Nursery* nursery; - AutoTraceSession session; - - /* Amount of data moved to the tenured generation during collection. */ - size_t tenuredSize; - - /* - * This list is threaded through the Nursery using the space from already - * moved things. The list is used to fix up the moved things and to find - * things held live by intra-Nursery pointers. - */ - RelocationOverlay* head; - RelocationOverlay** tail; - - /* Save and restore all of the runtime state we use during MinorGC. */ - bool savedRuntimeNeedBarrier; - AutoDisableProxyCheck disableStrictProxyChecking; - AutoEnterOOMUnsafeRegion oomUnsafeRegion; - - /* Insert the given relocation entry into the list of things to visit. */ - MOZ_ALWAYS_INLINE void insertIntoFixupList(RelocationOverlay* entry) { - *tail = entry; - tail = &entry->next_; - *tail = nullptr; - } - - MinorCollectionTracer(JSRuntime* rt, Nursery* nursery) - : JS::CallbackTracer(rt, Nursery::MinorGCCallback, TraceWeakMapKeysValues), - nursery(nursery), - session(rt, MinorCollecting), - tenuredSize(0), - head(nullptr), - tail(&head), - savedRuntimeNeedBarrier(rt->needsIncrementalBarrier()), - disableStrictProxyChecking(rt) - { - rt->gc.incGcNumber(); - - /* - * We disable the runtime needsIncrementalBarrier() check so that - * pre-barriers do not fire on objects that have been relocated. The - * pre-barrier's call to obj->zone() will try to look through shape_, - * which is now the relocation magic and will crash. However, - * zone->needsIncrementalBarrier() must still be set correctly so that - * allocations we make in minor GCs between incremental slices will - * allocate their objects marked. - */ - rt->setNeedsIncrementalBarrier(false); - } - - ~MinorCollectionTracer() { - runtime()->setNeedsIncrementalBarrier(savedRuntimeNeedBarrier); - } -}; - -} /* namespace gc */ -} /* namespace js */ - -MOZ_ALWAYS_INLINE TenuredCell* -js::Nursery::allocateFromTenured(Zone* zone, AllocKind thingKind) -{ - TenuredCell* t = zone->arenas.allocateFromFreeList(thingKind, Arena::thingSize(thingKind)); - if (t) - return t; - zone->arenas.checkEmptyFreeList(thingKind); - AutoMaybeStartBackgroundAllocation maybeStartBackgroundAllocation; - return zone->arenas.allocateFromArena(zone, thingKind, maybeStartBackgroundAllocation); -} - void Nursery::setForwardingPointer(void* oldData, void* newData, bool direct) { @@ -447,291 +372,32 @@ js::Nursery::forwardBufferPointer(HeapSlot** pSlotsElems) MOZ_ASSERT(IsWriteableAddress(*pSlotsElems)); } -// Structure for counting how many times objects in a particular group have -// been tenured during a minor collection. -struct TenureCount +js::TenuringTracer::TenuringTracer(JSRuntime* rt, Nursery* nursery) + : JSTracer(rt, JSTracer::TracerKindTag::Tenuring, TraceWeakMapKeysValues) + , nursery_(*nursery) + , tenuredSize(0) + , head(nullptr) + , tail(&head) + , savedRuntimeNeedBarrier(rt->needsIncrementalBarrier()) +#ifdef JS_GC_ZEAL + , verifyingPostBarriers(nullptr) +#endif { - ObjectGroup* group; - int count; -}; + rt->gc.incGcNumber(); -// Keep rough track of how many times we tenure objects in particular groups -// during minor collections, using a fixed size hash for efficiency at the cost -// of potential collisions. -struct Nursery::TenureCountCache -{ - TenureCount entries[16]; - - TenureCountCache() { PodZero(this); } - - TenureCount& findEntry(ObjectGroup* group) { - return entries[PointerHasher::hash(group) % ArrayLength(entries)]; - } -}; - -void -js::Nursery::collectToFixedPoint(MinorCollectionTracer* trc, TenureCountCache& tenureCounts) -{ - for (RelocationOverlay* p = trc->head; p; p = p->next()) { - JSObject* obj = static_cast(p->forwardingAddress()); - traceObject(trc, obj); - - TenureCount& entry = tenureCounts.findEntry(obj->group()); - if (entry.group == obj->group()) { - entry.count++; - } else if (!entry.group) { - entry.group = obj->group(); - entry.count = 1; - } - } + // We disable the runtime needsIncrementalBarrier() check so that + // pre-barriers do not fire on objects that have been relocated. The + // pre-barrier's call to obj->zone() will try to look through shape_, + // which is now the relocation magic and will crash. However, + // zone->needsIncrementalBarrier() must still be set correctly so that + // allocations we make in minor GCs between incremental slices will + // allocate their objects marked. + rt->setNeedsIncrementalBarrier(false); } -MOZ_ALWAYS_INLINE void -js::Nursery::traceObject(MinorCollectionTracer* trc, JSObject* obj) +js::TenuringTracer::~TenuringTracer() { - const Class* clasp = obj->getClass(); - if (clasp->trace) { - if (clasp->trace == InlineTypedObject::obj_trace) { - TypeDescr* descr = &obj->as().typeDescr(); - if (descr->hasTraceList()) { - markTraceList(trc, descr->traceList(), - obj->as().inlineTypedMem()); - } - return; - } - if (clasp == &UnboxedPlainObject::class_) { - JSObject** pexpando = obj->as().addressOfExpando(); - if (*pexpando) - markObject(trc, pexpando); - const UnboxedLayout& layout = obj->as().layoutDontCheckGeneration(); - if (layout.traceList()) { - markTraceList(trc, layout.traceList(), - obj->as().data()); - } - return; - } - clasp->trace(trc, obj); - } - - MOZ_ASSERT(obj->isNative() == clasp->isNative()); - if (!clasp->isNative()) - return; - NativeObject* nobj = &obj->as(); - - // Note: the contents of copy on write elements pointers are filled in - // during parsing and cannot contain nursery pointers. - if (!nobj->hasEmptyElements() && !nobj->denseElementsAreCopyOnWrite()) - markSlots(trc, nobj->getDenseElements(), nobj->getDenseInitializedLength()); - - HeapSlot* fixedStart; - HeapSlot* fixedEnd; - HeapSlot* dynStart; - HeapSlot* dynEnd; - nobj->getSlotRange(0, nobj->slotSpan(), &fixedStart, &fixedEnd, &dynStart, &dynEnd); - markSlots(trc, fixedStart, fixedEnd); - markSlots(trc, dynStart, dynEnd); -} - -MOZ_ALWAYS_INLINE void -js::Nursery::markSlots(MinorCollectionTracer* trc, HeapSlot* vp, uint32_t nslots) -{ - markSlots(trc, vp, vp + nslots); -} - -MOZ_ALWAYS_INLINE void -js::Nursery::markSlots(MinorCollectionTracer* trc, HeapSlot* vp, HeapSlot* end) -{ - for (; vp != end; ++vp) - markSlot(trc, vp); -} - -MOZ_ALWAYS_INLINE void -js::Nursery::markSlot(MinorCollectionTracer* trc, HeapSlot* slotp) -{ - if (!slotp->isObject()) - return; - - JSObject* obj = &slotp->toObject(); - if (markObject(trc, &obj)) - slotp->unsafeGet()->setObject(*obj); -} - -MOZ_ALWAYS_INLINE void -js::Nursery::markTraceList(MinorCollectionTracer* trc, const int32_t* traceList, uint8_t* memory) -{ - while (*traceList != -1) { - // Strings are not in the nursery and do not need tracing. - traceList++; - } - traceList++; - while (*traceList != -1) { - JSObject** pobj = reinterpret_cast(memory + *traceList); - markObject(trc, pobj); - traceList++; - } - traceList++; - while (*traceList != -1) { - HeapSlot* pslot = reinterpret_cast(memory + *traceList); - markSlot(trc, pslot); - traceList++; - } -} - -MOZ_ALWAYS_INLINE bool -js::Nursery::markObject(MinorCollectionTracer* trc, JSObject** pobj) -{ - if (!IsInsideNursery(*pobj)) - return false; - - if (getForwardedPointer(pobj)) - return true; - - *pobj = static_cast(moveToTenured(trc, *pobj)); - return true; -} - -void* -js::Nursery::moveToTenured(MinorCollectionTracer* trc, JSObject* src) -{ - - AllocKind dstKind = src->allocKindForTenure(*this); - Zone* zone = src->zone(); - JSObject* dst = reinterpret_cast(allocateFromTenured(zone, dstKind)); - if (!dst) - CrashAtUnhandlableOOM("Failed to allocate object while tenuring."); - - trc->tenuredSize += moveObjectToTenured(trc, dst, src, dstKind); - - RelocationOverlay* overlay = RelocationOverlay::fromCell(src); - overlay->forwardTo(dst); - trc->insertIntoFixupList(overlay); - - TracePromoteToTenured(src, dst); - return static_cast(dst); -} - -MOZ_ALWAYS_INLINE size_t -js::Nursery::moveObjectToTenured(MinorCollectionTracer* trc, - JSObject* dst, JSObject* src, AllocKind dstKind) -{ - size_t srcSize = Arena::thingSize(dstKind); - size_t tenuredSize = srcSize; - - /* - * Arrays do not necessarily have the same AllocKind between src and dst. - * We deal with this by copying elements manually, possibly re-inlining - * them if there is adequate room inline in dst. - * - * For Arrays we're reducing tenuredSize to the smaller srcSize - * because moveElementsToTenured() accounts for all Array elements, - * even if they are inlined. - */ - if (src->is()) - tenuredSize = srcSize = sizeof(NativeObject); - - js_memcpy(dst, src, srcSize); - if (src->isNative()) { - NativeObject* ndst = &dst->as(); - NativeObject* nsrc = &src->as(); - tenuredSize += moveSlotsToTenured(ndst, nsrc, dstKind); - tenuredSize += moveElementsToTenured(ndst, nsrc, dstKind); - - // The shape's list head may point into the old object. This can only - // happen for dictionaries, which are native objects. - if (&nsrc->shape_ == ndst->shape_->listp) { - MOZ_ASSERT(nsrc->shape_->inDictionary()); - ndst->shape_->listp = &ndst->shape_; - } - } - - if (src->is()) { - InlineTypedObject::objectMovedDuringMinorGC(trc, dst, src); - } else if (src->is()) { - tenuredSize += UnboxedArrayObject::objectMovedDuringMinorGC(trc, dst, src, dstKind); - } else { - // Objects with JSCLASS_SKIP_NURSERY_FINALIZE need to be handled above - // to ensure any additional nursery buffers they hold are moved. - MOZ_ASSERT(!(src->getClass()->flags & JSCLASS_SKIP_NURSERY_FINALIZE)); - } - - return tenuredSize; -} - -MOZ_ALWAYS_INLINE size_t -js::Nursery::moveSlotsToTenured(NativeObject* dst, NativeObject* src, AllocKind dstKind) -{ - /* Fixed slots have already been copied over. */ - if (!src->hasDynamicSlots()) - return 0; - - if (!isInside(src->slots_)) { - removeMallocedBuffer(src->slots_); - return 0; - } - - Zone* zone = src->zone(); - size_t count = src->numDynamicSlots(); - dst->slots_ = zone->pod_malloc(count); - if (!dst->slots_) - CrashAtUnhandlableOOM("Failed to allocate slots while tenuring."); - PodCopy(dst->slots_, src->slots_, count); - setSlotsForwardingPointer(src->slots_, dst->slots_, count); - return count * sizeof(HeapSlot); -} - -MOZ_ALWAYS_INLINE size_t -js::Nursery::moveElementsToTenured(NativeObject* dst, NativeObject* src, AllocKind dstKind) -{ - if (src->hasEmptyElements() || src->denseElementsAreCopyOnWrite()) - return 0; - - Zone* zone = src->zone(); - ObjectElements* srcHeader = src->getElementsHeader(); - ObjectElements* dstHeader; - - /* TODO Bug 874151: Prefer to put element data inline if we have space. */ - if (!isInside(srcHeader)) { - MOZ_ASSERT(src->elements_ == dst->elements_); - removeMallocedBuffer(srcHeader); - return 0; - } - - size_t nslots = ObjectElements::VALUES_PER_HEADER + srcHeader->capacity; - - /* Unlike other objects, Arrays can have fixed elements. */ - if (src->is() && nslots <= GetGCKindSlots(dstKind)) { - dst->as().setFixedElements(); - dstHeader = dst->as().getElementsHeader(); - js_memcpy(dstHeader, srcHeader, nslots * sizeof(HeapSlot)); - setElementsForwardingPointer(srcHeader, dstHeader, nslots); - return nslots * sizeof(HeapSlot); - } - - MOZ_ASSERT(nslots >= 2); - dstHeader = reinterpret_cast(zone->pod_malloc(nslots)); - if (!dstHeader) - CrashAtUnhandlableOOM("Failed to allocate elements while tenuring."); - js_memcpy(dstHeader, srcHeader, nslots * sizeof(HeapSlot)); - setElementsForwardingPointer(srcHeader, dstHeader, nslots); - dst->elements_ = dstHeader->elements(); - return nslots * sizeof(HeapSlot); -} - -static bool -ShouldMoveToTenured(MinorCollectionTracer* trc, void** thingp) -{ - Cell* cell = static_cast(*thingp); - Nursery& nursery = *trc->nursery; - return !nursery.isInside(thingp) && IsInsideNursery(cell) && - !nursery.getForwardedPointer(thingp); -} - -/* static */ void -js::Nursery::MinorGCCallback(JS::CallbackTracer* jstrc, void** thingp, JSGCTraceKind kind) -{ - MinorCollectionTracer* trc = static_cast(jstrc); - if (ShouldMoveToTenured(trc, thingp)) - *thingp = trc->nursery->moveToTenured(trc, static_cast(*thingp)); + runtime()->setNeedsIncrementalBarrier(savedRuntimeNeedBarrier); } #define TIME_START(name) int64_t timstampStart_##name = enableProfiling_ ? PRMJ_Now() : 0 @@ -766,48 +432,51 @@ js::Nursery::collect(JSRuntime* rt, JS::gcreason::Reason reason, ObjectGroupList TIME_START(total); + AutoTraceSession session(rt, MinorCollecting); AutoStopVerifyingBarriers av(rt, false); + AutoDisableProxyCheck disableStrictProxyChecking(rt); + DebugOnly oomUnsafeRegion; // Move objects pointed to by roots from the nursery to the major heap. - MinorCollectionTracer trc(rt, this); + TenuringTracer mover(rt, this); // Mark the store buffer. This must happen first. TIME_START(markValues); - sb.markValues(&trc); + sb.markValues(mover); TIME_END(markValues); TIME_START(markCells); - sb.markCells(&trc); + sb.markCells(mover); TIME_END(markCells); TIME_START(markSlots); - sb.markSlots(&trc); + sb.markSlots(mover); TIME_END(markSlots); TIME_START(markWholeCells); - sb.markWholeCells(&trc); + sb.markWholeCells(mover); TIME_END(markWholeCells); TIME_START(markRelocatableValues); - sb.markRelocatableValues(&trc); + sb.markRelocatableValues(mover); TIME_END(markRelocatableValues); TIME_START(markRelocatableCells); - sb.markRelocatableCells(&trc); + sb.markRelocatableCells(mover); TIME_END(markRelocatableCells); TIME_START(markGenericEntries); - sb.markGenericEntries(&trc); + sb.markGenericEntries(&mover); TIME_END(markGenericEntries); TIME_START(markRuntime); - rt->gc.markRuntime(&trc); + rt->gc.markRuntime(&mover); TIME_END(markRuntime); TIME_START(markDebugger); { gcstats::AutoPhase ap(rt->gc.stats, gcstats::PHASE_MARK_ROOTS); - Debugger::markAll(&trc); + Debugger::markAll(&mover); } TIME_END(markDebugger); @@ -821,7 +490,7 @@ js::Nursery::collect(JSRuntime* rt, JS::gcreason::Reason reason, ObjectGroupList // objects are left to move. That is, we iterate to a fixed point. TIME_START(collectToFP); TenureCountCache tenureCounts; - collectToFixedPoint(&trc, tenureCounts); + collectToFixedPoint(mover, tenureCounts); TIME_END(collectToFP); // Update the array buffer object's view lists. @@ -834,7 +503,7 @@ js::Nursery::collect(JSRuntime* rt, JS::gcreason::Reason reason, ObjectGroupList // Update any slot or element pointers whose destination has been tenured. TIME_START(updateJitActivations); - js::jit::UpdateJitActivationsForMinorGC(rt, &trc); + js::jit::UpdateJitActivationsForMinorGC(rt, &mover); forwardedBuffers.finish(); TIME_END(updateJitActivations); @@ -861,7 +530,7 @@ js::Nursery::collect(JSRuntime* rt, JS::gcreason::Reason reason, ObjectGroupList // Resize the nursery. TIME_START(resize); - double promotionRate = trc.tenuredSize / double(allocationEnd() - start()); + double promotionRate = mover.tenuredSize / double(allocationEnd() - start()); if (promotionRate > 0.05) growAllocableSpace(); else if (promotionRate < 0.01) diff --git a/js/src/gc/Nursery.h b/js/src/gc/Nursery.h index 8359d3ba223..94fddeb310e 100644 --- a/js/src/gc/Nursery.h +++ b/js/src/gc/Nursery.h @@ -29,6 +29,7 @@ namespace js { class ObjectElements; class NativeObject; +class Nursery; class HeapSlot; class ObjectGroup; @@ -37,12 +38,44 @@ void SetGCZeal(JSRuntime*, uint8_t, uint32_t); namespace gc { struct Cell; class MinorCollectionTracer; +class RelocationOverlay; } /* namespace gc */ namespace jit { class MacroAssembler; } +class TenuringTracer : public JSTracer +{ + friend class Nursery; + Nursery& nursery_; + + // Amount of data moved to the tenured generation during collection. + size_t tenuredSize; + + // This list is threaded through the Nursery using the space from already + // moved things. The list is used to fix up the moved things and to find + // things held live by intra-Nursery pointers. + gc::RelocationOverlay* head; + gc::RelocationOverlay** tail; + + // Save and restore all of the runtime state we use during MinorGC. + bool savedRuntimeNeedBarrier; + + TenuringTracer(JSRuntime* rt, Nursery* nursery); + ~TenuringTracer(); + + public: + const Nursery& nursery() const { return nursery_; } + JSObject* moveToTenured(JSObject* thing); + + void insertIntoFixupList(gc::RelocationOverlay* entry); + +#ifdef JS_GC_ZEAL + bool verifyingPostBarriers; +#endif +}; + class Nursery { public: @@ -122,14 +155,13 @@ class Nursery * sets |*ref| to the new location of the object and returns true. Otherwise * returns false and leaves |*ref| unset. */ - template - MOZ_ALWAYS_INLINE bool getForwardedPointer(T** ref); + MOZ_ALWAYS_INLINE bool getForwardedPointer(JSObject** ref) const; /* Forward a slots/elements pointer stored in an Ion frame. */ void forwardBufferPointer(HeapSlot** pSlotsElems); void maybeSetForwardingPointer(JSTracer* trc, void* oldData, void* newData, bool direct) { - if (IsMinorCollectionTracer(trc) && isInside(oldData)) + if (trc->isTenuringTracer() && isInside(oldData)) setForwardingPointer(oldData, newData, direct); } @@ -162,10 +194,6 @@ class Nursery return heapEnd_; } - static bool IsMinorCollectionTracer(JSTracer* trc) { - return trc->isCallbackTracer() && trc->asCallbackTracer()->hasCallback(MinorGCCallback); - } - #ifdef JS_GC_ZEAL void enterZealMode(); void leaveZealMode(); @@ -297,16 +325,16 @@ class Nursery * Move the object at |src| in the Nursery to an already-allocated cell * |dst| in Tenured. */ - void collectToFixedPoint(gc::MinorCollectionTracer* trc, TenureCountCache& tenureCounts); - MOZ_ALWAYS_INLINE void traceObject(gc::MinorCollectionTracer* trc, JSObject* src); - MOZ_ALWAYS_INLINE void markSlots(gc::MinorCollectionTracer* trc, HeapSlot* vp, uint32_t nslots); - MOZ_ALWAYS_INLINE void markSlots(gc::MinorCollectionTracer* trc, HeapSlot* vp, HeapSlot* end); - MOZ_ALWAYS_INLINE void markSlot(gc::MinorCollectionTracer* trc, HeapSlot* slotp); - MOZ_ALWAYS_INLINE void markTraceList(gc::MinorCollectionTracer* trc, + void collectToFixedPoint(TenuringTracer& trc, TenureCountCache& tenureCounts); + MOZ_ALWAYS_INLINE void traceObject(TenuringTracer& trc, JSObject* src); + MOZ_ALWAYS_INLINE void markSlots(TenuringTracer& trc, HeapSlot* vp, uint32_t nslots); + MOZ_ALWAYS_INLINE void markSlots(TenuringTracer& trc, HeapSlot* vp, HeapSlot* end); + MOZ_ALWAYS_INLINE void markSlot(TenuringTracer& trc, HeapSlot* slotp); + MOZ_ALWAYS_INLINE void markTraceList(TenuringTracer& trc, const int32_t* traceList, uint8_t* memory); - MOZ_ALWAYS_INLINE bool markObject(gc::MinorCollectionTracer* trc, JSObject** pobj); - void* moveToTenured(gc::MinorCollectionTracer* trc, JSObject* src); - size_t moveObjectToTenured(gc::MinorCollectionTracer* trc, JSObject* dst, JSObject* src, + MOZ_ALWAYS_INLINE bool markObject(TenuringTracer& trc, JSObject** pobj); + void* moveToTenured(TenuringTracer& trc, JSObject* src); + size_t moveObjectToTenured(TenuringTracer& trc, JSObject* dst, JSObject* src, gc::AllocKind dstKind); size_t moveElementsToTenured(NativeObject* dst, NativeObject* src, gc::AllocKind dstKind); size_t moveSlotsToTenured(NativeObject* dst, NativeObject* src, gc::AllocKind dstKind); @@ -331,8 +359,7 @@ class Nursery void growAllocableSpace(); void shrinkAllocableSpace(); - static void MinorGCCallback(JS::CallbackTracer* trc, void** thingp, JSGCTraceKind kind); - + friend class TenuringTracer; friend class gc::MinorCollectionTracer; friend class jit::MacroAssembler; }; diff --git a/js/src/gc/RootMarking.cpp b/js/src/gc/RootMarking.cpp index a9f685ea896..21062f34b73 100644 --- a/js/src/gc/RootMarking.cpp +++ b/js/src/gc/RootMarking.cpp @@ -216,7 +216,6 @@ AutoGCRooter::trace(JSTracer* trc) for (AutoObjectObjectHashMap::Enum e(map); !e.empty(); e.popFront()) { TraceRoot(trc, &e.front().value(), "AutoObjectObjectHashMap value"); JSObject* key = e.front().key(); - JS::AutoOriginalTraceLocation reloc(trc, &e.front().key()); TraceRoot(trc, &key, "AutoObjectObjectHashMap key"); if (key != e.front().key()) e.rekeyFront(key); diff --git a/js/src/gc/StoreBuffer.cpp b/js/src/gc/StoreBuffer.cpp index 4ee431a6f9b..6089b10ce2d 100644 --- a/js/src/gc/StoreBuffer.cpp +++ b/js/src/gc/StoreBuffer.cpp @@ -16,91 +16,11 @@ using namespace js; using namespace js::gc; -using mozilla::ReentrancyGuard; - -/*** Edges ***/ - -void -StoreBuffer::SlotsEdge::mark(JSTracer* trc) const -{ - NativeObject* obj = object(); - - // Beware JSObject::swap exchanging a native object for a non-native one. - if (!obj->isNative()) - return; - - if (IsInsideNursery(obj)) - return; - - if (kind() == ElementKind) { - int32_t initLen = obj->getDenseInitializedLength(); - int32_t clampedStart = Min(start_, initLen); - int32_t clampedEnd = Min(start_ + count_, initLen); - TraceRange(trc, clampedEnd - clampedStart, - static_cast(obj->getDenseElements() + clampedStart), "element"); - } else { - int32_t start = Min(uint32_t(start_), obj->slotSpan()); - int32_t end = Min(uint32_t(start_) + count_, obj->slotSpan()); - MOZ_ASSERT(end >= start); - TraceObjectSlots(trc, obj, start, end - start); - } -} - -void -StoreBuffer::WholeCellEdges::mark(JSTracer* trc) const -{ - MOZ_ASSERT(edge->isTenured()); - JSGCTraceKind kind = GetGCThingTraceKind(edge); - if (kind <= JSTRACE_OBJECT) { - JSObject* object = static_cast(edge); - if (object->is()) - ArgumentsObject::trace(trc, object); - object->traceChildren(trc); - return; - } - MOZ_ASSERT(kind == JSTRACE_JITCODE); - static_cast(edge)->traceChildren(trc); -} - -void -StoreBuffer::CellPtrEdge::mark(JSTracer* trc) const -{ - if (!*edge) - return; - - MOZ_ASSERT(GetGCThingTraceKind(*edge) == JSTRACE_OBJECT); - TraceRoot(trc, reinterpret_cast(edge), "store buffer edge"); -} - -void -StoreBuffer::ValueEdge::mark(JSTracer* trc) const -{ - if (!deref()) - return; - - TraceRoot(trc, edge, "store buffer edge"); -} - -/*** MonoTypeBuffer ***/ - -template -void -StoreBuffer::MonoTypeBuffer::mark(StoreBuffer* owner, JSTracer* trc) -{ - ReentrancyGuard g(*owner); - MOZ_ASSERT(owner->isEnabled()); - MOZ_ASSERT(stores_.initialized()); - sinkStores(owner); - for (typename StoreSet::Range r = stores_.all(); !r.empty(); r.popFront()) - r.front().mark(trc); -} - -/*** GenericBuffer ***/ void StoreBuffer::GenericBuffer::mark(StoreBuffer* owner, JSTracer* trc) { - ReentrancyGuard g(*owner); + mozilla::ReentrancyGuard g(*owner); MOZ_ASSERT(owner->isEnabled()); if (!storage_) return; @@ -114,8 +34,6 @@ StoreBuffer::GenericBuffer::mark(StoreBuffer* owner, JSTracer* trc) } } -/*** StoreBuffer ***/ - bool StoreBuffer::enable() { @@ -167,18 +85,6 @@ StoreBuffer::clear() return true; } -void -StoreBuffer::markAll(JSTracer* trc) -{ - bufferVal.mark(this, trc); - bufferCell.mark(this, trc); - bufferSlot.mark(this, trc); - bufferWholeCell.mark(this, trc); - bufferRelocVal.mark(this, trc); - bufferRelocCell.mark(this, trc); - bufferGeneric.mark(this, trc); -} - void StoreBuffer::setAboutToOverflow() { diff --git a/js/src/gc/StoreBuffer.h b/js/src/gc/StoreBuffer.h index 6a9abc2aec1..07055ebfd74 100644 --- a/js/src/gc/StoreBuffer.h +++ b/js/src/gc/StoreBuffer.h @@ -122,7 +122,7 @@ class StoreBuffer } /* Mark the source of all edges in the store buffer. */ - void mark(StoreBuffer* owner, JSTracer* trc); + void mark(StoreBuffer* owner, TenuringTracer& mover); size_t sizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf) { return stores_.sizeOfExcludingThis(mallocSizeOf); @@ -211,7 +211,7 @@ class StoreBuffer return !nursery.isInside(edge); } - void mark(JSTracer* trc) const; + void mark(TenuringTracer& mover) const; CellPtrEdge tagged() const { return CellPtrEdge((Cell**)(uintptr_t(edge) | 1)); } CellPtrEdge untagged() const { return CellPtrEdge((Cell**)(uintptr_t(edge) & ~1)); } @@ -236,7 +236,7 @@ class StoreBuffer return !nursery.isInside(edge); } - void mark(JSTracer* trc) const; + void mark(TenuringTracer& mover) const; ValueEdge tagged() const { return ValueEdge((JS::Value*)(uintptr_t(edge) | 1)); } ValueEdge untagged() const { return ValueEdge((JS::Value*)(uintptr_t(edge) & ~1)); } @@ -282,7 +282,7 @@ class StoreBuffer return !IsInsideNursery(reinterpret_cast(object())); } - void mark(JSTracer* trc) const; + void mark(TenuringTracer& mover) const; typedef struct { typedef SlotsEdge Lookup; @@ -308,7 +308,7 @@ class StoreBuffer static bool supportsDeduplication() { return true; } void* deduplicationKey() const { return (void*)edge; } - void mark(JSTracer* trc) const; + void mark(TenuringTracer& mover) const; typedef PointerEdgeHasher Hasher; }; @@ -444,14 +444,13 @@ class StoreBuffer } /* Methods to mark the source of all edges in the store buffer. */ - void markAll(JSTracer* trc); - void markValues(JSTracer* trc) { bufferVal.mark(this, trc); } - void markCells(JSTracer* trc) { bufferCell.mark(this, trc); } - void markSlots(JSTracer* trc) { bufferSlot.mark(this, trc); } - void markWholeCells(JSTracer* trc) { bufferWholeCell.mark(this, trc); } - void markRelocatableValues(JSTracer* trc) { bufferRelocVal.mark(this, trc); } - void markRelocatableCells(JSTracer* trc) { bufferRelocCell.mark(this, trc); } - void markGenericEntries(JSTracer* trc) { bufferGeneric.mark(this, trc); } + void markValues(TenuringTracer& mover) { bufferVal.mark(this, mover); } + void markCells(TenuringTracer& mover) { bufferCell.mark(this, mover); } + void markSlots(TenuringTracer& mover) { bufferSlot.mark(this, mover); } + void markWholeCells(TenuringTracer& mover) { bufferWholeCell.mark(this, mover); } + void markRelocatableValues(TenuringTracer& mover) { bufferRelocVal.mark(this, mover); } + void markRelocatableCells(TenuringTracer& mover) { bufferRelocCell.mark(this, mover); } + void markGenericEntries(JSTracer *trc) { bufferGeneric.mark(this, trc); } /* For use by our owned buffers and for testing. */ void setAboutToOverflow(); diff --git a/js/src/gc/Tracer.cpp b/js/src/gc/Tracer.cpp index 8373bf073c7..d717f73c472 100644 --- a/js/src/gc/Tracer.cpp +++ b/js/src/gc/Tracer.cpp @@ -168,7 +168,6 @@ JS_CallTenuredObjectTracer(JSTracer* trc, JS::TenuredHeap* objp, cons if (!obj) return; - JS::AutoOriginalTraceLocation reloc(trc, (void**)objp); TraceManuallyBarrieredEdge(trc, &obj, name); objp->setPtr(obj); diff --git a/js/src/gc/Verifier.cpp b/js/src/gc/Verifier.cpp index e6313914e52..b39c81b81bf 100644 --- a/js/src/gc/Verifier.cpp +++ b/js/src/gc/Verifier.cpp @@ -376,144 +376,6 @@ gc::GCRuntime::endVerifyPreBarriers() return true; } -/*** Post-Barrier Verifyier ***/ - -struct VerifyPostTracer : JS::CallbackTracer -{ - /* The gcNumber when the verification began. */ - uint64_t number; - - /* This counts up to gcZealFrequency to decide whether to verify. */ - int count; - - /* The set of edges in the StoreBuffer at the end of verification. */ - typedef HashSet, SystemAllocPolicy> EdgeSet; - EdgeSet* edges; - - VerifyPostTracer(JSRuntime* rt, JSTraceCallback callback) - : JS::CallbackTracer(rt, callback), number(rt->gc.gcNumber()), count(0) - {} -}; - -/* - * The post-barrier verifier runs the full store buffer and a fake nursery when - * running and when it stops, walks the full heap to ensure that all the - * important edges were inserted into the storebuffer. - */ -void -gc::GCRuntime::startVerifyPostBarriers() -{ - if (!JS::IsGenerationalGCEnabled(rt) || verifyPostData || isIncrementalGCInProgress()) - return; - - evictNursery(); - - number++; - - VerifyPostTracer* trc = js_new(rt, JSTraceCallback(nullptr)); - if (!trc) - return; - - verifyPostData = trc; -} - -void -PostVerifierCollectStoreBufferEdges(JS::CallbackTracer* jstrc, void** thingp, JSGCTraceKind kind) -{ - VerifyPostTracer* trc = (VerifyPostTracer*)jstrc; - - /* The nursery only stores objects. */ - if (kind != JSTRACE_OBJECT) - return; - - /* The store buffer may store extra, non-cross-generational edges. */ - JSObject* dst = *reinterpret_cast(thingp); - if (trc->runtime()->gc.nursery.isInside(thingp) || !IsInsideNursery(dst)) - return; - - /* - * Values will be unpacked to the stack before getting here. However, the - * only things that enter this callback are marked by the store buffer. The - * store buffer ensures that the real tracing location is set correctly. - */ - void*const* loc = trc->tracingLocation(thingp); - - trc->edges->put(loc); -} - -static void -AssertStoreBufferContainsEdge(VerifyPostTracer::EdgeSet* edges, void*const* loc, JSObject* dst) -{ - if (edges->has(loc)) - return; - - char msgbuf[1024]; - JS_snprintf(msgbuf, sizeof(msgbuf), "[post-barrier verifier] Missing edge @ %p to %p", - (void*)loc, (void*)dst); - MOZ_ReportAssertionFailure(msgbuf, __FILE__, __LINE__); - MOZ_CRASH(); -} - -void -PostVerifierVisitEdge(JS::CallbackTracer* jstrc, void** thingp, JSGCTraceKind kind) -{ - VerifyPostTracer* trc = (VerifyPostTracer*)jstrc; - - /* The nursery only stores objects. */ - if (kind != JSTRACE_OBJECT) - return; - - /* Filter out non cross-generational edges. */ - MOZ_ASSERT(!trc->runtime()->gc.nursery.isInside(thingp)); - JSObject* dst = *reinterpret_cast(thingp); - if (!IsInsideNursery(dst)) - return; - - /* - * Values will be unpacked to the stack before getting here. However, the - * only things that enter this callback are marked by the JS_TraceChildren - * below. Since JSObject::markChildren handles this, the real trace - * location will be set correctly in these cases. - */ - void*const* loc = trc->tracingLocation(thingp); - - AssertStoreBufferContainsEdge(trc->edges, loc, dst); -} - -bool -js::gc::GCRuntime::endVerifyPostBarriers() -{ - VerifyPostTracer* trc = (VerifyPostTracer*)verifyPostData; - if (!trc) - return false; - - VerifyPostTracer::EdgeSet edges; - AutoPrepareForTracing prep(rt, SkipAtoms); - - /* Visit every entry in the store buffer and put the edges in a hash set. */ - trc->setTraceCallback(PostVerifierCollectStoreBufferEdges); - if (!edges.init()) - goto oom; - trc->edges = &edges; - storeBuffer.markAll(trc); - - /* Walk the heap to find any edges not the the |edges| set. */ - trc->setTraceCallback(PostVerifierVisitEdge); - for (GCZoneGroupIter zone(rt); !zone.done(); zone.next()) { - for (auto kind : AllAllocKinds()) { - for (ZoneCellIterUnderGC cells(zone, kind); !cells.done(); cells.next()) { - Cell* src = cells.getCell(); - JS_TraceChildren(trc, src, MapAllocToTraceKind(kind)); - } - } - } - -oom: - js_delete(trc); - verifyPostData = nullptr; - return true; -} - /*** Barrier Verifier Scheduling ***/ void @@ -525,22 +387,11 @@ gc::GCRuntime::verifyPreBarriers() startVerifyPreBarriers(); } -void -gc::GCRuntime::verifyPostBarriers() -{ - if (verifyPostData) - endVerifyPostBarriers(); - else - startVerifyPostBarriers(); -} - void gc::VerifyBarriers(JSRuntime* rt, VerifierType type) { if (type == PreBarrierVerifier) rt->gc.verifyPreBarriers(); - else - rt->gc.verifyPostBarriers(); } void @@ -562,30 +413,11 @@ gc::GCRuntime::maybeVerifyPreBarriers(bool always) startVerifyPreBarriers(); } -void -gc::GCRuntime::maybeVerifyPostBarriers(bool always) -{ - if (zealMode != ZealVerifierPostValue) - return; - - if (rt->mainThread.suppressGC || !storeBuffer.isEnabled()) - return; - - if (VerifyPostTracer* trc = (VerifyPostTracer*)verifyPostData) { - if (++trc->count < zealFrequency && !always) - return; - - endVerifyPostBarriers(); - } - startVerifyPostBarriers(); -} - void js::gc::MaybeVerifyBarriers(JSContext* cx, bool always) { GCRuntime* gc = &cx->runtime()->gc; gc->maybeVerifyPreBarriers(always); - gc->maybeVerifyPostBarriers(always); } void @@ -595,10 +427,6 @@ js::gc::GCRuntime::finishVerifier() js_delete(trc); verifyPreData = nullptr; } - if (VerifyPostTracer* trc = (VerifyPostTracer*)verifyPostData) { - js_delete(trc); - verifyPostData = nullptr; - } } #endif /* JS_GC_ZEAL */ diff --git a/js/src/jit-test/tests/ion/bug1159899.js b/js/src/jit-test/tests/ion/bug1159899.js new file mode 100644 index 00000000000..10d930f3b90 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1159899.js @@ -0,0 +1,5 @@ +function f(x) { + return ~~(x >>> 0) / (x >>> 0) | 0 +} +f(1) +assertEq(f(-1), 0); diff --git a/js/src/jit-test/tests/ion/recover-objects.js b/js/src/jit-test/tests/ion/recover-objects.js index 68a339cf131..07a990b606f 100644 --- a/js/src/jit-test/tests/ion/recover-objects.js +++ b/js/src/jit-test/tests/ion/recover-objects.js @@ -19,11 +19,11 @@ function inline_notSoEmpty1(a, b, c, d) { } var uceFault_notSoEmpty1 = eval(uneval(uceFault).replace('uceFault', 'uceFault_notSoEmpty1')); function notSoEmpty1() { - var a = { v: i }; - var b = { v: 1 + a.v }; - var c = { v: 2 + b.v }; - var d = { v: 3 + c.v }; - var unused = { v: 4 + d.v }; + var a = { v: i, notunboxed: undefined }; + var b = { v: 1 + a.v, notunboxed: undefined }; + var c = { v: 2 + b.v, notunboxed: undefined }; + var d = { v: 3 + c.v, notunboxed: undefined }; + var unused = { v: 4 + d.v, notunboxed: undefined }; var res = inline_notSoEmpty1(a, b, c, d); if (uceFault_notSoEmpty1(i) || uceFault_notSoEmpty1(i)) assertEq(i, res.v); @@ -44,15 +44,15 @@ function notSoEmpty1() { // Check that we can recover objects with their content. function inline_notSoEmpty2(a, b, c, d) { "use strict"; - return { v: (a.v + b.v + c.v + d.v - 10) / 4 }; + return { v: (a.v + b.v + c.v + d.v - 10) / 4, notunboxed: undefined }; } var uceFault_notSoEmpty2 = eval(uneval(uceFault).replace('uceFault', 'uceFault_notSoEmpty2')); function notSoEmpty2(i) { - var a = { v: i }; - var b = { v: 1 + a.v }; - var c = { v: 2 + b.v }; - var d = { v: 3 + c.v }; - var unused = { v: 4 + d.v }; + var a = { v: i, notunboxed: undefined }; + var b = { v: 1 + a.v, notunboxed: undefined }; + var c = { v: 2 + b.v, notunboxed: undefined }; + var d = { v: 3 + c.v, notunboxed: undefined }; + var unused = { v: 4 + d.v, notunboxed: undefined }; var res = inline_notSoEmpty2(a, b, c, d); if (uceFault_notSoEmpty2(i) || uceFault_notSoEmpty2(i)) assertEq(i, res.v); @@ -70,13 +70,13 @@ function notSoEmpty2(i) { var argFault_observeArg = function (i) { if (i > 98) return inline_observeArg.arguments[0]; - return { test : i }; + return { test : i, notunboxed: undefined }; }; function inline_observeArg(obj, i) { return argFault_observeArg(i); } function observeArg(i) { - var obj = { test: i }; + var obj = { test: i, notunboxed: undefined }; var res = inline_observeArg(obj, i); assertEq(res.test, i); assertRecoveredOnBailout(obj, true); @@ -84,7 +84,7 @@ function observeArg(i) { // Check case where one successor can have multiple times the same predecessor. function complexPhi(i) { - var obj = { test: i }; + var obj = { test: i, notunboxed: undefined }; switch (i) { // TableSwitch case 0: obj.test = 0; break; case 1: obj.test = 1; break; @@ -103,12 +103,12 @@ function complexPhi(i) { function withinIf(i) { var x = undefined; if (i % 2 == 0) { - let obj = { foo: i }; + let obj = { foo: i, notunboxed: undefined }; x = obj.foo; assertRecoveredOnBailout(obj, true); obj = undefined; } else { - let obj = { bar: i }; + let obj = { bar: i, notunboxed: undefined }; x = obj.bar; assertRecoveredOnBailout(obj, true); obj = undefined; @@ -118,7 +118,7 @@ function withinIf(i) { // Check case where one successor can have multiple times the same predecessor. function unknownLoad(i) { - var obj = { foo: i }; + var obj = { foo: i, notunboxed: undefined }; assertEq(obj.bar, undefined); // Unknown properties are using GetPropertyCache. assertRecoveredOnBailout(obj, false); @@ -132,7 +132,8 @@ function dynamicSlots(i) { p11: i + 11, p12: i + 12, p13: i + 13, p14: i + 14, p15: i + 15, p16: i + 16, p17: i + 17, p18: i + 18, p19: i + 19, p20: i + 20, p21: i + 21, p22: i + 22, p23: i + 23, p24: i + 24, p25: i + 25, p26: i + 26, p27: i + 27, p28: i + 28, p29: i + 29, p30: i + 30, p31: i + 31, p32: i + 32, p33: i + 33, p34: i + 34, p35: i + 35, p36: i + 36, p37: i + 37, p38: i + 38, p39: i + 39, p40: i + 40, - p41: i + 41, p42: i + 42, p43: i + 43, p44: i + 44, p45: i + 45, p46: i + 46, p47: i + 47, p48: i + 48, p49: i + 49, p50: i + 50 + p41: i + 41, p42: i + 42, p43: i + 43, p44: i + 44, p45: i + 45, p46: i + 46, p47: i + 47, p48: i + 48, p49: i + 49, p50: i + 50, + notunboxed: undefined }; // Add a function call to capture a resumepoint at the end of the call or // inside the inlined block, such as the bailout does not rewind to the @@ -147,6 +148,7 @@ function Point(x, y) { this.x = x; this.y = y; + this.notUnboxed = undefined; } function createThisWithTemplate(i) diff --git a/js/src/jit/MIR.cpp b/js/src/jit/MIR.cpp index b19dc5fe71f..071733bd72f 100644 --- a/js/src/jit/MIR.cpp +++ b/js/src/jit/MIR.cpp @@ -2977,7 +2977,7 @@ MBitNot::foldsTo(TempAllocator& alloc) if (input->isBitNot() && input->toBitNot()->specialization_ == MIRType_Int32) { MOZ_ASSERT(input->toBitNot()->getOperand(0)->type() == MIRType_Int32); - return input->toBitNot()->getOperand(0); // ~~x => x + return MTruncateToInt32::New(alloc, input->toBitNot()->input()); // ~~x => x | 0 } return this; diff --git a/js/src/js.msg b/js/src/js.msg index de64a720c7a..bf88dffdd93 100644 --- a/js/src/js.msg +++ b/js/src/js.msg @@ -75,6 +75,7 @@ MSG_DEF(JSMSG_UTF8_CHAR_TOO_LARGE, 1, JSEXN_TYPEERR, "UTF-8 character {0} to MSG_DEF(JSMSG_MALFORMED_UTF8_CHAR, 1, JSEXN_TYPEERR, "malformed UTF-8 character sequence at offset {0}") MSG_DEF(JSMSG_WRONG_CONSTRUCTOR, 1, JSEXN_TYPEERR, "wrong constructor called for {0}") MSG_DEF(JSMSG_BUILTIN_CTOR_NO_NEW, 1, JSEXN_NONE, "calling a builtin {0} constructor without new is deprecated and will be forbidden in ES6") +MSG_DEF(JSMSG_BUILTIN_CTOR_NO_NEW_FATAL, 1, JSEXN_TYPEERR, "calling a builtin {0} constructor without new is forbidden") MSG_DEF(JSMSG_PROTO_SETTING_SLOW, 0, JSEXN_NONE, "mutating the [[Prototype]] of an object will cause your code to run very slowly; instead create the object with the correct initial [[Prototype]] value using Object.create") MSG_DEF(JSMSG_BAD_GENERATOR_YIELD, 1, JSEXN_TYPEERR, "yield from closing generator {0}") MSG_DEF(JSMSG_EMPTY_ARRAY_REDUCE, 0, JSEXN_TYPEERR, "reduce of empty array with no initial value") diff --git a/js/src/jsapi-tests/testGCNursery.cpp b/js/src/jsapi-tests/testGCNursery.cpp deleted file mode 100644 index db7276ac810..00000000000 --- a/js/src/jsapi-tests/testGCNursery.cpp +++ /dev/null @@ -1,125 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- -* vim: set ts=8 sts=4 et sw=4 tw=99: -*/ -/* This Source Code Form is subject to the terms of the Mozilla Public - * 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 "gc/Nursery.h" -#include "js/GCAPI.h" -#include "jsapi-tests/tests.h" - -static int ranFinalizer = 0; - -void -_finalize(js::FreeOp* fop, JSObject* obj) -{ - JS::AutoAssertGCCallback suppress(obj); - ++ranFinalizer; -} - -static const js::Class TenuredClass = { - "TenuredClass", - 0, - nullptr, /* addProperty */ - nullptr, /* delProperty */ - nullptr, /* getProperty */ - nullptr, /* setProperty */ - nullptr, /* enumerate */ - nullptr, /* resolve */ - nullptr, /* mayResolve */ - nullptr, /* ??? */ - _finalize, - nullptr, /* call */ - nullptr, /* hasInstance */ - nullptr, /* construct */ - nullptr, /* trace */ - JS_NULL_CLASS_SPEC, - JS_NULL_CLASS_EXT, - JS_NULL_OBJECT_OPS -}; - -static const js::Class NurseryClass = { - "NurseryClass", - JSCLASS_FINALIZE_FROM_NURSERY | JSCLASS_HAS_RESERVED_SLOTS(1), - nullptr, /* addProperty */ - nullptr, /* delProperty */ - nullptr, /* getProperty */ - nullptr, /* setProperty */ - nullptr, /* enumerate */ - nullptr, /* resolve */ - nullptr, /* mayResolve */ - nullptr, /* ??? */ - _finalize, - nullptr, /* call */ - nullptr, /* hasInstance */ - nullptr, /* construct */ - nullptr, /* trace */ - JS_NULL_CLASS_SPEC, - JS_NULL_CLASS_EXT, - JS_NULL_OBJECT_OPS -}; - -BEGIN_TEST(testGCNurseryFinalizer) -{ -#ifdef JS_GC_ZEAL - // Running extra GCs during this test will make us get incorrect - // finalization counts. - AutoLeaveZeal nozeal(cx); -#endif /* JS_GC_ZEAL */ - - JS::RootedObject obj(cx); - - obj = JS_NewObject(cx, Jsvalify(&TenuredClass)); - CHECK(!js::gc::IsInsideNursery(obj)); - - // Null finalization list with empty nursery. - rt->gc.minorGC(JS::gcreason::EVICT_NURSERY); - CHECK(ranFinalizer == 0); - - // Null finalization list with non-empty nursery. - obj = JS_NewPlainObject(cx); - obj = JS_NewPlainObject(cx); - obj = JS_NewPlainObject(cx); - CHECK(js::gc::IsInsideNursery(obj)); - obj = nullptr; - rt->gc.minorGC(JS::gcreason::EVICT_NURSERY); - CHECK(ranFinalizer == 0); - - // Single finalizable nursery thing. - obj = JS_NewObject(cx, Jsvalify(&NurseryClass)); - CHECK(js::gc::IsInsideNursery(obj)); - obj = nullptr; - rt->gc.minorGC(JS::gcreason::EVICT_NURSERY); - CHECK(ranFinalizer == 1); - ranFinalizer = 0; - - // Multiple finalizable nursery things. - obj = JS_NewObject(cx, Jsvalify(&NurseryClass)); - obj = JS_NewObject(cx, Jsvalify(&NurseryClass)); - obj = JS_NewObject(cx, Jsvalify(&NurseryClass)); - CHECK(js::gc::IsInsideNursery(obj)); - obj = nullptr; - rt->gc.minorGC(JS::gcreason::EVICT_NURSERY); - CHECK(ranFinalizer == 3); - ranFinalizer = 0; - - // Interleaved finalizable things in nursery. - obj = JS_NewPlainObject(cx); - obj = JS_NewObject(cx, Jsvalify(&NurseryClass)); - obj = JS_NewPlainObject(cx); - obj = JS_NewObject(cx, Jsvalify(&NurseryClass)); - obj = JS_NewPlainObject(cx); - obj = JS_NewObject(cx, Jsvalify(&NurseryClass)); - obj = JS_NewPlainObject(cx); - obj = JS_NewObject(cx, Jsvalify(&NurseryClass)); - obj = JS_NewPlainObject(cx); - CHECK(js::gc::IsInsideNursery(obj)); - obj = nullptr; - rt->gc.minorGC(JS::gcreason::EVICT_NURSERY); - CHECK(ranFinalizer == 4); - ranFinalizer = 0; - - return true; -} -END_TEST(testGCNurseryFinalizer) diff --git a/js/src/jscntxt.cpp b/js/src/jscntxt.cpp index 78b7937d63f..42f0a2c60b0 100644 --- a/js/src/jscntxt.cpp +++ b/js/src/jscntxt.cpp @@ -86,7 +86,6 @@ js::TraceCycleDetectionSet(JSTracer* trc, js::ObjectSet& set) { for (js::ObjectSet::Enum e(set); !e.empty(); e.popFront()) { JSObject* key = e.front(); - JS::AutoOriginalTraceLocation reloc(trc, &e.front()); TraceRoot(trc, &key, "cycle detector table entry"); if (key != e.front()) e.rekeyFront(key); diff --git a/js/src/jsgc.cpp b/js/src/jsgc.cpp index 5a6c0102c7e..71616b17c6a 100644 --- a/js/src/jsgc.cpp +++ b/js/src/jsgc.cpp @@ -1105,7 +1105,6 @@ GCRuntime::GCRuntime(JSRuntime* rt) : maxMallocBytes(0), numArenasFreeCommitted(0), verifyPreData(nullptr), - verifyPostData(nullptr), chunkAllocationSinceLastGC(false), nextFullGCTime(0), lastGCTime(PRMJ_Now()), @@ -1201,8 +1200,8 @@ const char* gc::ZealModeHelpText = " 8: Incremental GC in two slices: 1) mark roots 2) finish collection\n" " 9: Incremental GC in two slices: 1) mark all 2) new marking and finish\n" " 10: Incremental GC in multiple slices\n" - " 11: Verify post write barriers between instructions\n" - " 12: Verify post write barriers between paints\n" + " 11: unused\n" + " 12: unused\n" " 13: Check internal hashtables on minor GC\n" " 14: Perform a shrinking collection every N allocations\n"; @@ -1211,8 +1210,6 @@ GCRuntime::setZeal(uint8_t zeal, uint32_t frequency) { if (verifyPreData) VerifyBarriers(rt, PreBarrierVerifier); - if (verifyPostData) - VerifyBarriers(rt, PostBarrierVerifier); if (zealMode == ZealGenerationalGCValue) { evictNursery(JS::gcreason::DEBUG_GC); @@ -6280,11 +6277,6 @@ GCRuntime::notifyDidPaint() return; } - if (zealMode == ZealFrameVerifierPostValue) { - verifyPostBarriers(); - return; - } - if (zealMode == ZealFrameGCValue) { JS::PrepareForFullGC(rt); gc(GC_NORMAL, JS::gcreason::REFRESH_FRAME); @@ -7200,25 +7192,13 @@ JS::WasIncrementalGC(JSRuntime* rt) JS::AutoDisableGenerationalGC::AutoDisableGenerationalGC(JSRuntime* rt) : gc(&rt->gc) -#ifdef JS_GC_ZEAL - , restartVerifier(false) -#endif { -#ifdef JS_GC_ZEAL - restartVerifier = gc->endVerifyPostBarriers(); -#endif gc->disableGenerationalGC(); } JS::AutoDisableGenerationalGC::~AutoDisableGenerationalGC() { gc->enableGenerationalGC(); -#ifdef JS_GC_ZEAL - if (restartVerifier) { - MOZ_ASSERT(gc->isGenerationalGCEnabled()); - gc->startVerifyPostBarriers(); - } -#endif } JS_PUBLIC_API(bool) diff --git a/js/src/jsgc.h b/js/src/jsgc.h index 49a570b5dda..6b86f3cbf1f 100644 --- a/js/src/jsgc.h +++ b/js/src/jsgc.h @@ -1189,6 +1189,7 @@ MergeCompartments(JSCompartment* source, JSCompartment* target); class RelocationOverlay { friend class MinorCollectionTracer; + friend class js::TenuringTracer; /* The low bit is set so this should never equal a normal pointer. */ static const uintptr_t Relocated = uintptr_t(0xbad0bad1); @@ -1336,8 +1337,6 @@ const int ZealGenerationalGCValue = 7; const int ZealIncrementalRootsThenFinish = 8; const int ZealIncrementalMarkAllThenFinish = 9; const int ZealIncrementalMultipleSlices = 10; -const int ZealVerifierPostValue = 11; -const int ZealFrameVerifierPostValue = 12; const int ZealCheckHashTablesOnMinorGC = 13; const int ZealCompactValue = 14; const int ZealLimit = 14; diff --git a/js/src/tests/js1_8_5/extensions/dataview.js b/js/src/tests/js1_8_5/extensions/dataview.js index d0203dfd507..98f7b1b5955 100644 --- a/js/src/tests/js1_8_5/extensions/dataview.js +++ b/js/src/tests/js1_8_5/extensions/dataview.js @@ -1647,12 +1647,10 @@ function test() { assertEq(Object.getPrototypeOf(av), DataView.prototype); // Bug 760904: call another compartment's constructor with an ArrayBuffer - // from this compartment, both as a constructor and as a regular call. (The - // latter is what was broken in that bug.) + // from this compartment. var alien_constructor = alien.DataView; var local_buffer = (new Int8Array(3)).buffer; - var foreign_exchange_student_1 = alien_constructor(local_buffer); - var foreign_exchange_student_2 = new alien_constructor(local_buffer); + var foreign_exchange_student = new alien_constructor(local_buffer); // gc bug 787775 var ab = new ArrayBuffer(4); diff --git a/js/src/vm/NativeObject-inl.h b/js/src/vm/NativeObject-inl.h index b13bdf1facb..cfd88a775f9 100644 --- a/js/src/vm/NativeObject-inl.h +++ b/js/src/vm/NativeObject-inl.h @@ -612,6 +612,15 @@ WarnIfNotConstructing(JSContext* cx, const CallArgs& args, const char* builtinNa JSMSG_BUILTIN_CTOR_NO_NEW, builtinName); } +inline bool +ThrowIfNotConstructing(JSContext *cx, const CallArgs &args, const char *builtinName) +{ + if (args.isConstructing()) + return true; + return JS_ReportErrorFlagsAndNumber(cx, JSREPORT_ERROR, GetErrorMessage, nullptr, + JSMSG_BUILTIN_CTOR_NO_NEW_FATAL, builtinName); +} + } // namespace js #endif /* vm_NativeObject_inl_h */ diff --git a/js/src/vm/ObjectGroup.cpp b/js/src/vm/ObjectGroup.cpp index 313013b5eb7..74ffeced506 100644 --- a/js/src/vm/ObjectGroup.cpp +++ b/js/src/vm/ObjectGroup.cpp @@ -416,7 +416,6 @@ class ObjectGroupCompartment::NewTableRef : public gc::BufferableRef void mark(JSTracer* trc) { JSObject* prior = proto; - JS::AutoOriginalTraceLocation reloc(trc, &proto); TraceManuallyBarrieredEdge(trc, &proto, "newObjectGroups set prototype"); if (prior == proto) return; @@ -466,6 +465,8 @@ ObjectGroup::defaultNewGroup(ExclusiveContext* cx, const Class* clasp, // unboxed plain object. MOZ_ASSERT(!clasp == (associated && associated->is())); + AutoEnterAnalysis enter(cx); + ObjectGroupCompartment::NewTable*& table = cx->compartment()->objectGroups.defaultNewTable; if (!table) { @@ -499,6 +500,9 @@ ObjectGroup::defaultNewGroup(ExclusiveContext* cx, const Class* clasp, clasp = &PlainObject::class_; } + if (proto.isObject() && !proto.toObject()->setDelegate(cx)) + return nullptr; + ObjectGroupCompartment::NewTable::AddPtr p = table->lookupForAdd(ObjectGroupCompartment::NewEntry::Lookup(clasp, proto, associated)); if (p) { @@ -510,11 +514,6 @@ ObjectGroup::defaultNewGroup(ExclusiveContext* cx, const Class* clasp, return group; } - AutoEnterAnalysis enter(cx); - - if (proto.isObject() && !proto.toObject()->setDelegate(cx)) - return nullptr; - ObjectGroupFlags initialFlags = 0; if (!proto.isObject() || proto.toObject()->isNewGroupUnknown()) initialFlags = OBJECT_FLAG_DYNAMIC_MASK; diff --git a/js/src/vm/Runtime.cpp b/js/src/vm/Runtime.cpp index eff2b430be9..6c20dec640a 100644 --- a/js/src/vm/Runtime.cpp +++ b/js/src/vm/Runtime.cpp @@ -277,7 +277,7 @@ JSRuntime::init(uint32_t maxbytes, uint32_t maxNurseryBytes) const char* size = getenv("JSGC_MARK_STACK_LIMIT"); if (size) - SetMarkStackLimit(this, atoi(size)); + gc.setMarkStackLimit(atoi(size)); ScopedJSDeletePtr atomsZone(new_(this)); if (!atomsZone || !atomsZone->init(true)) diff --git a/js/src/vm/TypedArrayObject.cpp b/js/src/vm/TypedArrayObject.cpp index e1817588d73..dc13f0818e7 100644 --- a/js/src/vm/TypedArrayObject.cpp +++ b/js/src/vm/TypedArrayObject.cpp @@ -1094,6 +1094,9 @@ DataViewObject::class_constructor(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); + if (!ThrowIfNotConstructing(cx, args, "DataView")) + return false; + RootedObject bufobj(cx); if (!GetFirstArgumentAsObject(cx, args, "DataView constructor", &bufobj)) return false; diff --git a/js/src/vm/UnboxedObject.cpp b/js/src/vm/UnboxedObject.cpp index 89d4afa7b85..4499b98722c 100644 --- a/js/src/vm/UnboxedObject.cpp +++ b/js/src/vm/UnboxedObject.cpp @@ -71,6 +71,8 @@ static const uintptr_t CLEAR_CONSTRUCTOR_CODE_TOKEN = 0x1; /* static */ bool UnboxedLayout::makeConstructorCode(JSContext* cx, HandleObjectGroup group) { + gc::AutoSuppressGC suppress(cx); + using namespace jit; if (!cx->compartment()->ensureJitCompartmentExists(cx)) @@ -107,8 +109,7 @@ UnboxedLayout::makeConstructorCode(JSContext* cx, HandleObjectGroup group) Register object = regs.takeAny(), scratch1 = regs.takeAny(), scratch2 = regs.takeAny(); LiveGeneralRegisterSet savedNonVolatileRegisters = SavedNonVolatileRegisters(regs); - for (GeneralRegisterForwardIterator iter(savedNonVolatileRegisters); iter.more(); ++iter) - masm.Push(*iter); + masm.PushRegsInMask(savedNonVolatileRegisters); // The scratch double register might be used by MacroAssembler methods. if (ScratchDoubleReg.volatile_()) @@ -148,12 +149,20 @@ UnboxedLayout::makeConstructorCode(JSContext* cx, HandleObjectGroup group) masm.jump(&allocated); masm.bind(&postBarrier); + LiveGeneralRegisterSet liveVolatileRegisters; + liveVolatileRegisters.add(propertiesReg); + if (object.volatile_()) + liveVolatileRegisters.add(object); + masm.PushRegsInMask(liveVolatileRegisters); + masm.mov(ImmPtr(cx->runtime()), scratch1); masm.setupUnalignedABICall(2, scratch2); masm.passABIArg(scratch1); masm.passABIArg(object); masm.callWithABI(JS_FUNC_TO_DATA_PTR(void*, PostWriteBarrier)); + masm.PopRegsInMask(liveVolatileRegisters); + masm.bind(&allocated); ValueOperand valueOperand; @@ -213,8 +222,7 @@ UnboxedLayout::makeConstructorCode(JSContext* cx, HandleObjectGroup group) // Restore non-volatile registers which were saved on entry. if (ScratchDoubleReg.volatile_()) masm.pop(ScratchDoubleReg); - for (GeneralRegisterBackwardIterator iter(savedNonVolatileRegisters); iter.more(); ++iter) - masm.Pop(*iter); + masm.PopRegsInMask(savedNonVolatileRegisters); masm.abiret(); @@ -327,7 +335,7 @@ SetUnboxedValue(ExclusiveContext* cx, JSObject* unboxedObject, jsid id, } static inline Value -GetUnboxedValue(uint8_t* p, JSValueType type) +GetUnboxedValue(uint8_t* p, JSValueType type, bool maybeUninitialized) { switch (type) { case JSVAL_TYPE_BOOLEAN: @@ -336,8 +344,16 @@ GetUnboxedValue(uint8_t* p, JSValueType type) case JSVAL_TYPE_INT32: return Int32Value(*reinterpret_cast(p)); - case JSVAL_TYPE_DOUBLE: - return DoubleValue(*reinterpret_cast(p)); + case JSVAL_TYPE_DOUBLE: { + // During unboxed plain object creation, non-GC thing properties are + // left uninitialized. This is normally fine, since the properties will + // be filled in shortly, but if they are read before that happens we + // need to make sure that doubles are canonical. + double d = *reinterpret_cast(p); + if (maybeUninitialized) + return DoubleValue(JS::CanonicalizeNaN(d)); + return DoubleValue(d); + } case JSVAL_TYPE_STRING: return StringValue(*reinterpret_cast(p)); @@ -363,10 +379,11 @@ UnboxedPlainObject::setValue(ExclusiveContext* cx, const UnboxedLayout::Property } Value -UnboxedPlainObject::getValue(const UnboxedLayout::Property& property) +UnboxedPlainObject::getValue(const UnboxedLayout::Property& property, + bool maybeUninitialized /* = false */) { uint8_t* p = &data_[property.offset]; - return GetUnboxedValue(p, property.type); + return GetUnboxedValue(p, property.type, maybeUninitialized); } void @@ -411,6 +428,12 @@ UnboxedPlainObject::ensureExpando(JSContext* cx, Handle obj if (!expando) return nullptr; + // If the expando is tenured then the original object must also be tenured. + // Otherwise barriers triggered on the original object for writes to the + // expando (as can happen in the JIT) won't see the tenured->nursery edge. + // See WholeCellEdges::mark. + MOZ_ASSERT_IF(!IsInsideNursery(expando), !IsInsideNursery(obj)); + // As with setValue(), we need to manually trigger post barriers on the // whole object. If we treat the field as a HeapPtrObject and later convert // the object to its native representation, we will end up with a corrupted @@ -578,10 +601,15 @@ UnboxedPlainObject::convertToNative(JSContext* cx, JSObject* obj) AutoValueVector values(cx); for (size_t i = 0; i < layout.properties().length(); i++) { - if (!values.append(obj->as().getValue(layout.properties()[i]))) + // We might be reading properties off the object which have not been + // initialized yet. Make sure any double values we read here are + // canonicalized. + if (!values.append(obj->as().getValue(layout.properties()[i], true))) return false; } + JSObject::writeBarrierPre(expando); + obj->setGroup(layout.nativeGroup()); obj->as().setLastPropertyMakeNative(cx, layout.nativeShape()); @@ -935,7 +963,9 @@ const Class UnboxedExpandoObject::class_ = { const Class UnboxedPlainObject::class_ = { js_Object_str, - Class::NON_NATIVE | JSCLASS_IMPLEMENTS_BARRIERS, + Class::NON_NATIVE | + JSCLASS_IMPLEMENTS_BARRIERS | + JSCLASS_HAS_CACHED_PROTO(JSProto_Object), nullptr, /* addProperty */ nullptr, /* delProperty */ nullptr, /* getProperty */ @@ -1099,7 +1129,7 @@ UnboxedArrayObject::getElement(size_t index) { MOZ_ASSERT(index < initializedLength()); uint8_t* p = elements() + index * elementSize(); - return GetUnboxedValue(p, elementType()); + return GetUnboxedValue(p, elementType(), /* maybeUninitialized = */ false); } /* static */ void diff --git a/js/src/vm/UnboxedObject.h b/js/src/vm/UnboxedObject.h index 0643aa47865..b6e6e0d07c0 100644 --- a/js/src/vm/UnboxedObject.h +++ b/js/src/vm/UnboxedObject.h @@ -265,7 +265,7 @@ class UnboxedPlainObject : public JSObject static UnboxedExpandoObject* ensureExpando(JSContext* cx, Handle obj); bool setValue(ExclusiveContext* cx, const UnboxedLayout::Property& property, const Value& v); - Value getValue(const UnboxedLayout::Property& property); + Value getValue(const UnboxedLayout::Property& property, bool maybeUninitialized = false); static bool convertToNative(JSContext* cx, JSObject* obj); static UnboxedPlainObject* create(ExclusiveContext* cx, HandleObjectGroup group, diff --git a/js/src/vm/Xdr.h b/js/src/vm/Xdr.h index 8beaf79828a..b2aea741ee4 100644 --- a/js/src/vm/Xdr.h +++ b/js/src/vm/Xdr.h @@ -29,11 +29,11 @@ namespace js { * * https://developer.mozilla.org/en-US/docs/SpiderMonkey/Internals/Bytecode */ -static const uint32_t XDR_BYTECODE_VERSION_SUBTRAHEND = 282; +static const uint32_t XDR_BYTECODE_VERSION_SUBTRAHEND = 283; static const uint32_t XDR_BYTECODE_VERSION = uint32_t(0xb973c0de - XDR_BYTECODE_VERSION_SUBTRAHEND); -static_assert(JSErr_Limit == 393, +static_assert(JSErr_Limit == 394, "GREETINGS, POTENTIAL SUBTRAHEND INCREMENTER! If you added or " "removed MSG_DEFs from js.msg, you should increment " "XDR_BYTECODE_VERSION_SUBTRAHEND and update this assertion's " diff --git a/js/xpconnect/src/ExportHelpers.cpp b/js/xpconnect/src/ExportHelpers.cpp index dd7a1106a5c..39be4915338 100644 --- a/js/xpconnect/src/ExportHelpers.cpp +++ b/js/xpconnect/src/ExportHelpers.cpp @@ -324,18 +324,14 @@ FunctionForwarder(JSContext* cx, unsigned argc, Value* vp) RootedValue v(cx, js::GetFunctionNativeReserved(&args.callee(), 0)); RootedObject unwrappedFun(cx, js::UncheckedUnwrap(&v.toObject())); - RootedObject thisObj(cx, JS_THIS_OBJECT(cx, vp)); - if (!thisObj) { - return false; - } - + RootedObject thisObj(cx, args.isConstructing() ? nullptr : JS_THIS_OBJECT(cx, vp)); { // We manually implement the contents of CrossCompartmentWrapper::call // here, because certain function wrappers (notably content->nsEP) are // not callable. JSAutoCompartment ac(cx, unwrappedFun); - RootedValue thisVal(cx, ObjectValue(*thisObj)); + RootedValue thisVal(cx, ObjectOrNullValue(thisObj)); if (!CheckSameOriginArg(cx, options, thisVal) || !JS_WrapObject(cx, &thisObj)) return false; @@ -345,8 +341,13 @@ FunctionForwarder(JSContext* cx, unsigned argc, Value* vp) } RootedValue fval(cx, ObjectValue(*unwrappedFun)); - if (!JS_CallFunctionValue(cx, thisObj, fval, args, args.rval())) - return false; + if (args.isConstructing()) { + if (!JS::Construct(cx, fval, args, args.rval())) + return false; + } else { + if (!JS_CallFunctionValue(cx, thisObj, fval, args, args.rval())) + return false; + } } // Rewrap the return value into our compartment. @@ -361,8 +362,11 @@ NewFunctionForwarder(JSContext* cx, HandleId idArg, HandleObject callable, if (id == JSID_VOIDHANDLE) id = GetRTIdByIndex(cx, XPCJSRuntime::IDX_EMPTYSTRING); + // We have no way of knowing whether the underlying function wants to be a + // constructor or not, so we just mark all forwarders as constructors, and + // let the underlying function throw for construct calls if it wants. JSFunction* fun = js::NewFunctionByIdWithReserved(cx, FunctionForwarder, - 0, 0, id); + 0, JSFUN_CONSTRUCTOR, id); if (!fun) return false; diff --git a/js/xpconnect/tests/unit/test_bug1131707.js b/js/xpconnect/tests/unit/test_bug1131707.js new file mode 100644 index 00000000000..4ae4404a060 --- /dev/null +++ b/js/xpconnect/tests/unit/test_bug1131707.js @@ -0,0 +1,22 @@ +const Cu = Components.utils; + +function testStrict(sb) { + "use strict"; + do_check_eq(sb.eval("typeof wrappedCtor()"), "string"); + do_check_eq(sb.eval("typeof new wrappedCtor()"), "object"); +} + +function run_test() { + var sb = new Cu.Sandbox(null); + var dateCtor = sb.Date; + sb.wrappedCtor = Cu.exportFunction(function wrapper(val) { + "use strict"; + var constructing = this.constructor == wrapper; + return constructing ? new dateCtor(val) : dateCtor(val); + }, sb); + do_check_eq(typeof Date(), "string"); + do_check_eq(typeof new Date(), "object"); + do_check_eq(sb.eval("typeof wrappedCtor()"), "string"); + do_check_eq(sb.eval("typeof new wrappedCtor()"), "object"); + testStrict(sb); +} diff --git a/js/xpconnect/tests/unit/xpcshell.ini b/js/xpconnect/tests/unit/xpcshell.ini index 420ec16a29c..33d0eb2c2cf 100644 --- a/js/xpconnect/tests/unit/xpcshell.ini +++ b/js/xpconnect/tests/unit/xpcshell.ini @@ -54,6 +54,7 @@ support-files = [test_bug1082450.js] [test_bug1081990.js] [test_bug1110546.js] +[test_bug1131707.js] [test_bug1150771.js] [test_bug1151385.js] [test_bug_442086.js] diff --git a/media/webrtc/moz.build b/media/webrtc/moz.build index 9933bfc33d4..dfb4a1fbbbf 100644 --- a/media/webrtc/moz.build +++ b/media/webrtc/moz.build @@ -36,16 +36,6 @@ webrtc_non_unified_sources = [ 'trunk/webrtc/modules/video_capture/windows/sink_filter_ds.cc', # Because of the MEDIASUBTYPE_HDYC variable and initguid.h ] -IPDL_SOURCES += [ - 'signaling/src/peerconnection/PWebrtcGlobal.ipdl', -] - -EXPORTS.mozilla.media.webrtc += [ - 'signaling/src/peerconnection/WebrtcGlobal.h', - 'signaling/src/peerconnection/WebrtcGlobalChild.h', - 'signaling/src/peerconnection/WebrtcGlobalParent.h' -] - GYP_DIRS += ['trunk'] GYP_DIRS['trunk'].input = 'trunk/peerconnection.gyp' diff --git a/media/webrtc/signaling/src/jsep/JsepSessionImpl.cpp b/media/webrtc/signaling/src/jsep/JsepSessionImpl.cpp index 040266dc5e1..4bf138f148d 100644 --- a/media/webrtc/signaling/src/jsep/JsepSessionImpl.cpp +++ b/media/webrtc/signaling/src/jsep/JsepSessionImpl.cpp @@ -1146,13 +1146,16 @@ JsepSessionImpl::CreateAnswerMSection(const JsepAnswerOptions& options, SdpMediaSection* msection, Sdp* sdp) { + nsresult rv = CopyStickyParams(remoteMsection, msection); + NS_ENSURE_SUCCESS(rv, rv); + if (MsectionIsDisabled(remoteMsection)) { DisableMsection(sdp, msection); return NS_OK; } SdpSetupAttribute::Role role; - nsresult rv = DetermineAnswererSetupRole(remoteMsection, &role); + rv = DetermineAnswererSetupRole(remoteMsection, &role); NS_ENSURE_SUCCESS(rv, rv); rv = AddTransportAttributes(msection, role); @@ -1169,9 +1172,6 @@ JsepSessionImpl::CreateAnswerMSection(const JsepAnswerOptions& options, msection->SetReceiving(true); } - rv = CopyStickyParams(remoteMsection, msection); - NS_ENSURE_SUCCESS(rv, rv); - // Now add the codecs. PtrVector matchingCodecs( GetCommonCodecs(remoteMsection)); diff --git a/media/webrtc/signaling/src/mediapipeline/MediaPipelineFilter.cpp b/media/webrtc/signaling/src/mediapipeline/MediaPipelineFilter.cpp index 8a103ba5905..e8602327caa 100644 --- a/media/webrtc/signaling/src/mediapipeline/MediaPipelineFilter.cpp +++ b/media/webrtc/signaling/src/mediapipeline/MediaPipelineFilter.cpp @@ -79,7 +79,7 @@ void MediaPipelineFilter::Update(const MediaPipelineFilter& filter_update) { bool MediaPipelineFilter::FilterSenderReport(const unsigned char* data, size_t len) const { - if (len < FIRST_SSRC_OFFSET) { + if (len < FIRST_SSRC_OFFSET + 4) { return false; } diff --git a/media/webrtc/signaling/src/peerconnection/PeerConnectionCtx.h b/media/webrtc/signaling/src/peerconnection/PeerConnectionCtx.h index 8e7f3f85d26..11f55699c59 100644 --- a/media/webrtc/signaling/src/peerconnection/PeerConnectionCtx.h +++ b/media/webrtc/signaling/src/peerconnection/PeerConnectionCtx.h @@ -8,7 +8,7 @@ #include #if !defined(MOZILLA_EXTERNAL_LINKAGE) -#include "mozilla/media/webrtc/WebrtcGlobalChild.h" +#include "WebrtcGlobalChild.h" #endif #include "mozilla/Attributes.h" diff --git a/media/webrtc/signaling/src/peerconnection/WebrtcGlobalInformation.cpp b/media/webrtc/signaling/src/peerconnection/WebrtcGlobalInformation.cpp index 406ced1800c..50cfe0c7026 100644 --- a/media/webrtc/signaling/src/peerconnection/WebrtcGlobalInformation.cpp +++ b/media/webrtc/signaling/src/peerconnection/WebrtcGlobalInformation.cpp @@ -3,6 +3,7 @@ * You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "WebrtcGlobalInformation.h" +#include "mozilla/media/webrtc/WebrtcGlobal.h" #include "WebrtcGlobalChild.h" #include "WebrtcGlobalParent.h" @@ -16,7 +17,6 @@ #include "CSFLog.h" #include "WebRtcLog.h" #include "mozilla/dom/WebrtcGlobalInformationBinding.h" -#include "WebrtcGlobal.h" #include "mozilla/dom/ContentChild.h" #include "nsAutoPtr.h" @@ -404,7 +404,7 @@ RunStatsQuery( WebrtcGlobalChild* aThisChild, const int aRequestId) { - auto* queries = new RTCStatsQueries; + nsAutoPtr queries(new RTCStatsQueries); nsresult rv = BuildStatsQueryList(aPeerConnections, aPcIdFilter, queries); if (NS_FAILED(rv)) { @@ -424,7 +424,7 @@ RunStatsQuery( WrapRunnableNM(&GetAllStats_s, aThisChild, aRequestId, - nsAutoPtr(queries)), + queries), NS_DISPATCH_NORMAL); return rv; } diff --git a/mobile/android/app/mobile.js b/mobile/android/app/mobile.js index b950c88503f..5829c47fe10 100644 --- a/mobile/android/app/mobile.js +++ b/mobile/android/app/mobile.js @@ -570,6 +570,7 @@ pref("media.fragmented-mp4.android-media-codec.enabled", true); pref("media.fragmented-mp4.android-media-codec.preferred", true); // optimize images memory usage +pref("image.downscale-during-decode.enabled", true); pref("image.decode-only-on-draw.enabled", true); #ifdef NIGHTLY_BUILD diff --git a/modules/libpref/init/all.js b/modules/libpref/init/all.js index 3eb851ca114..ea8a3ca5ca7 100644 --- a/modules/libpref/init/all.js +++ b/modules/libpref/init/all.js @@ -3871,7 +3871,7 @@ pref("image.decode-only-on-draw.enabled", true); pref("image.decode-immediately.enabled", false); // Whether we attempt to downscale images during decoding. -pref("image.downscale-during-decode.enabled", false); +pref("image.downscale-during-decode.enabled", true); // The default Accept header sent for images loaded over HTTP(S) pref("image.http.accept", "image/png,image/*;q=0.8,*/*;q=0.5"); diff --git a/testing/mochitest/mach_commands.py b/testing/mochitest/mach_commands.py index e75c09acbf0..741dd5436ef 100644 --- a/testing/mochitest/mach_commands.py +++ b/testing/mochitest/mach_commands.py @@ -8,6 +8,7 @@ from argparse import Namespace import logging import mozpack.path as mozpath import os +import shutil import sys import warnings import which @@ -90,17 +91,41 @@ class MochitestRunner(MozbuildObject): def get_webapp_runtime_path(self): import mozinfo - appname = 'webapprt-stub' + mozinfo.info.get('bin_suffix', '') + app_name = 'webapprt-stub' + mozinfo.info.get('bin_suffix', '') + app_path = os.path.join(self.distdir, 'bin', app_name) if sys.platform.startswith('darwin'): - appname = os.path.join( + # On Mac, we copy the stub from the dist dir to the test app bundle, + # since we have to run it from a bundle for its windows to appear. + # Ideally, the build system would do this for us, and we should find + # a way for it to do that. + mac_dir_name = os.path.join( + self.mochitest_dir, + 'webapprtChrome', + 'webapprt', + 'test', + 'chrome', + 'TestApp.app', + 'Contents', + 'MacOS') + mac_app_name = 'webapprt' + mozinfo.info.get('bin_suffix', '') + mac_app_path = os.path.join(mac_dir_name, mac_app_name) + shutil.copy(app_path, mac_app_path) + return mac_app_path + return app_path + + # On Mac, the app invoked by runtests.py is in a different app bundle + # (as determined by get_webapp_runtime_path above), but the XRE path should + # still point to the browser's app bundle, so we set it here explicitly. + def get_webapp_runtime_xre_path(self): + if sys.platform.startswith('darwin'): + xre_path = os.path.join( self.distdir, self.substs['MOZ_MACBUNDLE_NAME'], 'Contents', - 'Resources', - appname) + 'Resources') else: - appname = os.path.join(self.distdir, 'bin', appname) - return appname + xre_path = os.path.join(self.distdir, 'bin') + return xre_path def __init__(self, *args, **kwargs): MozbuildObject.__init__(self, *args, **kwargs) @@ -244,11 +269,13 @@ class MochitestRunner(MozbuildObject): options.webapprtContent = True if not options.app or options.app == self.get_binary_path(): options.app = self.get_webapp_runtime_path() + options.xrePath = self.get_webapp_runtime_xre_path() elif suite == 'webapprt-chrome': options.webapprtChrome = True options.browserArgs.append("-test-mode") if not options.app or options.app == self.get_binary_path(): options.app = self.get_webapp_runtime_path() + options.xrePath = self.get_webapp_runtime_xre_path() else: raise Exception('None or unrecognized mochitest suite type.') diff --git a/testing/mozharness/mozharness.json b/testing/mozharness/mozharness.json index 0565e208cf1..4bccaac5cd4 100644 --- a/testing/mozharness/mozharness.json +++ b/testing/mozharness/mozharness.json @@ -1,4 +1,4 @@ { "repo": "https://hg.mozilla.org/build/mozharness", - "revision": "565ea3ec1d4d" + "revision": "4d260376921f" } diff --git a/testing/web-platform/meta/FileAPI/blob/Blob-constructor.html.ini b/testing/web-platform/meta/FileAPI/blob/Blob-constructor.html.ini index d20e156c4ef..f0d7039d23e 100644 --- a/testing/web-platform/meta/FileAPI/blob/Blob-constructor.html.ini +++ b/testing/web-platform/meta/FileAPI/blob/Blob-constructor.html.ini @@ -1,8 +1,5 @@ [Blob-constructor.html] type: testharness - [Blob interface object] - expected: FAIL - [no-argument Blob constructor without 'new'] expected: FAIL diff --git a/testing/web-platform/meta/MANIFEST.json b/testing/web-platform/meta/MANIFEST.json index 28d3c7011af..cf181d6854a 100644 --- a/testing/web-platform/meta/MANIFEST.json +++ b/testing/web-platform/meta/MANIFEST.json @@ -16147,70 +16147,6 @@ "path": "service-workers/cache-storage/common.https.html", "url": "/service-workers/cache-storage/common.https.html" }, - { - "path": "service-workers/cache-storage/serviceworker/cache-add.https.html", - "url": "/service-workers/cache-storage/serviceworker/cache-add.https.html" - }, - { - "path": "service-workers/cache-storage/serviceworker/cache-delete.https.html", - "url": "/service-workers/cache-storage/serviceworker/cache-delete.https.html" - }, - { - "path": "service-workers/cache-storage/serviceworker/cache-storage-keys.https.html", - "url": "/service-workers/cache-storage/serviceworker/cache-storage-keys.https.html" - }, - { - "path": "service-workers/cache-storage/serviceworker/cache-storage-match.https.html", - "url": "/service-workers/cache-storage/serviceworker/cache-storage-match.https.html" - }, - { - "path": "service-workers/cache-storage/serviceworker/cache-storage.https.html", - "url": "/service-workers/cache-storage/serviceworker/cache-storage.https.html" - }, - { - "path": "service-workers/cache-storage/window/cache-add.https.html", - "url": "/service-workers/cache-storage/window/cache-add.https.html" - }, - { - "path": "service-workers/cache-storage/window/cache-delete.https.html", - "url": "/service-workers/cache-storage/window/cache-delete.https.html" - }, - { - "path": "service-workers/cache-storage/window/cache-storage-keys.https.html", - "url": "/service-workers/cache-storage/window/cache-storage-keys.https.html" - }, - { - "path": "service-workers/cache-storage/window/cache-storage-match.https.html", - "url": "/service-workers/cache-storage/window/cache-storage-match.https.html" - }, - { - "path": "service-workers/cache-storage/window/cache-storage.https.html", - "url": "/service-workers/cache-storage/window/cache-storage.https.html" - }, - { - "path": "service-workers/cache-storage/window/sandboxed-iframes.https.html", - "url": "/service-workers/cache-storage/window/sandboxed-iframes.https.html" - }, - { - "path": "service-workers/cache-storage/worker/cache-add.https.html", - "url": "/service-workers/cache-storage/worker/cache-add.https.html" - }, - { - "path": "service-workers/cache-storage/worker/cache-delete.https.html", - "url": "/service-workers/cache-storage/worker/cache-delete.https.html" - }, - { - "path": "service-workers/cache-storage/worker/cache-storage-keys.https.html", - "url": "/service-workers/cache-storage/worker/cache-storage-keys.https.html" - }, - { - "path": "service-workers/cache-storage/worker/cache-storage-match.https.html", - "url": "/service-workers/cache-storage/worker/cache-storage-match.https.html" - }, - { - "path": "service-workers/cache-storage/worker/cache-storage.https.html", - "url": "/service-workers/cache-storage/worker/cache-storage.https.html" - }, { "path": "shadow-dom/elements-and-dom-objects/extensions-to-element-interface/attributes/test-001.html", "url": "/shadow-dom/elements-and-dom-objects/extensions-to-element-interface/attributes/test-001.html" @@ -19546,6 +19482,16 @@ "timeout": "long", "url": "/media-source/mediasource-redundant-seek.html" }, + { + "path": "service-workers/cache-storage/serviceworker/cache-add.https.html", + "timeout": "long", + "url": "/service-workers/cache-storage/serviceworker/cache-add.https.html" + }, + { + "path": "service-workers/cache-storage/serviceworker/cache-delete.https.html", + "timeout": "long", + "url": "/service-workers/cache-storage/serviceworker/cache-delete.https.html" + }, { "path": "service-workers/cache-storage/serviceworker/cache-match.https.html", "timeout": "long", @@ -19556,6 +19502,31 @@ "timeout": "long", "url": "/service-workers/cache-storage/serviceworker/cache-put.https.html" }, + { + "path": "service-workers/cache-storage/serviceworker/cache-storage-keys.https.html", + "timeout": "long", + "url": "/service-workers/cache-storage/serviceworker/cache-storage-keys.https.html" + }, + { + "path": "service-workers/cache-storage/serviceworker/cache-storage-match.https.html", + "timeout": "long", + "url": "/service-workers/cache-storage/serviceworker/cache-storage-match.https.html" + }, + { + "path": "service-workers/cache-storage/serviceworker/cache-storage.https.html", + "timeout": "long", + "url": "/service-workers/cache-storage/serviceworker/cache-storage.https.html" + }, + { + "path": "service-workers/cache-storage/window/cache-add.https.html", + "timeout": "long", + "url": "/service-workers/cache-storage/window/cache-add.https.html" + }, + { + "path": "service-workers/cache-storage/window/cache-delete.https.html", + "timeout": "long", + "url": "/service-workers/cache-storage/window/cache-delete.https.html" + }, { "path": "service-workers/cache-storage/window/cache-match.https.html", "timeout": "long", @@ -19566,6 +19537,36 @@ "timeout": "long", "url": "/service-workers/cache-storage/window/cache-put.https.html" }, + { + "path": "service-workers/cache-storage/window/cache-storage-keys.https.html", + "timeout": "long", + "url": "/service-workers/cache-storage/window/cache-storage-keys.https.html" + }, + { + "path": "service-workers/cache-storage/window/cache-storage-match.https.html", + "timeout": "long", + "url": "/service-workers/cache-storage/window/cache-storage-match.https.html" + }, + { + "path": "service-workers/cache-storage/window/cache-storage.https.html", + "timeout": "long", + "url": "/service-workers/cache-storage/window/cache-storage.https.html" + }, + { + "path": "service-workers/cache-storage/window/sandboxed-iframes.https.html", + "timeout": "long", + "url": "/service-workers/cache-storage/window/sandboxed-iframes.https.html" + }, + { + "path": "service-workers/cache-storage/worker/cache-add.https.html", + "timeout": "long", + "url": "/service-workers/cache-storage/worker/cache-add.https.html" + }, + { + "path": "service-workers/cache-storage/worker/cache-delete.https.html", + "timeout": "long", + "url": "/service-workers/cache-storage/worker/cache-delete.https.html" + }, { "path": "service-workers/cache-storage/worker/cache-match.https.html", "timeout": "long", @@ -19576,6 +19577,21 @@ "timeout": "long", "url": "/service-workers/cache-storage/worker/cache-put.https.html" }, + { + "path": "service-workers/cache-storage/worker/cache-storage-keys.https.html", + "timeout": "long", + "url": "/service-workers/cache-storage/worker/cache-storage-keys.https.html" + }, + { + "path": "service-workers/cache-storage/worker/cache-storage-match.https.html", + "timeout": "long", + "url": "/service-workers/cache-storage/worker/cache-storage-match.https.html" + }, + { + "path": "service-workers/cache-storage/worker/cache-storage.https.html", + "timeout": "long", + "url": "/service-workers/cache-storage/worker/cache-storage.https.html" + }, { "path": "websockets/binary/002.html", "timeout": "long", @@ -24825,7 +24841,7 @@ } ] }, - "rev": "40a9c4e9e4f99a738cd1a7602066c5e84d1b90b5", + "rev": "28de405307d9613052ccd1228be7888e109738a6", "url_base": "/", "version": 2 } \ No newline at end of file diff --git a/testing/web-platform/meta/mozilla-sync b/testing/web-platform/meta/mozilla-sync index a3063f835a9..ab051b69cd5 100644 --- a/testing/web-platform/meta/mozilla-sync +++ b/testing/web-platform/meta/mozilla-sync @@ -1 +1 @@ -eb7ac376c982330bc85c58e68fffc55aabef604c \ No newline at end of file +6e958cb0c757bc80226f22d98a93f7fec974aa6c \ No newline at end of file diff --git a/testing/web-platform/meta/service-workers/cache-storage/serviceworker/cache-add.https.html.ini b/testing/web-platform/meta/service-workers/cache-storage/serviceworker/cache-add.https.html.ini deleted file mode 100644 index f57705b87d9..00000000000 --- a/testing/web-platform/meta/service-workers/cache-storage/serviceworker/cache-add.https.html.ini +++ /dev/null @@ -1,3 +0,0 @@ -[cache-add.https.html] - type: testharness - disabled: https://bugzilla.mozilla.org/show_bug.cgi?id=1158347 diff --git a/testing/web-platform/meta/service-workers/cache-storage/serviceworker/cache-delete.https.html.ini b/testing/web-platform/meta/service-workers/cache-storage/serviceworker/cache-delete.https.html.ini deleted file mode 100644 index db57a7c3f7e..00000000000 --- a/testing/web-platform/meta/service-workers/cache-storage/serviceworker/cache-delete.https.html.ini +++ /dev/null @@ -1,3 +0,0 @@ -[cache-delete.https.html] - type: testharness - disabled: https://bugzilla.mozilla.org/show_bug.cgi?id=1158347 diff --git a/testing/web-platform/meta/service-workers/cache-storage/serviceworker/cache-match.https.html.ini b/testing/web-platform/meta/service-workers/cache-storage/serviceworker/cache-match.https.html.ini deleted file mode 100644 index c048c3dac1d..00000000000 --- a/testing/web-platform/meta/service-workers/cache-storage/serviceworker/cache-match.https.html.ini +++ /dev/null @@ -1,3 +0,0 @@ -[cache-match.https.html] - type: testharness - disabled: https://bugzilla.mozilla.org/show_bug.cgi?id=1158347 diff --git a/testing/web-platform/meta/service-workers/cache-storage/serviceworker/cache-put.https.html.ini b/testing/web-platform/meta/service-workers/cache-storage/serviceworker/cache-put.https.html.ini deleted file mode 100644 index 6c298ccdeb1..00000000000 --- a/testing/web-platform/meta/service-workers/cache-storage/serviceworker/cache-put.https.html.ini +++ /dev/null @@ -1,3 +0,0 @@ -[cache-put.https.html] - type: testharness - disabled: https://bugzilla.mozilla.org/show_bug.cgi?id=1158347 diff --git a/testing/web-platform/meta/service-workers/cache-storage/serviceworker/cache-storage-keys.https.html.ini b/testing/web-platform/meta/service-workers/cache-storage/serviceworker/cache-storage-keys.https.html.ini deleted file mode 100644 index 69e8c6ef718..00000000000 --- a/testing/web-platform/meta/service-workers/cache-storage/serviceworker/cache-storage-keys.https.html.ini +++ /dev/null @@ -1,3 +0,0 @@ -[cache-storage-keys.https.html] - type: testharness - disabled: https://bugzilla.mozilla.org/show_bug.cgi?id=1158347 diff --git a/testing/web-platform/meta/service-workers/cache-storage/serviceworker/cache-storage-match.https.html.ini b/testing/web-platform/meta/service-workers/cache-storage/serviceworker/cache-storage-match.https.html.ini deleted file mode 100644 index c5aef954bef..00000000000 --- a/testing/web-platform/meta/service-workers/cache-storage/serviceworker/cache-storage-match.https.html.ini +++ /dev/null @@ -1,3 +0,0 @@ -[cache-storage-match.https.html] - type: testharness - disabled: https://bugzilla.mozilla.org/show_bug.cgi?id=1158347 diff --git a/testing/web-platform/meta/service-workers/cache-storage/serviceworker/cache-storage.https.html.ini b/testing/web-platform/meta/service-workers/cache-storage/serviceworker/cache-storage.https.html.ini deleted file mode 100644 index cb04b8bfe7e..00000000000 --- a/testing/web-platform/meta/service-workers/cache-storage/serviceworker/cache-storage.https.html.ini +++ /dev/null @@ -1,3 +0,0 @@ -[cache-storage.https.html] - type: testharness - disabled: https://bugzilla.mozilla.org/show_bug.cgi?id=1158347 diff --git a/testing/web-platform/meta/service-workers/cache-storage/window/cache-add.https.html.ini b/testing/web-platform/meta/service-workers/cache-storage/window/cache-add.https.html.ini deleted file mode 100644 index 1e6b582ca87..00000000000 --- a/testing/web-platform/meta/service-workers/cache-storage/window/cache-add.https.html.ini +++ /dev/null @@ -1,18 +0,0 @@ -[cache-add.https.html] - type: testharness - [Cache.add called with non-HTTP/HTTPS URL] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1158265 - - [Cache.add called with Request object] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1158262 - - [Cache.add called with Request object with a used body] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1158262 - expected: FAIL - - [Cache.add called twice with the same Request object] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1158262 - - [Cache.addAll called with the same Request object specified twice] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1158263 - diff --git a/testing/web-platform/meta/service-workers/cache-storage/window/cache-delete.https.html.ini b/testing/web-platform/meta/service-workers/cache-storage/window/cache-delete.https.html.ini deleted file mode 100644 index d5a20135c2e..00000000000 --- a/testing/web-platform/meta/service-workers/cache-storage/window/cache-delete.https.html.ini +++ /dev/null @@ -1,9 +0,0 @@ -[cache-delete.https.html] - type: testharness - [Cache.delete called with a Request object] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1158262 - - [Cache.delete with a Request object containing used body] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1158262 - expected: FAIL - diff --git a/testing/web-platform/meta/service-workers/cache-storage/window/cache-match.https.html.ini b/testing/web-platform/meta/service-workers/cache-storage/window/cache-match.https.html.ini deleted file mode 100644 index 2e28cd3d7de..00000000000 --- a/testing/web-platform/meta/service-workers/cache-storage/window/cache-match.https.html.ini +++ /dev/null @@ -1,15 +0,0 @@ -[cache-match.https.html] - type: testharness - [Cache.matchAll with responses containing "Vary" header] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1158292 - - [Cache.match with responses containing "Vary" header] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1158292 - - [Cache.matchAll with "ignoreVary" parameter] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1158292 - - [Cache.match with Request containing non-empty body] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1158262 - expected: FAIL - diff --git a/testing/web-platform/meta/service-workers/cache-storage/window/cache-put.https.html.ini b/testing/web-platform/meta/service-workers/cache-storage/window/cache-put.https.html.ini deleted file mode 100644 index 653135c64a8..00000000000 --- a/testing/web-platform/meta/service-workers/cache-storage/window/cache-put.https.html.ini +++ /dev/null @@ -1,9 +0,0 @@ -[cache-put.https.html] - type: testharness - [Cache.put with Request containing a body] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1158262 - expected: FAIL - - [Cache.put with a used response body] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1158301 - diff --git a/testing/web-platform/meta/service-workers/cache-storage/window/cache-storage-match.https.html.ini b/testing/web-platform/meta/service-workers/cache-storage/window/cache-storage-match.https.html.ini deleted file mode 100644 index b8d08b15d60..00000000000 --- a/testing/web-platform/meta/service-workers/cache-storage/window/cache-storage-match.https.html.ini +++ /dev/null @@ -1,5 +0,0 @@ -[cache-storage-match.https.html] - type: testharness - [CacheStorageMatch with no caches available but name provided] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1158314 - diff --git a/testing/web-platform/meta/service-workers/cache-storage/window/cache-storage.https.html.ini b/testing/web-platform/meta/service-workers/cache-storage/window/cache-storage.https.html.ini deleted file mode 100644 index 11d28f491f6..00000000000 --- a/testing/web-platform/meta/service-workers/cache-storage/window/cache-storage.https.html.ini +++ /dev/null @@ -1,5 +0,0 @@ -[cache-storage.https.html] - type: testharness - [CacheStorage.open with existing cache] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1158306 - diff --git a/testing/web-platform/meta/service-workers/cache-storage/window/sandboxed-iframes.https.html.ini b/testing/web-platform/meta/service-workers/cache-storage/window/sandboxed-iframes.https.html.ini deleted file mode 100644 index 7f8edd628af..00000000000 --- a/testing/web-platform/meta/service-workers/cache-storage/window/sandboxed-iframes.https.html.ini +++ /dev/null @@ -1,3 +0,0 @@ -[sandboxed-iframes.https.html] - type: testharness - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1158324 diff --git a/testing/web-platform/meta/service-workers/cache-storage/worker/cache-add.https.html.ini b/testing/web-platform/meta/service-workers/cache-storage/worker/cache-add.https.html.ini deleted file mode 100644 index 1e6b582ca87..00000000000 --- a/testing/web-platform/meta/service-workers/cache-storage/worker/cache-add.https.html.ini +++ /dev/null @@ -1,18 +0,0 @@ -[cache-add.https.html] - type: testharness - [Cache.add called with non-HTTP/HTTPS URL] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1158265 - - [Cache.add called with Request object] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1158262 - - [Cache.add called with Request object with a used body] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1158262 - expected: FAIL - - [Cache.add called twice with the same Request object] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1158262 - - [Cache.addAll called with the same Request object specified twice] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1158263 - diff --git a/testing/web-platform/meta/service-workers/cache-storage/worker/cache-delete.https.html.ini b/testing/web-platform/meta/service-workers/cache-storage/worker/cache-delete.https.html.ini deleted file mode 100644 index d5a20135c2e..00000000000 --- a/testing/web-platform/meta/service-workers/cache-storage/worker/cache-delete.https.html.ini +++ /dev/null @@ -1,9 +0,0 @@ -[cache-delete.https.html] - type: testharness - [Cache.delete called with a Request object] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1158262 - - [Cache.delete with a Request object containing used body] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1158262 - expected: FAIL - diff --git a/testing/web-platform/meta/service-workers/cache-storage/worker/cache-match.https.html.ini b/testing/web-platform/meta/service-workers/cache-storage/worker/cache-match.https.html.ini deleted file mode 100644 index 2e28cd3d7de..00000000000 --- a/testing/web-platform/meta/service-workers/cache-storage/worker/cache-match.https.html.ini +++ /dev/null @@ -1,15 +0,0 @@ -[cache-match.https.html] - type: testharness - [Cache.matchAll with responses containing "Vary" header] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1158292 - - [Cache.match with responses containing "Vary" header] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1158292 - - [Cache.matchAll with "ignoreVary" parameter] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1158292 - - [Cache.match with Request containing non-empty body] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1158262 - expected: FAIL - diff --git a/testing/web-platform/meta/service-workers/cache-storage/worker/cache-put.https.html.ini b/testing/web-platform/meta/service-workers/cache-storage/worker/cache-put.https.html.ini deleted file mode 100644 index 653135c64a8..00000000000 --- a/testing/web-platform/meta/service-workers/cache-storage/worker/cache-put.https.html.ini +++ /dev/null @@ -1,9 +0,0 @@ -[cache-put.https.html] - type: testharness - [Cache.put with Request containing a body] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1158262 - expected: FAIL - - [Cache.put with a used response body] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1158301 - diff --git a/testing/web-platform/meta/service-workers/cache-storage/worker/cache-storage-match.https.html.ini b/testing/web-platform/meta/service-workers/cache-storage/worker/cache-storage-match.https.html.ini deleted file mode 100644 index b8d08b15d60..00000000000 --- a/testing/web-platform/meta/service-workers/cache-storage/worker/cache-storage-match.https.html.ini +++ /dev/null @@ -1,5 +0,0 @@ -[cache-storage-match.https.html] - type: testharness - [CacheStorageMatch with no caches available but name provided] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1158314 - diff --git a/testing/web-platform/meta/service-workers/cache-storage/worker/cache-storage.https.html.ini b/testing/web-platform/meta/service-workers/cache-storage/worker/cache-storage.https.html.ini deleted file mode 100644 index 11d28f491f6..00000000000 --- a/testing/web-platform/meta/service-workers/cache-storage/worker/cache-storage.https.html.ini +++ /dev/null @@ -1,5 +0,0 @@ -[cache-storage.https.html] - type: testharness - [CacheStorage.open with existing cache] - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1158306 - diff --git a/testing/web-platform/tests/FileAPI/blob/Blob-constructor.html b/testing/web-platform/tests/FileAPI/blob/Blob-constructor.html index 5a5104328f3..54dca00a96e 100644 --- a/testing/web-platform/tests/FileAPI/blob/Blob-constructor.html +++ b/testing/web-platform/tests/FileAPI/blob/Blob-constructor.html @@ -16,7 +16,7 @@ is ongoing that will affect a number of the following tests. diff --git a/testing/web-platform/tests/service-workers/cache-storage/serviceworker/cache-delete.https.html b/testing/web-platform/tests/service-workers/cache-storage/serviceworker/cache-delete.https.html index 50bc36d4582..7a5a43fd9e4 100644 --- a/testing/web-platform/tests/service-workers/cache-storage/serviceworker/cache-delete.https.html +++ b/testing/web-platform/tests/service-workers/cache-storage/serviceworker/cache-delete.https.html @@ -1,6 +1,7 @@ Cache.delete + diff --git a/testing/web-platform/tests/service-workers/cache-storage/serviceworker/cache-storage-keys.https.html b/testing/web-platform/tests/service-workers/cache-storage/serviceworker/cache-storage-keys.https.html index 48e9cd383bc..ec7e14b7af3 100644 --- a/testing/web-platform/tests/service-workers/cache-storage/serviceworker/cache-storage-keys.https.html +++ b/testing/web-platform/tests/service-workers/cache-storage/serviceworker/cache-storage-keys.https.html @@ -1,6 +1,7 @@ CacheStorage.keys + diff --git a/testing/web-platform/tests/service-workers/cache-storage/serviceworker/cache-storage-match.https.html b/testing/web-platform/tests/service-workers/cache-storage/serviceworker/cache-storage-match.https.html index 24c6cea4359..937f143ebb0 100644 --- a/testing/web-platform/tests/service-workers/cache-storage/serviceworker/cache-storage-match.https.html +++ b/testing/web-platform/tests/service-workers/cache-storage/serviceworker/cache-storage-match.https.html @@ -1,6 +1,7 @@ CacheStorage.match + diff --git a/testing/web-platform/tests/service-workers/cache-storage/serviceworker/cache-storage.https.html b/testing/web-platform/tests/service-workers/cache-storage/serviceworker/cache-storage.https.html index b199a65a67b..62c6b63572c 100644 --- a/testing/web-platform/tests/service-workers/cache-storage/serviceworker/cache-storage.https.html +++ b/testing/web-platform/tests/service-workers/cache-storage/serviceworker/cache-storage.https.html @@ -1,6 +1,7 @@ CacheStorage + diff --git a/testing/web-platform/tests/service-workers/cache-storage/window/cache-add.https.html b/testing/web-platform/tests/service-workers/cache-storage/window/cache-add.https.html index 2cd938356db..42e4b5076ac 100644 --- a/testing/web-platform/tests/service-workers/cache-storage/window/cache-add.https.html +++ b/testing/web-platform/tests/service-workers/cache-storage/window/cache-add.https.html @@ -1,6 +1,7 @@ Cache Storage: Cache.add and Cache.addAll + diff --git a/testing/web-platform/tests/service-workers/cache-storage/window/cache-delete.https.html b/testing/web-platform/tests/service-workers/cache-storage/window/cache-delete.https.html index 3ac04a6b187..754f785c7b5 100644 --- a/testing/web-platform/tests/service-workers/cache-storage/window/cache-delete.https.html +++ b/testing/web-platform/tests/service-workers/cache-storage/window/cache-delete.https.html @@ -1,6 +1,7 @@ Cache Storage: Cache.delete + diff --git a/testing/web-platform/tests/service-workers/cache-storage/window/cache-storage-keys.https.html b/testing/web-platform/tests/service-workers/cache-storage/window/cache-storage-keys.https.html index caf1f75f9d0..acde773dd4b 100644 --- a/testing/web-platform/tests/service-workers/cache-storage/window/cache-storage-keys.https.html +++ b/testing/web-platform/tests/service-workers/cache-storage/window/cache-storage-keys.https.html @@ -1,6 +1,7 @@ Cache Storage: CacheStorage.keys + diff --git a/testing/web-platform/tests/service-workers/cache-storage/window/cache-storage-match.https.html b/testing/web-platform/tests/service-workers/cache-storage/window/cache-storage-match.https.html index fe8972508f7..3c69d0f57c1 100644 --- a/testing/web-platform/tests/service-workers/cache-storage/window/cache-storage-match.https.html +++ b/testing/web-platform/tests/service-workers/cache-storage/window/cache-storage-match.https.html @@ -1,6 +1,7 @@ Cache Storage: CacheStorage.match + diff --git a/testing/web-platform/tests/service-workers/cache-storage/window/cache-storage.https.html b/testing/web-platform/tests/service-workers/cache-storage/window/cache-storage.https.html index 48cb364bdbf..7d015e34655 100644 --- a/testing/web-platform/tests/service-workers/cache-storage/window/cache-storage.https.html +++ b/testing/web-platform/tests/service-workers/cache-storage/window/cache-storage.https.html @@ -1,6 +1,7 @@ Cache Storage: CacheStorage + diff --git a/testing/web-platform/tests/service-workers/cache-storage/window/sandboxed-iframes.https.html b/testing/web-platform/tests/service-workers/cache-storage/window/sandboxed-iframes.https.html index de70db4e137..648bd597c57 100644 --- a/testing/web-platform/tests/service-workers/cache-storage/window/sandboxed-iframes.https.html +++ b/testing/web-platform/tests/service-workers/cache-storage/window/sandboxed-iframes.https.html @@ -1,6 +1,7 @@ Cache Storage: Verify access in sandboxed iframes + diff --git a/testing/web-platform/tests/service-workers/cache-storage/worker/cache-add.https.html b/testing/web-platform/tests/service-workers/cache-storage/worker/cache-add.https.html index b6aa9da8ceb..8e6deeb68e0 100644 --- a/testing/web-platform/tests/service-workers/cache-storage/worker/cache-add.https.html +++ b/testing/web-platform/tests/service-workers/cache-storage/worker/cache-add.https.html @@ -1,6 +1,7 @@ Cache.add and Cache.addAll +