Chromium Code Reviews| Index: base/memory/discardable_memory_mac.cc |
| diff --git a/base/memory/discardable_memory_mac.cc b/base/memory/discardable_memory_mac.cc |
| index 8cd5905c904deb8392f6bef67399484e0dd78e75..31241aed692ebf39d783114cad91e70810ac0c7d 100644 |
| --- a/base/memory/discardable_memory_mac.cc |
| +++ b/base/memory/discardable_memory_mac.cc |
| @@ -5,11 +5,13 @@ |
| #include "base/memory/discardable_memory.h" |
| #include <mach/mach.h> |
| -#include <sys/mman.h> |
| +#include <mach/mach_vm.h> |
| #include "base/basictypes.h" |
| #include "base/compiler_specific.h" |
| #include "base/logging.h" |
| +#include "base/mac/mach_logging.h" |
| +#include "base/mac/scoped_mach_vm.h" |
| #include "base/memory/discardable_memory_emulated.h" |
| #include "base/memory/discardable_memory_malloc.h" |
| #include "base/memory/scoped_ptr.h" |
| @@ -25,39 +27,44 @@ const int kDiscardableMemoryTag = VM_MAKE_TAG(252); |
| class DiscardableMemoryMac : public DiscardableMemory { |
| public: |
| explicit DiscardableMemoryMac(size_t size) |
| - : buffer_(0), |
| + : memory_(0, 0), |
| size_(size) { |
| } |
| bool Initialize() { |
| - kern_return_t ret = vm_allocate(mach_task_self(), |
| - &buffer_, |
| - size_, |
| - VM_FLAGS_PURGABLE | |
| - VM_FLAGS_ANYWHERE | |
| - kDiscardableMemoryTag); |
| + DCHECK_EQ(memory_.size(), 0u); |
| + mach_vm_address_t address = 0; |
| + kern_return_t ret = mach_vm_allocate(mach_task_self(), |
| + &address, |
| + size_, |
| + VM_FLAGS_PURGABLE | |
| + VM_FLAGS_ANYWHERE | |
| + kDiscardableMemoryTag); |
| if (ret != KERN_SUCCESS) { |
| - DLOG(ERROR) << "vm_allocate() failed"; |
| + MACH_DLOG(ERROR, ret) << "mach_vm_allocate"; |
| return false; |
| } |
| + memory_.reset(address, mach_vm_round_page(size_)); |
|
Robert Sesek
2014/05/09 20:40:01
You don't want to round the size in the initialize
|
| + |
| return true; |
| } |
| virtual ~DiscardableMemoryMac() { |
| - if (buffer_) |
| - vm_deallocate(mach_task_self(), buffer_, size_); |
| } |
| virtual DiscardableMemoryLockStatus Lock() OVERRIDE { |
| - DCHECK_EQ(0, mprotect(reinterpret_cast<void*>(buffer_), |
| - size_, |
| - PROT_READ | PROT_WRITE)); |
| + kern_return_t ret; |
| + MACH_DCHECK((ret = mach_vm_protect(mach_task_self(), |
| + memory_.address(), |
| + memory_.size(), |
| + FALSE, |
| + VM_PROT_DEFAULT)) == KERN_SUCCESS, ret); |
| int state = VM_PURGABLE_NONVOLATILE; |
| - kern_return_t ret = vm_purgable_control(mach_task_self(), |
| - buffer_, |
| - VM_PURGABLE_SET_STATE, |
| - &state); |
| + ret = mach_vm_purgable_control(mach_task_self(), |
| + memory_.address(), |
| + VM_PURGABLE_SET_STATE, |
| + &state); |
| if (ret != KERN_SUCCESS) |
| return DISCARDABLE_MEMORY_LOCK_STATUS_FAILED; |
| @@ -67,22 +74,25 @@ class DiscardableMemoryMac : public DiscardableMemory { |
| virtual void Unlock() OVERRIDE { |
| int state = VM_PURGABLE_VOLATILE | VM_VOLATILE_GROUP_DEFAULT; |
| - kern_return_t ret = vm_purgable_control(mach_task_self(), |
| - buffer_, |
| - VM_PURGABLE_SET_STATE, |
| - &state); |
| - DCHECK_EQ(0, mprotect(reinterpret_cast<void*>(buffer_), size_, PROT_NONE)); |
| - if (ret != KERN_SUCCESS) |
| - DLOG(ERROR) << "Failed to unlock memory."; |
| + kern_return_t ret = mach_vm_purgable_control(mach_task_self(), |
| + memory_.address(), |
| + VM_PURGABLE_SET_STATE, |
| + &state); |
| + MACH_DLOG_IF(ERROR, ret != KERN_SUCCESS, ret) << "mach_vm_purgable_control"; |
| + MACH_DCHECK((ret = mach_vm_protect(mach_task_self(), |
| + memory_.address(), |
| + memory_.size(), |
| + FALSE, |
| + VM_PROT_NONE)) == KERN_SUCCESS, ret); |
| } |
| virtual void* Memory() const OVERRIDE { |
| - return reinterpret_cast<void*>(buffer_); |
| + return reinterpret_cast<void*>(memory_.address()); |
| } |
| private: |
| - vm_address_t buffer_; |
| - const size_t size_; |
| + mac::ScopedMachVM memory_; |
| + size_t size_; |
| DISALLOW_COPY_AND_ASSIGN(DiscardableMemoryMac); |
| }; |
| @@ -149,7 +159,7 @@ scoped_ptr<DiscardableMemory> DiscardableMemory::CreateLockedMemoryWithType( |
| // static |
| void DiscardableMemory::PurgeForTesting() { |
| int state = 0; |
| - vm_purgable_control(mach_task_self(), 0, VM_PURGABLE_PURGE_ALL, &state); |
| + mach_vm_purgable_control(mach_task_self(), 0, VM_PURGABLE_PURGE_ALL, &state); |
| internal::DiscardableMemoryEmulated::PurgeForTesting(); |
| } |