Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1045)

Side by Side Diff: base/memory/discardable_memory_mac.cc

Issue 15650016: [Not for review] Discardable memory emulation (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: . Created 7 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "base/memory/discardable_memory.h" 5 #include "base/memory/discardable_memory.h"
6 6
7 #include <mach/mach.h> 7 #include <mach/mach.h>
8 8
9 #include "base/logging.h" 9 #include "base/logging.h"
10 #include "base/memory/singleton.h"
10 11
11 namespace base { 12 namespace base {
12 13
13 namespace { 14 namespace {
14 15
15 // The VM subsystem allows tagging of memory and 240-255 is reserved for 16 // 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 // application use (see mach/vm_statistics.h). Pick 252 (after chromium's atomic
17 // weight of ~52). 18 // weight of ~52).
18 const int kDiscardableMemoryTag = VM_MAKE_TAG(252); 19 const int kDiscardableMemoryTag = VM_MAKE_TAG(252);
19 20
21 class BASE_EXPORT DiscardableMemoryMac : public DiscardableMemory {
22 public:
23 DiscardableMemoryMac()
24 : memory_(NULL),
25 size_(0),
26 is_locked_(false) {
27 }
28
29 virtual ~DiscardableMemoryMac() {
30 if (memory_) {
31 vm_deallocate(mach_task_self(),
32 reinterpret_cast<vm_address_t>(memory_),
33 size_);
34 }
35 }
36
37 virtual bool InitializeAndLock(size_t size) OVERRIDE {
38 DCHECK(!memory_);
39 size_ = size;
40
41 vm_address_t buffer = 0;
42 kern_return_t ret = vm_allocate(mach_task_self(),
43 &buffer,
44 size,
45 VM_FLAGS_PURGABLE |
46 VM_FLAGS_ANYWHERE |
47 kDiscardableMemoryTag);
48
49 if (ret != KERN_SUCCESS) {
50 DLOG(ERROR) << "vm_allocate() failed";
51 return false;
52 }
53
54 is_locked_ = true;
55 memory_ = reinterpret_cast<void*>(buffer);
56 return true;
57 }
58
59 virtual LockDiscardableMemoryStatus Lock() OVERRIDE {
60 DCHECK(!is_locked_);
61
62 int state = VM_PURGABLE_NONVOLATILE;
63 kern_return_t ret = vm_purgable_control(
64 mach_task_self(),
65 reinterpret_cast<vm_address_t>(memory_),
66 VM_PURGABLE_SET_STATE,
67 &state);
68
69 if (ret != KERN_SUCCESS)
70 return DISCARDABLE_MEMORY_FAILED;
71
72 is_locked_ = true;
73 return state & VM_PURGABLE_EMPTY ? DISCARDABLE_MEMORY_PURGED
74 : DISCARDABLE_MEMORY_SUCCESS;
75 }
76
77 virtual void Unlock() OVERRIDE {
78 DCHECK(is_locked_);
79
80 int state = VM_PURGABLE_VOLATILE | VM_VOLATILE_GROUP_DEFAULT;
81 kern_return_t ret = vm_purgable_control(
82 mach_task_self(),
83 reinterpret_cast<vm_address_t>(memory_),
84 VM_PURGABLE_SET_STATE,
85 &state);
86
87 if (ret != KERN_SUCCESS)
88 DLOG(ERROR) << "Failed to unlock memory.";
89
90 is_locked_ = false;
91 }
92
93 virtual void* Memory() OVERRIDE {
94 return memory_;
95 }
96
97 private:
98 void* memory_;
99 size_t size_;
100 bool is_locked_;
101
102 DISALLOW_COPY_AND_ASSIGN(DiscardableMemoryMac);
103 };
104
105 class BASE_EXPORT DiscardableMemoryProviderMac
106 : public DiscardableMemoryProvider {
107 public:
108 virtual DiscardableMemory* CreateDiscardableMemory() OVERRIDE {
109 return new DiscardableMemoryMac;
110 }
111
112 virtual bool PurgeForTestingSupported() const OVERRIDE {
113 return true;
114 }
115
116 virtual void PurgeForTesting() OVERRIDE {
117 int state = 0;
118 vm_purgable_control(mach_task_self(), 0, VM_PURGABLE_PURGE_ALL, &state);
119 }
120 };
121
20 } // namespace 122 } // namespace
21 123
22 // static 124 // static
23 bool DiscardableMemory::Supported() { 125 DiscardableMemoryProvider* DiscardableMemoryProvider::GetInstance() {
24 return true; 126 base::Singleton<DiscardableMemoryProviderMac>::GetInstance();
25 }
26
27 DiscardableMemory::~DiscardableMemory() {
28 if (memory_) {
29 vm_deallocate(mach_task_self(),
30 reinterpret_cast<vm_address_t>(memory_),
31 size_);
32 }
33 }
34
35 bool DiscardableMemory::InitializeAndLock(size_t size) {
36 DCHECK(!memory_);
37 size_ = size;
38
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);
46
47 if (ret != KERN_SUCCESS) {
48 DLOG(ERROR) << "vm_allocate() failed";
49 return false;
50 }
51
52 is_locked_ = true;
53 memory_ = reinterpret_cast<void*>(buffer);
54 return true;
55 }
56
57 LockDiscardableMemoryStatus DiscardableMemory::Lock() {
58 DCHECK(!is_locked_);
59
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);
66
67 if (ret != KERN_SUCCESS)
68 return DISCARDABLE_MEMORY_FAILED;
69
70 is_locked_ = true;
71 return state & VM_PURGABLE_EMPTY ? DISCARDABLE_MEMORY_PURGED
72 : DISCARDABLE_MEMORY_SUCCESS;
73 }
74
75 void DiscardableMemory::Unlock() {
76 DCHECK(is_locked_);
77
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);
84
85 if (ret != KERN_SUCCESS)
86 DLOG(ERROR) << "Failed to unlock memory.";
87
88 is_locked_ = false;
89 }
90
91 // static
92 bool DiscardableMemory::PurgeForTestingSupported() {
93 return true;
94 }
95
96 // static
97 void DiscardableMemory::PurgeForTesting() {
98 int state = 0;
99 vm_purgable_control(mach_task_self(), 0, VM_PURGABLE_PURGE_ALL, &state);
100 } 127 }
101 128
102 } // namespace base 129 } // namespace base
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698