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

Side by Side Diff: content/common/host_discardable_shared_memory_manager.cc

Issue 1009413002: Revert "base: Implement browser process support for discardable memory." (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 9 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
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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 "content/common/host_discardable_shared_memory_manager.h" 5 #include "content/common/host_discardable_shared_memory_manager.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 8
9 #include "base/callback.h" 9 #include "base/callback.h"
10 #include "base/debug/crash_logging.h" 10 #include "base/debug/crash_logging.h"
11 #include "base/lazy_instance.h" 11 #include "base/lazy_instance.h"
12 #include "base/numerics/safe_math.h" 12 #include "base/numerics/safe_math.h"
13 #include "base/profiler/scoped_tracker.h" 13 #include "base/profiler/scoped_tracker.h"
14 #include "base/strings/string_number_conversions.h" 14 #include "base/strings/string_number_conversions.h"
15 #include "base/sys_info.h" 15 #include "base/sys_info.h"
16 #include "base/trace_event/trace_event.h" 16 #include "base/trace_event/trace_event.h"
17 17
18 namespace content { 18 namespace content {
19 namespace { 19 namespace {
20 20
21 class DiscardableMemoryShmemChunkImpl
22 : public base::DiscardableMemoryShmemChunk {
23 public:
24 explicit DiscardableMemoryShmemChunkImpl(
25 scoped_ptr<base::DiscardableSharedMemory> shared_memory)
26 : shared_memory_(shared_memory.Pass()), is_locked_(true) {}
27 ~DiscardableMemoryShmemChunkImpl() override {
28 if (is_locked_)
29 shared_memory_->Unlock(0, 0);
30 shared_memory_->Purge(base::Time::Now());
31 }
32
33 // Overridden from base::DiscardableMemoryShmemChunk:
34 bool Lock() override {
35 DCHECK(!is_locked_);
36
37 if (shared_memory_->Lock(0, 0) != base::DiscardableSharedMemory::SUCCESS)
38 return false;
39
40 is_locked_ = true;
41 return true;
42 }
43 void Unlock() override {
44 DCHECK(is_locked_);
45
46 shared_memory_->Unlock(0, 0);
47 is_locked_ = false;
48 }
49 void* Memory() const override {
50 DCHECK(is_locked_);
51 return shared_memory_->memory();
52 }
53
54 private:
55 scoped_ptr<base::DiscardableSharedMemory> shared_memory_;
56 bool is_locked_;
57
58 DISALLOW_COPY_AND_ASSIGN(DiscardableMemoryShmemChunkImpl);
59 };
60
61 base::LazyInstance<HostDiscardableSharedMemoryManager> 21 base::LazyInstance<HostDiscardableSharedMemoryManager>
62 g_discardable_shared_memory_manager = LAZY_INSTANCE_INITIALIZER; 22 g_discardable_shared_memory_manager = LAZY_INSTANCE_INITIALIZER;
63 23
64 const int64_t kMaxDefaultMemoryLimit = 512 * 1024 * 1024; 24 const int64_t kMaxDefaultMemoryLimit = 512 * 1024 * 1024;
65 25
66 const int kEnforceMemoryPolicyDelayMs = 1000; 26 const int kEnforceMemoryPolicyDelayMs = 1000;
67 27
68 } // namespace 28 } // namespace
69 29
70 HostDiscardableSharedMemoryManager::MemorySegment::MemorySegment( 30 HostDiscardableSharedMemoryManager::MemorySegment::MemorySegment(
(...skipping 23 matching lines...) Expand all
94 } 54 }
95 55
96 HostDiscardableSharedMemoryManager* 56 HostDiscardableSharedMemoryManager*
97 HostDiscardableSharedMemoryManager::current() { 57 HostDiscardableSharedMemoryManager::current() {
98 return g_discardable_shared_memory_manager.Pointer(); 58 return g_discardable_shared_memory_manager.Pointer();
99 } 59 }
100 60
101 scoped_ptr<base::DiscardableMemoryShmemChunk> 61 scoped_ptr<base::DiscardableMemoryShmemChunk>
102 HostDiscardableSharedMemoryManager::AllocateLockedDiscardableMemory( 62 HostDiscardableSharedMemoryManager::AllocateLockedDiscardableMemory(
103 size_t size) { 63 size_t size) {
104 // Note: Use DiscardableSharedMemoryHeap for in-process allocation 64 // TODO(reveman): Need to implement this for discardable memory support in
105 // of discardable memory if the cost of each allocation is too high. 65 // the browser process.
106 base::SharedMemoryHandle handle; 66 NOTIMPLEMENTED();
107 AllocateLockedDiscardableSharedMemory(base::GetCurrentProcessHandle(), size, 67 return nullptr;
108 &handle);
109 CHECK(base::SharedMemory::IsHandleValid(handle));
110 scoped_ptr<base::DiscardableSharedMemory> memory(
111 new base::DiscardableSharedMemory(handle));
112 CHECK(memory->Map(size));
113 return make_scoped_ptr(new DiscardableMemoryShmemChunkImpl(memory.Pass()));
114 } 68 }
115 69
116 void HostDiscardableSharedMemoryManager:: 70 void HostDiscardableSharedMemoryManager::
117 AllocateLockedDiscardableSharedMemoryForChild( 71 AllocateLockedDiscardableSharedMemoryForChild(
118 base::ProcessHandle process_handle, 72 base::ProcessHandle process_handle,
119 size_t size, 73 size_t size,
120 base::SharedMemoryHandle* shared_memory_handle) { 74 base::SharedMemoryHandle* shared_memory_handle) {
121 AllocateLockedDiscardableSharedMemory(process_handle, size,
122 shared_memory_handle);
123 }
124
125 void HostDiscardableSharedMemoryManager::ProcessRemoved(
126 base::ProcessHandle process_handle) {
127 base::AutoLock lock(lock_);
128
129 size_t bytes_allocated_before_purging = bytes_allocated_;
130 for (auto& segment : segments_) {
131 // Skip segments that belong to a different process.
132 if (segment.process_handle != process_handle)
133 continue;
134
135 size_t size = segment.memory->mapped_size();
136 DCHECK_GE(bytes_allocated_, size);
137
138 // This will unmap the memory segment and drop our reference. The result
139 // is that the memory will be released to the OS if the child process is
140 // no longer referencing it.
141 // Note: We intentionally leave the segment in the vector to avoid
142 // reconstructing the heap. The element will be removed from the heap
143 // when its last usage time is older than all other segments.
144 segment.memory->Close();
145 bytes_allocated_ -= size;
146 }
147
148 if (bytes_allocated_ != bytes_allocated_before_purging)
149 BytesAllocatedChanged(bytes_allocated_);
150 }
151
152 void HostDiscardableSharedMemoryManager::SetMemoryLimit(size_t limit) {
153 base::AutoLock lock(lock_);
154
155 memory_limit_ = limit;
156 ReduceMemoryUsageUntilWithinMemoryLimit();
157 }
158
159 void HostDiscardableSharedMemoryManager::EnforceMemoryPolicy() {
160 base::AutoLock lock(lock_);
161
162 enforce_memory_policy_pending_ = false;
163 ReduceMemoryUsageUntilWithinMemoryLimit();
164 }
165
166 void HostDiscardableSharedMemoryManager::AllocateLockedDiscardableSharedMemory(
167 base::ProcessHandle process_handle,
168 size_t size,
169 base::SharedMemoryHandle* shared_memory_handle) {
170 // TODO(erikchen): Remove ScopedTracker below once http://crbug.com/466405 75 // TODO(erikchen): Remove ScopedTracker below once http://crbug.com/466405
171 // is fixed. 76 // is fixed.
172 tracked_objects::ScopedTracker tracking_profile1( 77 tracked_objects::ScopedTracker tracking_profile1(
173 FROM_HERE_WITH_EXPLICIT_FUNCTION( 78 FROM_HERE_WITH_EXPLICIT_FUNCTION(
174 "466405 AllocateLockedDiscardableSharedMemory::Start")); 79 "466405 AllocateLockedDiscardableSharedMemoryForChild::Start"));
175 base::AutoLock lock(lock_); 80 base::AutoLock lock(lock_);
176 81
177 // Memory usage must be reduced to prevent the addition of |size| from 82 // Memory usage must be reduced to prevent the addition of |size| from
178 // taking usage above the limit. Usage should be reduced to 0 in cases 83 // taking usage above the limit. Usage should be reduced to 0 in cases
179 // where |size| is greater than the limit. 84 // where |size| is greater than the limit.
180 size_t limit = 0; 85 size_t limit = 0;
181 // Note: the actual mapped size can be larger than requested and cause 86 // Note: the actual mapped size can be larger than requested and cause
182 // |bytes_allocated_| to temporarily be larger than |memory_limit_|. The 87 // |bytes_allocated_| to temporarily be larger than |memory_limit_|. The
183 // error is minimized by incrementing |bytes_allocated_| with the actual 88 // error is minimized by incrementing |bytes_allocated_| with the actual
184 // mapped size rather than |size| below. 89 // mapped size rather than |size| below.
185 if (size < memory_limit_) 90 if (size < memory_limit_)
186 limit = memory_limit_ - size; 91 limit = memory_limit_ - size;
187 92
188 // TODO(erikchen): Remove ScopedTracker below once http://crbug.com/466405 93 // TODO(erikchen): Remove ScopedTracker below once http://crbug.com/466405
189 // is fixed. 94 // is fixed.
190 tracked_objects::ScopedTracker tracking_profile2( 95 tracked_objects::ScopedTracker tracking_profile2(
191 FROM_HERE_WITH_EXPLICIT_FUNCTION( 96 FROM_HERE_WITH_EXPLICIT_FUNCTION(
192 "466405 AllocateLockedDiscardableSharedMemory::ReduceMemoryUsage")); 97 "466405 "
98 "AllocateLockedDiscardableSharedMemoryForChild::ReduceMemoryUsage"));
193 if (bytes_allocated_ > limit) 99 if (bytes_allocated_ > limit)
194 ReduceMemoryUsageUntilWithinLimit(limit); 100 ReduceMemoryUsageUntilWithinLimit(limit);
195 101
196 // TODO(erikchen): Remove ScopedTracker below once http://crbug.com/466405 102 // TODO(erikchen): Remove ScopedTracker below once http://crbug.com/466405
197 // is fixed. 103 // is fixed.
198 tracked_objects::ScopedTracker tracking_profile3( 104 tracked_objects::ScopedTracker tracking_profile3(
199 FROM_HERE_WITH_EXPLICIT_FUNCTION( 105 FROM_HERE_WITH_EXPLICIT_FUNCTION(
200 "466405 AllocateLockedDiscardableSharedMemory::NewMemory")); 106 "466405 AllocateLockedDiscardableSharedMemoryForChild::NewMemory"));
201 linked_ptr<base::DiscardableSharedMemory> memory( 107 linked_ptr<base::DiscardableSharedMemory> memory(
202 new base::DiscardableSharedMemory); 108 new base::DiscardableSharedMemory);
203 if (!memory->CreateAndMap(size)) { 109 if (!memory->CreateAndMap(size)) {
204 *shared_memory_handle = base::SharedMemory::NULLHandle(); 110 *shared_memory_handle = base::SharedMemory::NULLHandle();
205 return; 111 return;
206 } 112 }
207 113
208 // TODO(erikchen): Remove ScopedTracker below once http://crbug.com/466405 114 // TODO(erikchen): Remove ScopedTracker below once http://crbug.com/466405
209 // is fixed. 115 // is fixed.
210 tracked_objects::ScopedTracker tracking_profile4( 116 tracked_objects::ScopedTracker tracking_profile4(
211 FROM_HERE_WITH_EXPLICIT_FUNCTION( 117 FROM_HERE_WITH_EXPLICIT_FUNCTION(
212 "466405 AllocateLockedDiscardableSharedMemory::ShareToProcess")); 118 "466405 "
119 "AllocateLockedDiscardableSharedMemoryForChild::ShareToProcess"));
213 if (!memory->ShareToProcess(process_handle, shared_memory_handle)) { 120 if (!memory->ShareToProcess(process_handle, shared_memory_handle)) {
214 LOG(ERROR) << "Cannot share discardable memory segment"; 121 LOG(ERROR) << "Cannot share discardable memory segment";
215 *shared_memory_handle = base::SharedMemory::NULLHandle(); 122 *shared_memory_handle = base::SharedMemory::NULLHandle();
216 return; 123 return;
217 } 124 }
218 125
219 base::CheckedNumeric<size_t> checked_bytes_allocated = bytes_allocated_; 126 base::CheckedNumeric<size_t> checked_bytes_allocated = bytes_allocated_;
220 checked_bytes_allocated += memory->mapped_size(); 127 checked_bytes_allocated += memory->mapped_size();
221 if (!checked_bytes_allocated.IsValid()) { 128 if (!checked_bytes_allocated.IsValid()) {
222 *shared_memory_handle = base::SharedMemory::NULLHandle(); 129 *shared_memory_handle = base::SharedMemory::NULLHandle();
223 return; 130 return;
224 } 131 }
225 132
226 // TODO(erikchen): Remove ScopedTracker below once http://crbug.com/466405 133 // TODO(erikchen): Remove ScopedTracker below once http://crbug.com/466405
227 // is fixed. 134 // is fixed.
228 tracked_objects::ScopedTracker tracking_profile5( 135 tracked_objects::ScopedTracker tracking_profile5(
229 FROM_HERE_WITH_EXPLICIT_FUNCTION( 136 FROM_HERE_WITH_EXPLICIT_FUNCTION(
230 "466405 " 137 "466405 "
231 "AllocateLockedDiscardableSharedMemory::BytesAllocatedChanged")); 138 "AllocateLockedDiscardableSharedMemoryForChild::"
139 "BytesAllocatedChanged"));
232 bytes_allocated_ = checked_bytes_allocated.ValueOrDie(); 140 bytes_allocated_ = checked_bytes_allocated.ValueOrDie();
233 BytesAllocatedChanged(bytes_allocated_); 141 BytesAllocatedChanged(bytes_allocated_);
234 142
235 segments_.push_back(MemorySegment(memory, process_handle)); 143 segments_.push_back(MemorySegment(memory, process_handle));
236 std::push_heap(segments_.begin(), segments_.end(), CompareMemoryUsageTime); 144 std::push_heap(segments_.begin(), segments_.end(), CompareMemoryUsageTime);
237 145
238 // TODO(erikchen): Remove ScopedTracker below once http://crbug.com/466405 146 // TODO(erikchen): Remove ScopedTracker below once http://crbug.com/466405
239 // is fixed. 147 // is fixed.
240 tracked_objects::ScopedTracker tracking_profile6( 148 tracked_objects::ScopedTracker tracking_profile6(
241 FROM_HERE_WITH_EXPLICIT_FUNCTION( 149 FROM_HERE_WITH_EXPLICIT_FUNCTION(
242 "466405 " 150 "466405 "
243 "AllocateLockedDiscardableSharedMemory::" 151 "AllocateLockedDiscardableSharedMemoryForChild::"
244 "ScheduleEnforceMemoryPolicy")); 152 "ScheduleEnforceMemoryPolicy"));
245 if (bytes_allocated_ > memory_limit_) 153 if (bytes_allocated_ > memory_limit_)
246 ScheduleEnforceMemoryPolicy(); 154 ScheduleEnforceMemoryPolicy();
247 } 155 }
248 156
157 void HostDiscardableSharedMemoryManager::ProcessRemoved(
158 base::ProcessHandle process_handle) {
159 base::AutoLock lock(lock_);
160
161 size_t bytes_allocated_before_purging = bytes_allocated_;
162 for (auto& segment : segments_) {
163 // Skip segments that belong to a different process.
164 if (segment.process_handle != process_handle)
165 continue;
166
167 size_t size = segment.memory->mapped_size();
168 DCHECK_GE(bytes_allocated_, size);
169
170 // This will unmap the memory segment and drop our reference. The result
171 // is that the memory will be released to the OS if the child process is
172 // no longer referencing it.
173 // Note: We intentionally leave the segment in the vector to avoid
174 // reconstructing the heap. The element will be removed from the heap
175 // when its last usage time is older than all other segments.
176 segment.memory->Close();
177 bytes_allocated_ -= size;
178 }
179
180 if (bytes_allocated_ != bytes_allocated_before_purging)
181 BytesAllocatedChanged(bytes_allocated_);
182 }
183
184 void HostDiscardableSharedMemoryManager::SetMemoryLimit(size_t limit) {
185 base::AutoLock lock(lock_);
186
187 memory_limit_ = limit;
188 ReduceMemoryUsageUntilWithinMemoryLimit();
189 }
190
191 void HostDiscardableSharedMemoryManager::EnforceMemoryPolicy() {
192 base::AutoLock lock(lock_);
193
194 enforce_memory_policy_pending_ = false;
195 ReduceMemoryUsageUntilWithinMemoryLimit();
196 }
197
249 void HostDiscardableSharedMemoryManager::OnMemoryPressure( 198 void HostDiscardableSharedMemoryManager::OnMemoryPressure(
250 base::MemoryPressureListener::MemoryPressureLevel memory_pressure_level) { 199 base::MemoryPressureListener::MemoryPressureLevel memory_pressure_level) {
251 base::AutoLock lock(lock_); 200 base::AutoLock lock(lock_);
252 201
253 switch (memory_pressure_level) { 202 switch (memory_pressure_level) {
254 case base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE: 203 case base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE:
255 break; 204 break;
256 case base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE: 205 case base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE:
257 // Purge memory until usage is within half of |memory_limit_|. 206 // Purge memory until usage is within half of |memory_limit_|.
258 ReduceMemoryUsageUntilWithinLimit(memory_limit_ / 2); 207 ReduceMemoryUsageUntilWithinLimit(memory_limit_ / 2);
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
343 292
344 enforce_memory_policy_pending_ = true; 293 enforce_memory_policy_pending_ = true;
345 base::MessageLoop::current()->PostDelayedTask( 294 base::MessageLoop::current()->PostDelayedTask(
346 FROM_HERE, 295 FROM_HERE,
347 base::Bind(&HostDiscardableSharedMemoryManager::EnforceMemoryPolicy, 296 base::Bind(&HostDiscardableSharedMemoryManager::EnforceMemoryPolicy,
348 weak_ptr_factory_.GetWeakPtr()), 297 weak_ptr_factory_.GetWeakPtr()),
349 base::TimeDelta::FromMilliseconds(kEnforceMemoryPolicyDelayMs)); 298 base::TimeDelta::FromMilliseconds(kEnforceMemoryPolicyDelayMs));
350 } 299 }
351 300
352 } // namespace content 301 } // namespace content
OLDNEW
« no previous file with comments | « content/common/host_discardable_shared_memory_manager.h ('k') | content/renderer/render_thread_impl.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698