Skip to content

Commit

Permalink
Add discardable memory emulation for non-android/mac platforms
Browse files Browse the repository at this point in the history
Adds support for emulated discardable memory. The memory is managed by a
provider which listens for memory pressure notifications from the platform.

Currently, only android pushes these notifications, but in future patches, we
will apply pressure on other platforms in certain situations (e.g., when a tab
gets backgrounded).

BUG=237681

Review URL: https://codereview.chromium.org/17106004

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@231845 0039d316-1c4b-4281-b951-d872f2087c98
  • Loading branch information
vollick@chromium.org committed Oct 30, 2013
1 parent 1bc20da commit cef6c76
Show file tree
Hide file tree
Showing 15 changed files with 880 additions and 66 deletions.
6 changes: 6 additions & 0 deletions base/base.gyp
Original file line number Diff line number Diff line change
Expand Up @@ -530,6 +530,7 @@
'md5_unittest.cc',
'memory/aligned_memory_unittest.cc',
'memory/discardable_memory_unittest.cc',
'memory/discardable_memory_provider_unittest.cc',
'memory/linked_ptr_unittest.cc',
'memory/ref_counted_memory_unittest.cc',
'memory/ref_counted_unittest.cc',
Expand Down Expand Up @@ -830,6 +831,11 @@
'third_party/nspr/nspr.gyp:nspr',
],
}],
['<(native_discardable_memory)==1', {
'sources!': [
'memory/discardable_memory_provider_unittest.cc',
],
}],
], # conditions
'target_conditions': [
['OS == "ios" and _toolset != "host"', {
Expand Down
12 changes: 11 additions & 1 deletion base/base.gypi
Original file line number Diff line number Diff line change
Expand Up @@ -283,10 +283,12 @@
'mac/sdk_forward_declarations.h',
'memory/aligned_memory.cc',
'memory/aligned_memory.h',
'memory/discardable_memory.cc',
'memory/discardable_memory.h',
'memory/discardable_memory_android.cc',
'memory/discardable_memory_emulated.cc',
'memory/discardable_memory_mac.cc',
'memory/discardable_memory_provider.cc',
'memory/discardable_memory_provider.h',
'memory/linked_ptr.h',
'memory/manual_constructor.h',
'memory/memory_pressure_listener.cc',
Expand Down Expand Up @@ -847,6 +849,14 @@
'sources/': [ ['exclude', '^win/'] ],
},
],
['<(native_discardable_memory)==1', {
'sources!': [
'memory/discardable_memory_emulated.cc',
'memory/discardable_memory_provider.cc',
'memory/discardable_memory_provider.h',
],
},
],
['OS != "android" or >(nacl_untrusted_build)==1', {
'sources/': [ ['exclude', '^android/'] ],
},
Expand Down
9 changes: 7 additions & 2 deletions base/containers/mru_cache.h
Original file line number Diff line number Diff line change
Expand Up @@ -123,15 +123,20 @@ class MRUCacheBase {

// Retrieves the payload associated with a given key and returns it via
// result without affecting the ordering (unlike Get).
//
// TODO(brettw) We may want a const version of this function in the future.
iterator Peek(const KeyType& key) {
typename KeyIndex::const_iterator index_iter = index_.find(key);
if (index_iter == index_.end())
return end();
return index_iter->second;
}

const_iterator Peek(const KeyType& key) const {
typename KeyIndex::const_iterator index_iter = index_.find(key);
if (index_iter == index_.end())
return end();
return index_iter->second;
}

// Erases the item referenced by the given iterator. An iterator to the item
// following it will be returned. The iterator must be valid.
iterator Erase(iterator pos) {
Expand Down
39 changes: 0 additions & 39 deletions base/memory/discardable_memory.cc

This file was deleted.

8 changes: 6 additions & 2 deletions base/memory/discardable_memory.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,9 @@ enum LockDiscardableMemoryStatus {
// - Because of memory alignment, the amount of memory allocated can be
// larger than the requested memory size. It is not very efficient for
// small allocations.
// - A discardable memory instance is not thread safe. It is the
// responsibility of users of discardable memory to ensure there are no
// races.
//
// References:
// - Linux: http://lwn.net/Articles/452035/
Expand All @@ -48,8 +51,9 @@ class BASE_EXPORT DiscardableMemory {
public:
virtual ~DiscardableMemory() {}

// Returns whether the system supports discardable memory.
static bool Supported();
// Check whether the system supports discardable memory natively. Returns
// false if the support is emulated.
static bool SupportedNatively();

static scoped_ptr<DiscardableMemory> CreateLockedMemory(size_t size);

Expand Down
2 changes: 1 addition & 1 deletion base/memory/discardable_memory_android.cc
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ class DiscardableMemoryAndroid : public DiscardableMemory {
} // namespace

// static
bool DiscardableMemory::Supported() {
bool DiscardableMemory::SupportedNatively() {
return true;
}

Expand Down
85 changes: 85 additions & 0 deletions base/memory/discardable_memory_emulated.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "base/memory/discardable_memory.h"

#include "base/memory/discardable_memory_provider.h"

using base::internal::DiscardableMemoryProvider;

namespace base {
namespace {

class DiscardableMemoryEmulated : public DiscardableMemory {
public:
explicit DiscardableMemoryEmulated(size_t size) : is_locked_(false) {
DiscardableMemoryProvider::GetInstance()->Register(this, size);
}

virtual ~DiscardableMemoryEmulated() {
if (is_locked_)
Unlock();
DiscardableMemoryProvider::GetInstance()->Unregister(this);
}

// DiscardableMemory:
virtual LockDiscardableMemoryStatus Lock() OVERRIDE {
DCHECK(!is_locked_);

bool purged = false;
memory_ = DiscardableMemoryProvider::GetInstance()->Acquire(this, &purged);
if (!memory_)
return DISCARDABLE_MEMORY_FAILED;

is_locked_ = true;
return purged ? DISCARDABLE_MEMORY_PURGED : DISCARDABLE_MEMORY_SUCCESS;
}

virtual void Unlock() OVERRIDE {
DCHECK(is_locked_);
DiscardableMemoryProvider::GetInstance()->Release(this, memory_.Pass());
is_locked_ = false;
}

virtual void* Memory() const OVERRIDE {
DCHECK(memory_);
return memory_.get();
}

private:
scoped_ptr<uint8, FreeDeleter> memory_;
bool is_locked_;

DISALLOW_COPY_AND_ASSIGN(DiscardableMemoryEmulated);
};

} // namespace

// static
bool DiscardableMemory::SupportedNatively() {
return false;
}

// static
scoped_ptr<DiscardableMemory> DiscardableMemory::CreateLockedMemory(
size_t size) {
scoped_ptr<DiscardableMemory> memory(new DiscardableMemoryEmulated(size));
if (!memory)
return scoped_ptr<DiscardableMemory>();
if (memory->Lock() != DISCARDABLE_MEMORY_PURGED)
return scoped_ptr<DiscardableMemory>();
return memory.Pass();
}

// static
bool DiscardableMemory::PurgeForTestingSupported() {
return true;
}

// static
void DiscardableMemory::PurgeForTesting() {
DiscardableMemoryProvider::GetInstance()->PurgeAll();
}

} // namespace base
2 changes: 1 addition & 1 deletion base/memory/discardable_memory_mac.cc
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ class DiscardableMemoryMac : public DiscardableMemory {
} // namespace

// static
bool DiscardableMemory::Supported() {
bool DiscardableMemory::SupportedNatively() {
return true;
}

Expand Down
Loading

0 comments on commit cef6c76

Please sign in to comment.