Merge for back out changeset ff043f7356f7 - Bug 396519

This commit is contained in:
Robert Strong 2008-09-11 15:08:14 -07:00
commit 043bda8081
10 changed files with 124 additions and 57 deletions

View File

@ -307,6 +307,8 @@ nsDocShell::nsDocShell():
mMarginHeight(0),
mItemType(typeContent),
mDefaultScrollbarPref(Scrollbar_Auto, Scrollbar_Auto),
mPreviousTransIndex(-1),
mLoadedTransIndex(-1),
mTreeOwner(nsnull),
mChromeEventHandler(nsnull)
#ifdef DEBUG
@ -1630,6 +1632,42 @@ nsDocShell::SetUseErrorPages(PRBool aUseErrorPages)
return NS_OK;
}
NS_IMETHODIMP
nsDocShell::GetPreviousTransIndex(PRInt32 *aPreviousTransIndex)
{
*aPreviousTransIndex = mPreviousTransIndex;
return NS_OK;
}
NS_IMETHODIMP
nsDocShell::GetLoadedTransIndex(PRInt32 *aLoadedTransIndex)
{
*aLoadedTransIndex = mLoadedTransIndex;
return NS_OK;
}
NS_IMETHODIMP
nsDocShell::HistoryPurged(PRInt32 aNumEntries)
{
// These indices are used for fastback cache eviction, to determine
// which session history entries are candidates for content viewer
// eviction. We need to adjust by the number of entries that we
// just purged from history, so that we look at the right session history
// entries during eviction.
mPreviousTransIndex = PR_MAX(-1, mPreviousTransIndex - aNumEntries);
mLoadedTransIndex = PR_MAX(0, mLoadedTransIndex - aNumEntries);
PRInt32 count = mChildList.Count();
for (PRInt32 i = 0; i < count; ++i) {
nsCOMPtr<nsIDocShell> shell = do_QueryInterface(ChildAt(i));
if (shell) {
shell->HistoryPurged(aNumEntries);
}
}
return NS_OK;
}
NS_IMETHODIMP
nsDocShell::GetSessionStorageForURI(nsIURI* aURI,
nsIDOMStorage** aStorage)
@ -2675,6 +2713,14 @@ nsDocShell::DoAddChildSHEntry(nsISHEntry* aNewEntry, PRInt32 aChildOffset)
* for this subframe in the CloneAndReplace function.
*/
// In this case, we will end up calling AddEntry, which increases the
// current index by 1
nsCOMPtr<nsISHistory> rootSH;
GetRootSessionHistory(getter_AddRefs(rootSH));
if (rootSH) {
rootSH->GetIndex(&mPreviousTransIndex);
}
nsresult rv;
nsCOMPtr<nsIDocShellHistory> parent =
do_QueryInterface(GetAsSupports(mParent), &rv);
@ -2682,6 +2728,15 @@ nsDocShell::DoAddChildSHEntry(nsISHEntry* aNewEntry, PRInt32 aChildOffset)
rv = parent->AddChildSHEntry(mOSHE, aNewEntry, aChildOffset);
}
if (rootSH) {
rootSH->GetIndex(&mLoadedTransIndex);
#ifdef DEBUG_PAGE_CACHE
printf("Previous index: %d, Loaded index: %d\n\n", mPreviousTransIndex,
mLoadedTransIndex);
#endif
}
return rv;
}
@ -5386,17 +5441,12 @@ nsDocShell::CaptureState()
return NS_ERROR_FAILURE;
}
PRBool shouldSaveContentViewer = PR_FALSE;
nsresult rv = mOSHE->GetSaveContentViewerFlag(&shouldSaveContentViewer);
if (NS_FAILED(rv) || !shouldSaveContentViewer)
return NS_ERROR_FAILURE;
nsCOMPtr<nsPIDOMWindow> privWin = do_QueryInterface(mScriptGlobal);
if (!privWin)
return NS_ERROR_FAILURE;
nsCOMPtr<nsISupports> windowState;
rv = privWin->SaveWindowState(getter_AddRefs(windowState));
nsresult rv = privWin->SaveWindowState(getter_AddRefs(windowState));
NS_ENSURE_SUCCESS(rv, rv);
#ifdef DEBUG_PAGE_CACHE
@ -5707,7 +5757,13 @@ nsDocShell::RestoreFromHistory()
GetRootSessionHistory(getter_AddRefs(rootSH));
if (rootSH) {
nsCOMPtr<nsISHistoryInternal> hist = do_QueryInterface(rootSH);
rootSH->GetIndex(&mPreviousTransIndex);
hist->UpdateIndex();
rootSH->GetIndex(&mLoadedTransIndex);
#ifdef DEBUG_PAGE_CACHE
printf("Previous index: %d, Loaded index: %d\n\n", mPreviousTransIndex,
mLoadedTransIndex);
#endif
}
// Rather than call Embed(), we will retrieve the viewer from the session
@ -8025,7 +8081,13 @@ nsDocShell::OnNewURI(nsIURI * aURI, nsIChannel * aChannel,
if (rootSH && (mLoadType & LOAD_CMD_HISTORY)) {
nsCOMPtr<nsISHistoryInternal> shInternal(do_QueryInterface(rootSH));
if (shInternal) {
rootSH->GetIndex(&mPreviousTransIndex);
shInternal->UpdateIndex();
rootSH->GetIndex(&mLoadedTransIndex);
#ifdef DEBUG_PAGE_CACHE
printf("Previous index: %d, Loaded index: %d\n\n",
mPreviousTransIndex, mLoadedTransIndex);
#endif
}
}
PRBool onLocationChangeNeeded = SetCurrentURI(aURI, aChannel,
@ -8232,7 +8294,13 @@ nsDocShell::AddToSessionHistory(nsIURI * aURI,
nsCOMPtr<nsISHistoryInternal>
shPrivate(do_QueryInterface(mSessionHistory));
NS_ENSURE_TRUE(shPrivate, NS_ERROR_FAILURE);
mSessionHistory->GetIndex(&mPreviousTransIndex);
rv = shPrivate->AddEntry(entry, shouldPersist);
mSessionHistory->GetIndex(&mLoadedTransIndex);
#ifdef DEBUG_PAGE_CACHE
printf("Previous index: %d, Loaded index: %d\n\n",
mPreviousTransIndex, mLoadedTransIndex);
#endif
}
}
else {

View File

@ -648,6 +648,11 @@ protected:
// hash of session storages, keyed by domain
nsInterfaceHashtable<nsCStringHashKey, nsIDOMStorage> mStorages;
// Index into the SHTransaction list, indicating the previous and current
// transaction at the time that this DocShell begins to load
PRInt32 mPreviousTransIndex;
PRInt32 mLoadedTransIndex;
// Editor data, if this document is designMode or contentEditable.
nsAutoPtr<nsDocShellEditorData> mEditorData;

View File

@ -68,7 +68,7 @@ interface nsILayoutHistoryState;
interface nsISecureBrowserUI;
interface nsIDOMStorage;
[scriptable, uuid(cf974f45-d2f1-4bd5-aecd-568a1c4da454)]
[scriptable, uuid(7d1cf6b9-daa3-476d-8f9f-9eb2a971a95c)]
interface nsIDocShell : nsISupports
{
/**
@ -400,6 +400,22 @@ interface nsIDocShell : nsISupports
/* attribute to access whether error pages are enabled */
attribute boolean useErrorPages;
/**
* Keeps track of the previous SHTransaction index and the current
* SHTransaction index at the time that the doc shell begins to load.
* Used for ContentViewer eviction.
*/
readonly attribute long previousTransIndex;
readonly attribute long loadedTransIndex;
/**
* Notification that entries have been removed from the beginning of a
* nsSHistory which has this as its rootDocShell.
*
* @param numEntries - The number of entries removed
*/
void historyPurged(in long numEntries);
/*
* Retrieves the WebApps session storage object for the supplied domain.
* If it doesn't already exist, a new one will be created.

View File

@ -1239,7 +1239,13 @@ nsresult nsWebShell::EndPageLoad(nsIWebProgress *aProgress,
if (rootSH && (mLoadType & LOAD_CMD_HISTORY)) {
nsCOMPtr<nsISHistoryInternal> shInternal(do_QueryInterface(rootSH));
if (shInternal) {
rootSH->GetIndex(&mPreviousTransIndex);
shInternal->UpdateIndex();
rootSH->GetIndex(&mLoadedTransIndex);
#ifdef DEBUG_PAGE_CACHE
printf("Previous index: %d, Loaded index: %d\n\n",
mPreviousTransIndex, mLoadedTransIndex);
#endif
}
}

View File

@ -58,7 +58,7 @@ class nsDocShellEditorData;
[ptr] native nsDocShellEditorDataPtr(nsDocShellEditorData);
[scriptable, uuid(622412da-be41-407e-b57e-9aba2a282b00)]
[scriptable, uuid(c16fde76-3108-450e-8c8c-ae8286f286ed)]
interface nsISHEntry : nsIHistoryEntry
{
/** URI for the document */
@ -152,9 +152,6 @@ interface nsISHEntry : nsIHistoryEntry
/** attribute to set and get the cache key for the entry */
attribute nsISupports cacheKey;
/** attribute to indicate whether the contentViewer should be saved */
attribute boolean saveContentViewerFlag;
/** attribute to indicate whether layoutHistoryState should be saved */
attribute boolean saveLayoutStateFlag;

View File

@ -52,7 +52,7 @@ interface nsIDocShell;
#define NS_SHISTORY_INTERNAL_CONTRACTID "@mozilla.org/browser/shistory-internal;1"
%}
[scriptable, uuid(0e91697a-4ba0-4ede-b08a-0bae9ee1a701)]
[scriptable, uuid(9c47c121-1c6e-4d8f-b904-3ac968116e88)]
interface nsISHistoryInternal: nsISupports
{
/**
@ -92,11 +92,13 @@ interface nsISHistoryInternal: nsISupports
readonly attribute nsISHistoryListener listener;
/**
* Count total number of content viewers globally and evict one if we are over
* our total max. This is always called in Show(), after we destroy the
* previous viewer.
* Evict content viewers until the number of content viewers per tab
* is no more than gHistoryMaxViewers. Also, count
* total number of content viewers globally and evict one if we are over
* our total max. This is always called in Show(), after we destroy
* the previous viewer.
*/
void evictContentViewers();
void evictContentViewers(in long previousIndex, in long index);
/**
* Evict the content viewer associated with a session history entry

View File

@ -106,7 +106,6 @@ nsSHEntry::nsSHEntry()
, mPageIdentifier(mID)
, mScrollPositionX(0)
, mScrollPositionY(0)
, mSaveContentViewer(PR_TRUE)
, mIsFrameNavigation(PR_FALSE)
, mSaveLayoutState(PR_TRUE)
, mExpired(PR_FALSE)
@ -128,7 +127,6 @@ nsSHEntry::nsSHEntry(const nsSHEntry &other)
, mPageIdentifier(other.mPageIdentifier)
, mScrollPositionX(0) // XXX why not copy?
, mScrollPositionY(0) // XXX why not copy?
, mSaveContentViewer(other.mSaveContentViewer)
, mIsFrameNavigation(other.mIsFrameNavigation)
, mSaveLayoutState(other.mSaveLayoutState)
, mExpired(other.mExpired)
@ -418,18 +416,6 @@ NS_IMETHODIMP nsSHEntry::SetCacheKey(nsISupports* aCacheKey)
return NS_OK;
}
NS_IMETHODIMP nsSHEntry::GetSaveContentViewerFlag(PRBool * aFlag)
{
*aFlag = mSaveContentViewer;
return NS_OK;
}
NS_IMETHODIMP nsSHEntry::SetSaveContentViewerFlag(PRBool aFlag)
{
mSaveContentViewer = aFlag;
return NS_OK;
}
NS_IMETHODIMP nsSHEntry::GetSaveLayoutStateFlag(PRBool * aFlag)
{
*aFlag = mSaveLayoutState;

View File

@ -102,7 +102,6 @@ private:
PRUint32 mPageIdentifier;
PRInt32 mScrollPositionX;
PRInt32 mScrollPositionY;
PRPackedBool mSaveContentViewer;
PRPackedBool mIsFrameNavigation;
PRPackedBool mSaveLayoutState;
PRPackedBool mExpired;

View File

@ -330,7 +330,6 @@ nsSHistory::AddEntry(nsISHEntry * aSHEntry, PRBool aPersist)
// 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.
PRInt32 oldIndex = mIndex;
mLength = (++mIndex + 1);
// If this is the very first transaction, initialize the list
@ -341,8 +340,6 @@ nsSHistory::AddEntry(nsISHEntry * aSHEntry, PRBool aPersist)
if ((gHistoryMaxSize >= 0) && (mLength > gHistoryMaxSize))
PurgeHistory(mLength-gHistoryMaxSize);
// Evict a content viewer if we might have too many behind us
EvictWindowContentViewers(oldIndex, mIndex);
return NS_OK;
}
@ -586,6 +583,9 @@ nsSHistory::PurgeHistory(PRInt32 aEntries)
mIndex = -1;
}
if (mRootDocShell)
mRootDocShell->HistoryPurged(cnt);
return NS_OK;
}
@ -655,8 +655,10 @@ nsSHistory::GetListener(nsISHistoryListener ** aListener)
}
NS_IMETHODIMP
nsSHistory::EvictContentViewers()
nsSHistory::EvictContentViewers(PRInt32 aPreviousIndex, PRInt32 aIndex)
{
// Check our per SHistory object limit in the currently navigated SHistory
EvictWindowContentViewers(aPreviousIndex, aIndex);
// Check our total limit across all SHistory objects
EvictGlobalContentViewer();
return NS_OK;
@ -1124,15 +1126,6 @@ nsSHistory::LoadURI(const PRUnichar* aURI,
NS_IMETHODIMP
nsSHistory::GotoIndex(PRInt32 aIndex)
{
if (mIndex > -1 && PR_ABS(aIndex - mIndex) > gHistoryMaxViewers) {
// The current entry is too far from the new index, so mark it so its
// content viewer doesn't get saved.
nsCOMPtr<nsISHEntry> currentEntry;
nsresult rv = GetEntryAtIndex(mIndex, PR_FALSE, getter_AddRefs(currentEntry));
if (NS_SUCCEEDED(rv) && currentEntry)
currentEntry->SetSaveContentViewerFlag(PR_FALSE);
}
return LoadEntry(aIndex, nsIDocShellLoadInfo::loadHistory, HIST_CMD_GOTOINDEX);
}
@ -1228,17 +1221,7 @@ nsSHistory::LoadEntry(PRInt32 aIndex, long aLoadType, PRUint32 aHistCmd)
}
// Start the load on the appropriate docshell
nsresult rv = InitiateLoad(nextEntry, docShell, aLoadType);
if (NS_SUCCEEDED(rv)) {
// mark the entry as being able to save its content viewer
nextEntry->SetSaveContentViewerFlag(PR_TRUE);
// evict any content viewers that are now gHistoryMaxViewers
// or more away from the new index
EvictWindowContentViewers(mIndex, mRequestedIndex);
}
return rv;
return InitiateLoad(nextEntry, docShell, aLoadType);
}

View File

@ -1861,10 +1861,15 @@ DocumentViewerImpl::Show(void)
webNav->GetSessionHistory(getter_AddRefs(history));
nsCOMPtr<nsISHistoryInternal> historyInt = do_QueryInterface(history);
if (historyInt) {
PRInt32 prevIndex,loadedIndex;
nsCOMPtr<nsIDocShell> docShell = do_QueryInterface(treeItem);
docShell->GetPreviousTransIndex(&prevIndex);
docShell->GetLoadedTransIndex(&loadedIndex);
#ifdef DEBUG_PAGE_CACHE
printf("About to evict content viewers\n");
printf("About to evict content viewers: prev=%d, loaded=%d\n",
prevIndex, loadedIndex);
#endif
historyInt->EvictContentViewers();
historyInt->EvictContentViewers(prevIndex, loadedIndex);
}
}
}