diff options
author | kinuko@chromium.org <kinuko@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-04-11 06:04:56 +0000 |
---|---|---|
committer | kinuko@chromium.org <kinuko@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-04-11 06:04:56 +0000 |
commit | 05d8c3ab7688cc2c009f4514779f1f9f40e8e36c (patch) | |
tree | 029631c66090abb67c21a6f7f3ecda8f37a4e81c /webkit | |
parent | 45c9010caec464904fe9cb0fd68173895e562a61 (diff) | |
download | chromium_src-05d8c3ab7688cc2c009f4514779f1f9f40e8e36c.zip chromium_src-05d8c3ab7688cc2c009f4514779f1f9f40e8e36c.tar.gz chromium_src-05d8c3ab7688cc2c009f4514779f1f9f40e8e36c.tar.bz2 |
Purge in-memory localStorage areas if the # of areas exceeds the limit
BUG=178980
TEST=manual (verified the memory stops increasing at a certain level)
Review URL: https://chromiumcodereview.appspot.com/12398008
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@193585 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'webkit')
-rw-r--r-- | webkit/dom_storage/dom_storage_area.h | 3 | ||||
-rw-r--r-- | webkit/dom_storage/dom_storage_context.cc | 2 | ||||
-rw-r--r-- | webkit/dom_storage/dom_storage_host.cc | 16 | ||||
-rw-r--r-- | webkit/dom_storage/dom_storage_host.h | 1 | ||||
-rw-r--r-- | webkit/dom_storage/dom_storage_namespace.cc | 18 | ||||
-rw-r--r-- | webkit/dom_storage/dom_storage_namespace.h | 14 | ||||
-rw-r--r-- | webkit/dom_storage/dom_storage_types.h | 3 |
7 files changed, 52 insertions, 5 deletions
diff --git a/webkit/dom_storage/dom_storage_area.h b/webkit/dom_storage/dom_storage_area.h index 0c0a76b..57c0e89 100644 --- a/webkit/dom_storage/dom_storage_area.h +++ b/webkit/dom_storage/dom_storage_area.h @@ -80,6 +80,9 @@ class WEBKIT_STORAGE_EXPORT DomStorageArea // no longer do anything. void Shutdown(); + // Returns true if the data is loaded in memory. + bool IsLoadedInMemory() const { return is_initial_import_done_; } + private: friend class DomStorageAreaTest; FRIEND_TEST_ALL_PREFIXES(DomStorageAreaTest, DomStorageAreaBasics); diff --git a/webkit/dom_storage/dom_storage_context.cc b/webkit/dom_storage/dom_storage_context.cc index 8065ec6..80df009 100644 --- a/webkit/dom_storage/dom_storage_context.cc +++ b/webkit/dom_storage/dom_storage_context.cc @@ -167,7 +167,7 @@ void DomStorageContext::PurgeMemory() { StorageNamespaceMap::iterator found = namespaces_.find(kLocalStorageNamespaceId); if (found != namespaces_.end()) - found->second->PurgeMemory(); + found->second->PurgeMemory(DomStorageNamespace::PURGE_AGGRESSIVE); } void DomStorageContext::Shutdown() { diff --git a/webkit/dom_storage/dom_storage_host.cc b/webkit/dom_storage/dom_storage_host.cc index a8637e0..7f4fca1 100644 --- a/webkit/dom_storage/dom_storage_host.cc +++ b/webkit/dom_storage/dom_storage_host.cc @@ -61,6 +61,15 @@ bool DomStorageHost::ExtractAreaValues( // for sending a bad message. return true; } + if (!area->IsLoadedInMemory()) { + DomStorageNamespace* ns = GetNamespace(connection_id); + DCHECK(ns); + if (ns->CountInMemoryAreas() > kMaxInMemoryAreas) { + ns->PurgeMemory(DomStorageNamespace::PURGE_UNOPENED); + if (ns->CountInMemoryAreas() > kMaxInMemoryAreas) + ns->PurgeMemory(DomStorageNamespace::PURGE_AGGRESSIVE); + } + } area->ExtractValues(map); return true; } @@ -146,6 +155,13 @@ DomStorageArea* DomStorageHost::GetOpenArea(int connection_id) { return found->second.area_; } +DomStorageNamespace* DomStorageHost::GetNamespace(int connection_id) { + AreaMap::iterator found = connections_.find(connection_id); + if (found == connections_.end()) + return NULL; + return found->second.namespace_; +} + // NamespaceAndArea DomStorageHost::NamespaceAndArea::NamespaceAndArea() {} diff --git a/webkit/dom_storage/dom_storage_host.h b/webkit/dom_storage/dom_storage_host.h index ccdfab3..7dc6321 100644 --- a/webkit/dom_storage/dom_storage_host.h +++ b/webkit/dom_storage/dom_storage_host.h @@ -60,6 +60,7 @@ class WEBKIT_STORAGE_EXPORT DomStorageHost { typedef std::map<int, NamespaceAndArea > AreaMap; DomStorageArea* GetOpenArea(int connection_id); + DomStorageNamespace* GetNamespace(int connection_id); scoped_refptr<DomStorageContext> context_; AreaMap connections_; diff --git a/webkit/dom_storage/dom_storage_namespace.cc b/webkit/dom_storage/dom_storage_namespace.cc index 4c1cbd7..941a169 100644 --- a/webkit/dom_storage/dom_storage_namespace.cc +++ b/webkit/dom_storage/dom_storage_namespace.cc @@ -117,7 +117,7 @@ void DomStorageNamespace::DeleteSessionStorageOrigin(const GURL& origin) { CloseStorageArea(area); } -void DomStorageNamespace::PurgeMemory() { +void DomStorageNamespace::PurgeMemory(PurgeOption option) { if (directory_.empty()) return; // We can't purge w/o backing on disk. AreaMap::iterator it = areas_.begin(); @@ -136,8 +136,12 @@ void DomStorageNamespace::PurgeMemory() { continue; } - // Otherwise, we can clear caches and such. - it->second.area_->PurgeMemory(); + if (option == PURGE_AGGRESSIVE) { + // If aggressive is true, we clear caches and such + // for opened areas. + it->second.area_->PurgeMemory(); + } + ++it; } } @@ -148,6 +152,14 @@ void DomStorageNamespace::Shutdown() { it->second.area_->Shutdown(); } +unsigned int DomStorageNamespace::CountInMemoryAreas() const { + unsigned int area_count = 0; + for (AreaMap::const_iterator it = areas_.begin(); it != areas_.end(); ++it) { + if (it->second.area_->IsLoadedInMemory()) + ++area_count; + } + return area_count; +} DomStorageNamespace::AreaHolder* DomStorageNamespace::GetAreaHolder(const GURL& origin) { diff --git a/webkit/dom_storage/dom_storage_namespace.h b/webkit/dom_storage/dom_storage_namespace.h index 78ef4d7..1d20e86 100644 --- a/webkit/dom_storage/dom_storage_namespace.h +++ b/webkit/dom_storage/dom_storage_namespace.h @@ -25,6 +25,16 @@ class SessionStorageDatabase; class WEBKIT_STORAGE_EXPORT DomStorageNamespace : public base::RefCountedThreadSafe<DomStorageNamespace> { public: + // Option for PurgeMemory. + enum PurgeOption { + // Purge unopened areas only. + PURGE_UNOPENED, + + // Purge aggressively, i.e. discard cache even for areas that have + // non-zero open count. + PURGE_AGGRESSIVE, + }; + // Constructor for a LocalStorage namespace with id of 0 // and an optional backing directory on disk. DomStorageNamespace(const base::FilePath& directory, // may be empty @@ -59,9 +69,11 @@ class WEBKIT_STORAGE_EXPORT DomStorageNamespace void DeleteLocalStorageOrigin(const GURL& origin); void DeleteSessionStorageOrigin(const GURL& origin); - void PurgeMemory(); + void PurgeMemory(PurgeOption purge); void Shutdown(); + unsigned int CountInMemoryAreas() const; + private: friend class base::RefCountedThreadSafe<DomStorageNamespace>; diff --git a/webkit/dom_storage/dom_storage_types.h b/webkit/dom_storage/dom_storage_types.h index 1f663b4..e0a8509 100644 --- a/webkit/dom_storage/dom_storage_types.h +++ b/webkit/dom_storage/dom_storage_types.h @@ -32,6 +32,9 @@ const int64 kLocalStorageNamespaceId = 0; const int64 kInvalidSessionStorageNamespaceId = kLocalStorageNamespaceId; +// Start purging memory if the number of in-memory areas exceeds this. +const int64 kMaxInMemoryAreas = 100; + // Value to indicate an area that not be opened. const int kInvalidAreaId = -1; |