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

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

Issue 24988003: Refactor DiscardableMemory for the upcoming DiscardableMemoryAllocator. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Speculative fix for Mac unit test Created 7 years, 2 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
« no previous file with comments | « base/memory/discardable_memory_android.cc ('k') | base/memory/discardable_memory_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 #include <sys/mman.h>
8 9
10 #include "base/basictypes.h"
11 #include "base/compiler_specific.h"
9 #include "base/logging.h" 12 #include "base/logging.h"
13 #include "base/memory/scoped_ptr.h"
10 14
11 namespace base { 15 namespace base {
12
13 namespace { 16 namespace {
14 17
15 // The VM subsystem allows tagging of memory and 240-255 is reserved for 18 // 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 19 // application use (see mach/vm_statistics.h). Pick 252 (after chromium's atomic
17 // weight of ~52). 20 // weight of ~52).
18 const int kDiscardableMemoryTag = VM_MAKE_TAG(252); 21 const int kDiscardableMemoryTag = VM_MAKE_TAG(252);
19 22
23 class DiscardableMemoryMac : public DiscardableMemory {
24 public:
25 DiscardableMemoryMac(void* memory, size_t size)
26 : memory_(memory),
27 size_(size) {
28 DCHECK(memory_);
29 }
30
31 virtual ~DiscardableMemoryMac() {
32 vm_deallocate(mach_task_self(),
33 reinterpret_cast<vm_address_t>(memory_),
34 size_);
35 }
36
37 virtual LockDiscardableMemoryStatus Lock() OVERRIDE {
38 DCHECK_EQ(0, mprotect(memory_, size_, PROT_READ | PROT_WRITE));
Avi (use Gerrit) 2013/10/17 15:09:38 If you're going to mprotect, do it _after_ you get
Philippe 2013/10/17 16:20:35 The memory must be touchable to let vm_purgeable_c
39 int state = VM_PURGABLE_NONVOLATILE;
40 kern_return_t ret = vm_purgable_control(
41 mach_task_self(),
42 reinterpret_cast<vm_address_t>(memory_),
43 VM_PURGABLE_SET_STATE,
44 &state);
45 if (ret != KERN_SUCCESS)
46 return DISCARDABLE_MEMORY_FAILED;
47
48 return state & VM_PURGABLE_EMPTY ? DISCARDABLE_MEMORY_PURGED
49 : DISCARDABLE_MEMORY_SUCCESS;
50 }
51
52 virtual void Unlock() OVERRIDE {
53 int state = VM_PURGABLE_VOLATILE | VM_VOLATILE_GROUP_DEFAULT;
54 kern_return_t ret = vm_purgable_control(
55 mach_task_self(),
56 reinterpret_cast<vm_address_t>(memory_),
57 VM_PURGABLE_SET_STATE,
58 &state);
59 DCHECK_EQ(0, mprotect(memory_, size_, PROT_NONE));
Avi (use Gerrit) 2013/10/17 15:09:38 Can we mprotect before we mark it as purgeable? Pu
Philippe 2013/10/17 16:20:35 See the previous patch set (patch set 7) and my co
60 if (ret != KERN_SUCCESS)
61 DLOG(ERROR) << "Failed to unlock memory.";
62 }
63
64 virtual void* Memory() const OVERRIDE {
65 return memory_;
66 }
67
68 private:
69 void* const memory_;
70 const size_t size_;
71
72 DISALLOW_COPY_AND_ASSIGN(DiscardableMemoryMac);
73 };
74
20 } // namespace 75 } // namespace
21 76
22 // static 77 // static
23 bool DiscardableMemory::Supported() { 78 bool DiscardableMemory::Supported() {
24 return true; 79 return true;
25 } 80 }
26 81
27 DiscardableMemory::~DiscardableMemory() { 82 // static
28 if (memory_) { 83 scoped_ptr<DiscardableMemory> DiscardableMemory::CreateLockedMemory(
29 vm_deallocate(mach_task_self(), 84 size_t size) {
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; 85 vm_address_t buffer = 0;
40 kern_return_t ret = vm_allocate(mach_task_self(), 86 kern_return_t ret = vm_allocate(mach_task_self(),
41 &buffer, 87 &buffer,
42 size, 88 size,
43 VM_FLAGS_PURGABLE | 89 VM_FLAGS_PURGABLE |
44 VM_FLAGS_ANYWHERE | 90 VM_FLAGS_ANYWHERE |
45 kDiscardableMemoryTag); 91 kDiscardableMemoryTag);
46
47 if (ret != KERN_SUCCESS) { 92 if (ret != KERN_SUCCESS) {
48 DLOG(ERROR) << "vm_allocate() failed"; 93 DLOG(ERROR) << "vm_allocate() failed";
49 return false; 94 return scoped_ptr<DiscardableMemory>();
50 } 95 }
51 96 return scoped_ptr<DiscardableMemory>(
52 is_locked_ = true; 97 new DiscardableMemoryMac(reinterpret_cast<void*>(buffer), size));
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 } 98 }
90 99
91 // static 100 // static
92 bool DiscardableMemory::PurgeForTestingSupported() { 101 bool DiscardableMemory::PurgeForTestingSupported() {
93 return true; 102 return true;
94 } 103 }
95 104
96 // static 105 // static
97 void DiscardableMemory::PurgeForTesting() { 106 void DiscardableMemory::PurgeForTesting() {
98 int state = 0; 107 int state = 0;
99 vm_purgable_control(mach_task_self(), 0, VM_PURGABLE_PURGE_ALL, &state); 108 vm_purgable_control(mach_task_self(), 0, VM_PURGABLE_PURGE_ALL, &state);
100 } 109 }
101 110
102 } // namespace base 111 } // namespace base
OLDNEW
« no previous file with comments | « base/memory/discardable_memory_android.cc ('k') | base/memory/discardable_memory_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698