Separate Simple Backend creation from initialization.
[chromium-blink-merge.git] / base / memory / discardable_memory_mac.cc
blob1dbb6ad1fd2cf67002ddab891e5fd80bb5d6d884
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"
7 #include <mach/mach.h>
9 #include "base/logging.h"
11 namespace base {
13 namespace {
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
17 // weight of ~52).
18 const int kDiscardableMemoryTag = VM_MAKE_TAG(252);
20 } // namespace
22 // static
23 bool DiscardableMemory::Supported() {
24 return true;
27 DiscardableMemory::~DiscardableMemory() {
28 if (memory_) {
29 vm_deallocate(mach_task_self(),
30 reinterpret_cast<vm_address_t>(memory_),
31 size_);
35 bool DiscardableMemory::InitializeAndLock(size_t size) {
36 DCHECK(!memory_);
37 size_ = size;
39 vm_address_t buffer = 0;
40 kern_return_t ret = vm_allocate(mach_task_self(),
41 &buffer,
42 size,
43 VM_FLAGS_PURGABLE |
44 VM_FLAGS_ANYWHERE |
45 kDiscardableMemoryTag);
47 if (ret != KERN_SUCCESS) {
48 DLOG(ERROR) << "vm_allocate() failed";
49 return false;
52 is_locked_ = true;
53 memory_ = reinterpret_cast<void*>(buffer);
54 return true;
57 LockDiscardableMemoryStatus DiscardableMemory::Lock() {
58 DCHECK(!is_locked_);
60 int state = VM_PURGABLE_NONVOLATILE;
61 kern_return_t ret = vm_purgable_control(
62 mach_task_self(),
63 reinterpret_cast<vm_address_t>(memory_),
64 VM_PURGABLE_SET_STATE,
65 &state);
67 if (ret != KERN_SUCCESS)
68 return DISCARDABLE_MEMORY_FAILED;
70 is_locked_ = true;
71 return state & VM_PURGABLE_EMPTY ? DISCARDABLE_MEMORY_PURGED
72 : DISCARDABLE_MEMORY_SUCCESS;
75 void DiscardableMemory::Unlock() {
76 DCHECK(is_locked_);
78 int state = VM_PURGABLE_VOLATILE | VM_VOLATILE_GROUP_DEFAULT;
79 kern_return_t ret = vm_purgable_control(
80 mach_task_self(),
81 reinterpret_cast<vm_address_t>(memory_),
82 VM_PURGABLE_SET_STATE,
83 &state);
85 if (ret != KERN_SUCCESS)
86 DLOG(ERROR) << "Failed to unlock memory.";
88 is_locked_ = false;
91 // static
92 bool DiscardableMemory::PurgeForTestingSupported() {
93 return true;
96 // static
97 void DiscardableMemory::PurgeForTesting() {
98 int state = 0;
99 vm_purgable_control(mach_task_self(), 0, VM_PURGABLE_PURGE_ALL, &state);
102 } // namespace base