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(); |
} |