From f80cfaf15ba9f369ed36d42b13e6f588948e6e9c Mon Sep 17 00:00:00 2001 From: Samael Wang Date: Thu, 24 Aug 2017 14:32:23 +0800 Subject: [PATCH] Bug 1364364 - Part 2: Extract a part of EvictExpiredContentViewerForEntry to a new function FindTransactionForBFCache, and implement RemoveDynEntriesForEntry on top of it. r=smaug MozReview-Commit-ID: EzK2U0c94v8 --HG-- extra : rebase_source : 472fae2733efae09157b8440c466a8c5ccc6b626 --- docshell/shistory/nsISHistoryInternal.idl | 14 ++++++++ docshell/shistory/nsSHistory.cpp | 43 ++++++++++++++++++++--- docshell/shistory/nsSHistory.h | 6 ++++ 3 files changed, 58 insertions(+), 5 deletions(-) diff --git a/docshell/shistory/nsISHistoryInternal.idl b/docshell/shistory/nsISHistoryInternal.idl index ae0a1facf073..22af9d85f8d2 100644 --- a/docshell/shistory/nsISHistoryInternal.idl +++ b/docshell/shistory/nsISHistoryInternal.idl @@ -120,6 +120,20 @@ interface nsISHistoryInternal: nsISupports [noscript, notxpcom] void RemoveDynEntries(in long aIndex, in nsISHContainer aContainer); + /** + * Similar to RemoveDynEntries, but instead of specifying an index, use the + * given BFCacheEntry to find the index and remove dynamic entries from the + * index. + * + * The method takes no effect if the bfcache entry is not or no longer hold + * by the SHistory instance. + * + * @param aEntry + * The bfcache entry to look up for index to remove dynamic entries + * from. + */ + [noscript, notxpcom] void RemoveDynEntriesForBFCacheEntry(in nsIBFCacheEntry aEntry); + /** * Removes entries from the history if their docshellID is in * aIDs array. diff --git a/docshell/shistory/nsSHistory.cpp b/docshell/shistory/nsSHistory.cpp index d36a7582fdb4..a3419d88bd3e 100644 --- a/docshell/shistory/nsSHistory.cpp +++ b/docshell/shistory/nsSHistory.cpp @@ -213,7 +213,7 @@ nsSHistory::EvictContentViewerForTransaction(nsISHTransaction* aTrans) LOG_SHENTRY_SPEC(("Evicting content viewer 0x%p for " "owning SHEntry 0x%p at %s.", viewer.get(), ownerEntry.get(), _spec), - ownerEntry); + ownerEntry); // Drop the presentation state before destroying the viewer, so that // document teardown is able to correctly persist the state. @@ -1290,8 +1290,13 @@ nsSHistory::GloballyEvictContentViewers() } nsresult -nsSHistory::EvictExpiredContentViewerForEntry(nsIBFCacheEntry* aEntry) +nsSHistory::FindTransactionForBFCache(nsIBFCacheEntry* aEntry, + nsISHTransaction** aResult, + int32_t* aResultIndex) { + *aResult = nullptr; + *aResultIndex = -1; + int32_t startIndex = std::max(0, mIndex - nsISHistory::VIEWER_WINDOW); int32_t endIndex = std::min(mLength - 1, mIndex + nsISHistory::VIEWER_WINDOW); nsCOMPtr trans; @@ -1311,15 +1316,29 @@ nsSHistory::EvictExpiredContentViewerForEntry(nsIBFCacheEntry* aEntry) temp->GetNext(getter_AddRefs(trans)); } if (i > endIndex) { - return NS_OK; + return NS_ERROR_FAILURE; } - if (i == mIndex) { + trans.forget(aResult); + *aResultIndex = i; + return NS_OK; +} + +nsresult +nsSHistory::EvictExpiredContentViewerForEntry(nsIBFCacheEntry* aEntry) +{ + int32_t index; + nsCOMPtr trans; + FindTransactionForBFCache(aEntry, getter_AddRefs(trans), &index); + + if (index == mIndex) { NS_WARNING("How did the current SHEntry expire?"); return NS_OK; } - EvictContentViewerForTransaction(trans); + if (trans) { + EvictContentViewerForTransaction(trans); + } return NS_OK; } @@ -1586,6 +1605,20 @@ nsSHistory::RemoveDynEntries(int32_t aIndex, nsISHContainer* aContainer) } } +void +nsSHistory::RemoveDynEntriesForBFCacheEntry(nsIBFCacheEntry* aEntry) +{ + int32_t index; + nsCOMPtr trans; + FindTransactionForBFCache(aEntry, getter_AddRefs(trans), &index); + if (trans) { + nsCOMPtr entry; + trans->GetSHEntry(getter_AddRefs(entry)); + nsCOMPtr container(do_QueryInterface(entry)); + RemoveDynEntries(index, container); + } +} + NS_IMETHODIMP nsSHistory::UpdateIndex() { diff --git a/docshell/shistory/nsSHistory.h b/docshell/shistory/nsSHistory.h index a8933ad17763..41d0186e771b 100644 --- a/docshell/shistory/nsSHistory.h +++ b/docshell/shistory/nsSHistory.h @@ -96,6 +96,12 @@ private: nsresult PrintHistory(); #endif + // Find the transaction for a given bfcache entry. It only looks up between + // the range where alive viewers may exist (i.e nsISHistory::VIEWER_WINDOW). + nsresult FindTransactionForBFCache(nsIBFCacheEntry* aEntry, + nsISHTransaction** aResult, + int32_t* aResultIndex); + // Evict content viewers in this window which don't lie in the "safe" range // around aIndex. void EvictOutOfRangeWindowContentViewers(int32_t aIndex);