зеркало из https://github.com/mozilla/gecko-dev.git
fix for bug 75183, "separate eviction policy for chrome needed". sr=darin.
This commit is contained in:
Родитель
7f033b21f1
Коммит
96f47a92dc
|
@ -41,14 +41,16 @@ const char *gMemoryCacheSizePref = "browser.cache.memory_cache_size";
|
||||||
|
|
||||||
|
|
||||||
nsMemoryCacheDevice::nsMemoryCacheDevice()
|
nsMemoryCacheDevice::nsMemoryCacheDevice()
|
||||||
: mHardLimit(0),
|
: mEvictionThreshold(40 * 1024),
|
||||||
|
mHardLimit(0),
|
||||||
mSoftLimit(0),
|
mSoftLimit(0),
|
||||||
mTotalSize(0),
|
mTotalSize(0),
|
||||||
mInactiveSize(0),
|
mInactiveSize(0),
|
||||||
mEntryCount(0),
|
mEntryCount(0),
|
||||||
mMaxEntryCount(0)
|
mMaxEntryCount(0)
|
||||||
{
|
{
|
||||||
PR_INIT_CLIST(&mEvictionList);
|
PR_INIT_CLIST(&mEvictionList[mostLikelyToEvict]);
|
||||||
|
PR_INIT_CLIST(&mEvictionList[leastLikelyToEvict]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -130,20 +132,22 @@ nsMemoryCacheDevice::Shutdown()
|
||||||
// evict all entries
|
// evict all entries
|
||||||
nsCacheEntry * entry, * next;
|
nsCacheEntry * entry, * next;
|
||||||
|
|
||||||
entry = (nsCacheEntry *)PR_LIST_HEAD(&mEvictionList);
|
for (int i=mostLikelyToEvict; i <= leastLikelyToEvict; ++i) {
|
||||||
while (entry != &mEvictionList) {
|
entry = (nsCacheEntry *)PR_LIST_HEAD(&mEvictionList[i]);
|
||||||
NS_ASSERTION(entry->IsInUse() == PR_FALSE, "### shutting down with active entries.\n");
|
while (entry != &mEvictionList[i]) {
|
||||||
next = (nsCacheEntry *)PR_NEXT_LINK(entry);
|
NS_ASSERTION(entry->IsInUse() == PR_FALSE, "### shutting down with active entries.\n");
|
||||||
PR_REMOVE_AND_INIT_LINK(entry);
|
next = (nsCacheEntry *)PR_NEXT_LINK(entry);
|
||||||
|
PR_REMOVE_AND_INIT_LINK(entry);
|
||||||
// update statistics
|
|
||||||
PRUint32 memoryRecovered = entry->Size();
|
// update statistics
|
||||||
mTotalSize -= memoryRecovered;
|
PRUint32 memoryRecovered = entry->Size();
|
||||||
mInactiveSize -= memoryRecovered;
|
mTotalSize -= memoryRecovered;
|
||||||
--mEntryCount;
|
mInactiveSize -= memoryRecovered;
|
||||||
|
--mEntryCount;
|
||||||
|
|
||||||
delete entry;
|
delete entry;
|
||||||
entry = next;
|
entry = next;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -169,9 +173,9 @@ nsMemoryCacheDevice::FindEntry(nsCString * key)
|
||||||
nsCacheEntry * entry = mMemCacheEntries.GetEntry(key);
|
nsCacheEntry * entry = mMemCacheEntries.GetEntry(key);
|
||||||
if (!entry) return nsnull;
|
if (!entry) return nsnull;
|
||||||
|
|
||||||
// move entry to the tail of the eviction list
|
// move entry to the tail of an eviction list
|
||||||
PR_REMOVE_AND_INIT_LINK(entry);
|
PR_REMOVE_AND_INIT_LINK(entry);
|
||||||
PR_APPEND_LINK(entry, &mEvictionList);
|
PR_APPEND_LINK(entry, &mEvictionList[EvictionList(entry, 0)]);
|
||||||
|
|
||||||
mInactiveSize -= entry->Size();
|
mInactiveSize -= entry->Size();
|
||||||
|
|
||||||
|
@ -214,7 +218,7 @@ nsMemoryCacheDevice::BindEntry(nsCacheEntry * entry)
|
||||||
|
|
||||||
if (!entry->IsDoomed()) {
|
if (!entry->IsDoomed()) {
|
||||||
// append entry to the eviction list
|
// append entry to the eviction list
|
||||||
PR_APPEND_LINK(entry, &mEvictionList);
|
PR_APPEND_LINK(entry, &mEvictionList[EvictionList(entry, 0)]);
|
||||||
|
|
||||||
// add entry to hashtable of mem cache entries
|
// add entry to hashtable of mem cache entries
|
||||||
nsresult rv = mMemCacheEntries.AddEntry(entry);
|
nsresult rv = mMemCacheEntries.AddEntry(entry);
|
||||||
|
@ -293,6 +297,12 @@ nsMemoryCacheDevice::OnDataSizeChange( nsCacheEntry * entry, PRInt32 deltaSize)
|
||||||
|
|
||||||
// adjust our totals
|
// adjust our totals
|
||||||
mTotalSize += deltaSize;
|
mTotalSize += deltaSize;
|
||||||
|
|
||||||
|
if (!entry->IsDoomed()) {
|
||||||
|
// move entry to the tail of the appropriate eviction list
|
||||||
|
PR_REMOVE_AND_INIT_LINK(entry);
|
||||||
|
PR_APPEND_LINK(entry, &mEvictionList[EvictionList(entry, deltaSize)]);
|
||||||
|
}
|
||||||
|
|
||||||
EvictEntriesIfNecessary();
|
EvictEntriesIfNecessary();
|
||||||
|
|
||||||
|
@ -336,25 +346,36 @@ nsMemoryCacheDevice::EvictEntriesIfNecessary(void)
|
||||||
if ((mTotalSize < mHardLimit) && (mInactiveSize < mSoftLimit))
|
if ((mTotalSize < mHardLimit) && (mInactiveSize < mSoftLimit))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// XXX implement more sophisticated eviction ordering
|
for (int i=mostLikelyToEvict; i<=leastLikelyToEvict; ++i) {
|
||||||
|
entry = (nsCacheEntry *)PR_LIST_HEAD(&mEvictionList[i]);
|
||||||
|
while (entry != &mEvictionList[i]) {
|
||||||
|
if (entry->IsInUse()) {
|
||||||
|
entry = (nsCacheEntry *)PR_NEXT_LINK(entry);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
entry = (nsCacheEntry *)PR_LIST_HEAD(&mEvictionList);
|
next = (nsCacheEntry *)PR_NEXT_LINK(entry);
|
||||||
while (entry != &mEvictionList) {
|
EvictEntry(entry);
|
||||||
if (entry->IsInUse()) {
|
entry = next;
|
||||||
entry = (nsCacheEntry *)PR_NEXT_LINK(entry);
|
|
||||||
continue;
|
if ((mTotalSize < mHardLimit) && (mInactiveSize < mSoftLimit))
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
next = (nsCacheEntry *)PR_NEXT_LINK(entry);
|
|
||||||
EvictEntry(entry);
|
|
||||||
entry = next;
|
|
||||||
|
|
||||||
if ((mTotalSize < mHardLimit) && (mInactiveSize < mSoftLimit))
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
nsMemoryCacheDevice::EvictionList(nsCacheEntry * entry, PRUint32 deltaSize)
|
||||||
|
{
|
||||||
|
PRUint32 size = entry->Size() + deltaSize;
|
||||||
|
if ((size > mEvictionThreshold) || (entry->ExpirationTime() != 0))
|
||||||
|
return mostLikelyToEvict;
|
||||||
|
|
||||||
|
return leastLikelyToEvict;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
nsMemoryCacheDevice::Visit(nsICacheVisitor * visitor)
|
nsMemoryCacheDevice::Visit(nsICacheVisitor * visitor)
|
||||||
{
|
{
|
||||||
|
@ -372,20 +393,21 @@ nsMemoryCacheDevice::Visit(nsICacheVisitor * visitor)
|
||||||
nsCacheEntry * entry;
|
nsCacheEntry * entry;
|
||||||
nsCOMPtr<nsICacheEntryInfo> entryRef;
|
nsCOMPtr<nsICacheEntryInfo> entryRef;
|
||||||
|
|
||||||
entry = (nsCacheEntry *)PR_LIST_HEAD(&mEvictionList);
|
for (int i=mostLikelyToEvict; i <= leastLikelyToEvict; ++i) {
|
||||||
while (entry != &mEvictionList) {
|
entry = (nsCacheEntry *)PR_LIST_HEAD(&mEvictionList[i]);
|
||||||
nsCacheEntryInfo * entryInfo = new nsCacheEntryInfo(entry);
|
while (entry != &mEvictionList[i]) {
|
||||||
if (!entryInfo) return NS_ERROR_OUT_OF_MEMORY;
|
nsCacheEntryInfo * entryInfo = new nsCacheEntryInfo(entry);
|
||||||
entryRef = entryInfo;
|
if (!entryInfo) return NS_ERROR_OUT_OF_MEMORY;
|
||||||
|
entryRef = entryInfo;
|
||||||
|
|
||||||
rv = visitor->VisitEntry(gMemoryDeviceID, entryInfo, &keepGoing);
|
rv = visitor->VisitEntry(gMemoryDeviceID, entryInfo, &keepGoing);
|
||||||
entryInfo->DetachEntry();
|
entryInfo->DetachEntry();
|
||||||
if (NS_FAILED(rv)) return rv;
|
if (NS_FAILED(rv)) return rv;
|
||||||
if (!keepGoing) break;
|
if (!keepGoing) break;
|
||||||
|
|
||||||
entry = (nsCacheEntry *)PR_NEXT_LINK(entry);
|
entry = (nsCacheEntry *)PR_NEXT_LINK(entry);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -396,20 +418,22 @@ nsMemoryCacheDevice::EvictEntries(const char * clientID)
|
||||||
nsCacheEntry * entry;
|
nsCacheEntry * entry;
|
||||||
PRUint32 prefixLength = (clientID ? nsCRT::strlen(clientID) : 0);
|
PRUint32 prefixLength = (clientID ? nsCRT::strlen(clientID) : 0);
|
||||||
|
|
||||||
PRCList * elem = PR_LIST_HEAD(&mEvictionList);
|
for (int i=mostLikelyToEvict; i<=leastLikelyToEvict; ++i) {
|
||||||
while (elem != &mEvictionList) {
|
PRCList * elem = PR_LIST_HEAD(&mEvictionList[i]);
|
||||||
entry = (nsCacheEntry *)elem;
|
while (elem != &mEvictionList[i]) {
|
||||||
elem = PR_NEXT_LINK(elem);
|
entry = (nsCacheEntry *)elem;
|
||||||
|
elem = PR_NEXT_LINK(elem);
|
||||||
const char * key = entry->Key()->get();
|
|
||||||
if (clientID && nsCRT::strncmp(clientID, key, prefixLength) != 0)
|
const char * key = entry->Key()->get();
|
||||||
continue;
|
if (clientID && nsCRT::strncmp(clientID, key, prefixLength) != 0)
|
||||||
|
continue;
|
||||||
if (entry->IsInUse()) {
|
|
||||||
nsresult rv = nsCacheService::GlobalInstance()->DoomEntry_Locked(entry);
|
if (entry->IsInUse()) {
|
||||||
if (NS_FAILED(rv)) return rv;
|
nsresult rv = nsCacheService::GlobalInstance()->DoomEntry_Locked(entry);
|
||||||
} else {
|
if (NS_FAILED(rv)) return rv;
|
||||||
EvictEntry(entry);
|
} else {
|
||||||
|
EvictEntry(entry);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
|
|
|
@ -70,9 +70,17 @@ private:
|
||||||
void AdjustMemoryLimits( PRUint32 softLimit, PRUint32 hardLimit);
|
void AdjustMemoryLimits( PRUint32 softLimit, PRUint32 hardLimit);
|
||||||
void EvictEntry( nsCacheEntry * entry );
|
void EvictEntry( nsCacheEntry * entry );
|
||||||
void EvictEntriesIfNecessary();
|
void EvictEntriesIfNecessary();
|
||||||
|
int EvictionList(nsCacheEntry * entry, PRUint32 deltaSize);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Data members
|
||||||
|
*/
|
||||||
|
|
||||||
nsCacheEntryHashTable mMemCacheEntries;
|
nsCacheEntryHashTable mMemCacheEntries;
|
||||||
PRCList mEvictionList;
|
|
||||||
|
enum { mostLikelyToEvict = 0, leastLikelyToEvict = 1 }; // constants to differentiate eviction lists
|
||||||
|
PRCList mEvictionList[2];
|
||||||
|
PRUint32 mEvictionThreshold;
|
||||||
|
|
||||||
PRUint32 mHardLimit;
|
PRUint32 mHardLimit;
|
||||||
PRUint32 mSoftLimit;
|
PRUint32 mSoftLimit;
|
||||||
|
|
Загрузка…
Ссылка в новой задаче