Bug 1421704 - Optimize NotifyVisited IPC to take batch r=mak

During history import, sending NotifyVisited messages from the
chrome process to the content processes in order to change link
colors can take a significant portion of the parent process's
main thread time. Batching it seems to have very significant
results on jank time during history imports.

MozReview-Commit-ID: BHAXpIMa7ly

--HG--
extra : rebase_source : f43c653e6945d7775cc9dd7bca4c1e84099c2673
This commit is contained in:
Doug Thayer 2017-12-04 09:45:29 -08:00
Родитель 4b804b50dd
Коммит 42065fc66b
5 изменённых файлов: 44 добавлений и 25 удалений

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

@ -2453,15 +2453,17 @@ ContentChild::RecvNotifyAlertsObserver(const nsCString& aType, const nsString& a
// NOTE: This method is being run in the SystemGroup, and thus cannot directly
// touch pages. See GetSpecificMessageEventTarget.
mozilla::ipc::IPCResult
ContentChild::RecvNotifyVisited(const URIParams& aURI)
ContentChild::RecvNotifyVisited(nsTArray<URIParams>&& aURIs)
{
nsCOMPtr<nsIURI> newURI = DeserializeURI(aURI);
if (!newURI) {
return IPC_FAIL_NO_REASON(this);
}
nsCOMPtr<IHistory> history = services::GetHistoryService();
if (history) {
history->NotifyVisited(newURI);
for (const URIParams& uri : aURIs) {
nsCOMPtr<nsIURI> newURI = DeserializeURI(uri);
if (!newURI) {
return IPC_FAIL_NO_REASON(this);
}
nsCOMPtr<IHistory> history = services::GetHistoryService();
if (history) {
history->NotifyVisited(newURI);
}
}
return IPC_OK();
}

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

@ -362,7 +362,7 @@ public:
virtual mozilla::ipc::IPCResult RecvBidiKeyboardNotify(const bool& isLangRTL,
const bool& haveBidiKeyboards) override;
virtual mozilla::ipc::IPCResult RecvNotifyVisited(const URIParams& aURI) override;
virtual mozilla::ipc::IPCResult RecvNotifyVisited(nsTArray<URIParams>&& aURIs) override;
// auto remove when alertfinished is received.
nsresult AddRemoteAlertObserver(const nsString& aData, nsIObserver* aObserver);

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

@ -426,7 +426,7 @@ child:
async SetConnectivity(bool connectivity);
async SetCaptivePortalState(int32_t aState);
async NotifyVisited(URIParams uri);
async NotifyVisited(URIParams[] uri);
async PreferenceUpdate(Pref pref);
async VarUpdate(GfxVarUpdate var);

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

@ -575,6 +575,11 @@ public:
History* history = History::GetService();
NS_ENSURE_STATE(history);
history->NotifyVisited(mURI);
AutoTArray<URIParams, 1> uris;
URIParams uri;
SerializeURI(mURI, uri);
uris.AppendElement(Move(uri));
history->NotifyVisitedParent(uris);
}
nsCOMPtr<nsIObserverService> observerService =
@ -643,6 +648,7 @@ public:
nsresult NotifyVisit(nsNavHistory* aNavHistory,
nsCOMPtr<nsIObserverService>& aObsService,
PRTime aNow,
nsTArray<URIParams>& aNotifyVisitedURIs,
VisitData aPlace) {
nsCOMPtr<nsIURI> uri;
MOZ_ALWAYS_SUCCEEDS(NS_NewURI(getter_AddRefs(uri), aPlace.spec));
@ -675,6 +681,10 @@ public:
aNavHistory->NotifyTitleChange(uri, aPlace.title, aPlace.guid);
}
URIParams serialized;
SerializeURI(uri, serialized);
aNotifyVisitedURIs.AppendElement(Move(serialized));
return NS_OK;
}
@ -699,13 +709,17 @@ public:
PRTime now = PR_Now();
if (mPlaces.Length() > 0) {
InfallibleTArray<URIParams> uris(mPlaces.Length());
for (uint32_t i = 0; i < mPlaces.Length(); ++i) {
nsresult rv = NotifyVisit(navHistory, obsService, now, mPlaces[i]);
nsresult rv = NotifyVisit(navHistory, obsService, now, uris, mPlaces[i]);
NS_ENSURE_SUCCESS(rv, rv);
}
mHistory->NotifyVisitedParent(uris);
} else {
nsresult rv = NotifyVisit(navHistory, obsService, now, mPlace);
AutoTArray<URIParams, 1> uris;
nsresult rv = NotifyVisit(navHistory, obsService, now, uris, mPlace);
NS_ENSURE_SUCCESS(rv, rv);
mHistory->NotifyVisitedParent(uris);
}
return NS_OK;
@ -1998,6 +2012,20 @@ GetLinkDocument(Link* aLink)
return element ? element->OwnerDoc() : nullptr;
}
void
History::NotifyVisitedParent(const nsTArray<URIParams>& aURIs)
{
MOZ_ASSERT(XRE_IsParentProcess());
nsTArray<ContentParent*> cplist;
ContentParent::GetAll(cplist);
if (!cplist.IsEmpty()) {
for (uint32_t i = 0; i < cplist.Length(); ++i) {
Unused << cplist[i]->SendNotifyVisited(aURIs);
}
}
}
NS_IMETHODIMP
History::NotifyVisited(nsIURI* aURI)
{
@ -2008,19 +2036,6 @@ History::NotifyVisited(nsIURI* aURI)
nsAutoScriptBlocker scriptBlocker;
if (XRE_IsParentProcess()) {
nsTArray<ContentParent*> cplist;
ContentParent::GetAll(cplist);
if (!cplist.IsEmpty()) {
URIParams uri;
SerializeURI(aURI, uri);
for (uint32_t i = 0; i < cplist.Length(); ++i) {
Unused << cplist[i]->SendNotifyVisited(uri);
}
}
}
// If we have no observers for this URI, we have nothing to notify about.
KeyClass* key = mObservers.GetEntry(aURI);
if (!key) {

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

@ -15,6 +15,7 @@
#include "Database.h"
#include "mozilla/dom/Link.h"
#include "mozilla/ipc/URIParams.h"
#include "nsTHashtable.h"
#include "nsString.h"
#include "nsURIHashKey.h"
@ -143,6 +144,7 @@ public:
*/
void AppendToRecentlyVisitedURIs(nsIURI* aURI);
void NotifyVisitedParent(const nsTArray<mozilla::ipc::URIParams>& aURIs);
private:
virtual ~History();