1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "base/memory/discardable_memory.h"
9 #include "base/logging.h"
15 // The VM subsystem allows tagging of memory and 240-255 is reserved for
16 // application use (see mach/vm_statistics.h). Pick 252 (after chromium's atomic
18 const int kDiscardableMemoryTag
= VM_MAKE_TAG(252);
23 bool DiscardableMemory::Supported() {
27 DiscardableMemory::~DiscardableMemory() {
29 vm_deallocate(mach_task_self(),
30 reinterpret_cast<vm_address_t
>(memory_
),
35 bool DiscardableMemory::InitializeAndLock(size_t size
) {
39 vm_address_t buffer
= 0;
40 kern_return_t ret
= vm_allocate(mach_task_self(),
45 kDiscardableMemoryTag
);
47 if (ret
!= KERN_SUCCESS
) {
48 DLOG(ERROR
) << "vm_allocate() failed";
53 memory_
= reinterpret_cast<void*>(buffer
);
57 LockDiscardableMemoryStatus
DiscardableMemory::Lock() {
60 int state
= VM_PURGABLE_NONVOLATILE
;
61 kern_return_t ret
= vm_purgable_control(
63 reinterpret_cast<vm_address_t
>(memory_
),
64 VM_PURGABLE_SET_STATE
,
67 if (ret
!= KERN_SUCCESS
)
68 return DISCARDABLE_MEMORY_FAILED
;
71 return state
& VM_PURGABLE_EMPTY
? DISCARDABLE_MEMORY_PURGED
72 : DISCARDABLE_MEMORY_SUCCESS
;
75 void DiscardableMemory::Unlock() {
78 int state
= VM_PURGABLE_VOLATILE
| VM_VOLATILE_GROUP_DEFAULT
;
79 kern_return_t ret
= vm_purgable_control(
81 reinterpret_cast<vm_address_t
>(memory_
),
82 VM_PURGABLE_SET_STATE
,
85 if (ret
!= KERN_SUCCESS
)
86 DLOG(ERROR
) << "Failed to unlock memory.";
92 bool DiscardableMemory::PurgeForTestingSupported() {
97 void DiscardableMemory::PurgeForTesting() {
99 vm_purgable_control(mach_task_self(), 0, VM_PURGABLE_PURGE_ALL
, &state
);