| Index: base/memory/discardable_memory_mac.cc
|
| diff --git a/base/memory/discardable_memory_mac.cc b/base/memory/discardable_memory_mac.cc
|
| index 1dbb6ad1fd2cf67002ddab891e5fd80bb5d6d884..7e004691389f11e7ed308ecdc29f9713075a6f4d 100644
|
| --- a/base/memory/discardable_memory_mac.cc
|
| +++ b/base/memory/discardable_memory_mac.cc
|
| @@ -7,6 +7,7 @@
|
| #include <mach/mach.h>
|
|
|
| #include "base/logging.h"
|
| +#include "base/memory/singleton.h"
|
|
|
| namespace base {
|
|
|
| @@ -17,86 +18,112 @@ namespace {
|
| // weight of ~52).
|
| const int kDiscardableMemoryTag = VM_MAKE_TAG(252);
|
|
|
| -} // namespace
|
| +class BASE_EXPORT DiscardableMemoryMac : public DiscardableMemory {
|
| + public:
|
| + DiscardableMemoryMac()
|
| + : memory_(NULL),
|
| + size_(0),
|
| + is_locked_(false) {
|
| + }
|
|
|
| -// static
|
| -bool DiscardableMemory::Supported() {
|
| - return true;
|
| -}
|
| + virtual ~DiscardableMemoryMac() {
|
| + if (memory_) {
|
| + vm_deallocate(mach_task_self(),
|
| + reinterpret_cast<vm_address_t>(memory_),
|
| + size_);
|
| + }
|
| + }
|
|
|
| -DiscardableMemory::~DiscardableMemory() {
|
| - if (memory_) {
|
| - vm_deallocate(mach_task_self(),
|
| - reinterpret_cast<vm_address_t>(memory_),
|
| - size_);
|
| + virtual bool InitializeAndLock(size_t size) OVERRIDE {
|
| + DCHECK(!memory_);
|
| + size_ = size;
|
| +
|
| + vm_address_t buffer = 0;
|
| + kern_return_t ret = vm_allocate(mach_task_self(),
|
| + &buffer,
|
| + size,
|
| + VM_FLAGS_PURGABLE |
|
| + VM_FLAGS_ANYWHERE |
|
| + kDiscardableMemoryTag);
|
| +
|
| + if (ret != KERN_SUCCESS) {
|
| + DLOG(ERROR) << "vm_allocate() failed";
|
| + return false;
|
| + }
|
| +
|
| + is_locked_ = true;
|
| + memory_ = reinterpret_cast<void*>(buffer);
|
| + return true;
|
| }
|
| -}
|
|
|
| -bool DiscardableMemory::InitializeAndLock(size_t size) {
|
| - DCHECK(!memory_);
|
| - size_ = size;
|
| -
|
| - vm_address_t buffer = 0;
|
| - kern_return_t ret = vm_allocate(mach_task_self(),
|
| - &buffer,
|
| - size,
|
| - VM_FLAGS_PURGABLE |
|
| - VM_FLAGS_ANYWHERE |
|
| - kDiscardableMemoryTag);
|
| -
|
| - if (ret != KERN_SUCCESS) {
|
| - DLOG(ERROR) << "vm_allocate() failed";
|
| - return false;
|
| + virtual LockDiscardableMemoryStatus Lock() OVERRIDE {
|
| + DCHECK(!is_locked_);
|
| +
|
| + int state = VM_PURGABLE_NONVOLATILE;
|
| + kern_return_t ret = vm_purgable_control(
|
| + mach_task_self(),
|
| + reinterpret_cast<vm_address_t>(memory_),
|
| + VM_PURGABLE_SET_STATE,
|
| + &state);
|
| +
|
| + if (ret != KERN_SUCCESS)
|
| + return DISCARDABLE_MEMORY_FAILED;
|
| +
|
| + is_locked_ = true;
|
| + return state & VM_PURGABLE_EMPTY ? DISCARDABLE_MEMORY_PURGED
|
| + : DISCARDABLE_MEMORY_SUCCESS;
|
| }
|
|
|
| - is_locked_ = true;
|
| - memory_ = reinterpret_cast<void*>(buffer);
|
| - return true;
|
| -}
|
| + virtual void Unlock() OVERRIDE {
|
| + DCHECK(is_locked_);
|
|
|
| -LockDiscardableMemoryStatus DiscardableMemory::Lock() {
|
| - DCHECK(!is_locked_);
|
| + int state = VM_PURGABLE_VOLATILE | VM_VOLATILE_GROUP_DEFAULT;
|
| + kern_return_t ret = vm_purgable_control(
|
| + mach_task_self(),
|
| + reinterpret_cast<vm_address_t>(memory_),
|
| + VM_PURGABLE_SET_STATE,
|
| + &state);
|
|
|
| - int state = VM_PURGABLE_NONVOLATILE;
|
| - kern_return_t ret = vm_purgable_control(
|
| - mach_task_self(),
|
| - reinterpret_cast<vm_address_t>(memory_),
|
| - VM_PURGABLE_SET_STATE,
|
| - &state);
|
| + if (ret != KERN_SUCCESS)
|
| + DLOG(ERROR) << "Failed to unlock memory.";
|
|
|
| - if (ret != KERN_SUCCESS)
|
| - return DISCARDABLE_MEMORY_FAILED;
|
| + is_locked_ = false;
|
| + }
|
|
|
| - is_locked_ = true;
|
| - return state & VM_PURGABLE_EMPTY ? DISCARDABLE_MEMORY_PURGED
|
| - : DISCARDABLE_MEMORY_SUCCESS;
|
| -}
|
| + virtual void* Memory() OVERRIDE {
|
| + return memory_;
|
| + }
|
|
|
| -void DiscardableMemory::Unlock() {
|
| - DCHECK(is_locked_);
|
| + private:
|
| + void* memory_;
|
| + size_t size_;
|
| + bool is_locked_;
|
|
|
| - int state = VM_PURGABLE_VOLATILE | VM_VOLATILE_GROUP_DEFAULT;
|
| - kern_return_t ret = vm_purgable_control(
|
| - mach_task_self(),
|
| - reinterpret_cast<vm_address_t>(memory_),
|
| - VM_PURGABLE_SET_STATE,
|
| - &state);
|
| + DISALLOW_COPY_AND_ASSIGN(DiscardableMemoryMac);
|
| +};
|
|
|
| - if (ret != KERN_SUCCESS)
|
| - DLOG(ERROR) << "Failed to unlock memory.";
|
| +class BASE_EXPORT DiscardableMemoryProviderMac
|
| + : public DiscardableMemoryProvider {
|
| + public:
|
| + virtual DiscardableMemory* CreateDiscardableMemory() OVERRIDE {
|
| + return new DiscardableMemoryMac;
|
| + }
|
|
|
| - is_locked_ = false;
|
| -}
|
| + virtual bool PurgeForTestingSupported() const OVERRIDE {
|
| + return true;
|
| + }
|
|
|
| -// static
|
| -bool DiscardableMemory::PurgeForTestingSupported() {
|
| - return true;
|
| -}
|
| + virtual void PurgeForTesting() OVERRIDE {
|
| + int state = 0;
|
| + vm_purgable_control(mach_task_self(), 0, VM_PURGABLE_PURGE_ALL, &state);
|
| + }
|
| +};
|
| +
|
| +} // namespace
|
|
|
| // static
|
| -void DiscardableMemory::PurgeForTesting() {
|
| - int state = 0;
|
| - vm_purgable_control(mach_task_self(), 0, VM_PURGABLE_PURGE_ALL, &state);
|
| +DiscardableMemoryProvider* DiscardableMemoryProvider::GetInstance() {
|
| + base::Singleton<DiscardableMemoryProviderMac>::GetInstance();
|
| }
|
|
|
| } // namespace base
|
|
|