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

Unified Diff: content/common/host_discardable_shared_memory_manager.cc

Issue 1004043002: Re-land: base: Implement browser process support for discardable memory. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: set allocator instance for blink tests 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 side-by-side diff with in-line comments
Download patch
« 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 »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: content/common/host_discardable_shared_memory_manager.cc
diff --git a/content/common/host_discardable_shared_memory_manager.cc b/content/common/host_discardable_shared_memory_manager.cc
index e150fc63dcf00a11da58b0b4ae912f8a94ada2e5..3d2be9d22c1e32bcad935e4cc8694b60e1282df7 100644
--- a/content/common/host_discardable_shared_memory_manager.cc
+++ b/content/common/host_discardable_shared_memory_manager.cc
@@ -18,6 +18,46 @@
namespace content {
namespace {
+class DiscardableMemoryShmemChunkImpl
+ : public base::DiscardableMemoryShmemChunk {
+ public:
+ explicit DiscardableMemoryShmemChunkImpl(
+ scoped_ptr<base::DiscardableSharedMemory> shared_memory)
+ : shared_memory_(shared_memory.Pass()), is_locked_(true) {}
+ ~DiscardableMemoryShmemChunkImpl() override {
+ if (is_locked_)
+ shared_memory_->Unlock(0, 0);
+ shared_memory_->Purge(base::Time::Now());
+ }
+
+ // Overridden from base::DiscardableMemoryShmemChunk:
+ bool Lock() override {
+ DCHECK(!is_locked_);
+
+ if (shared_memory_->Lock(0, 0) != base::DiscardableSharedMemory::SUCCESS)
+ return false;
+
+ is_locked_ = true;
+ return true;
+ }
+ void Unlock() override {
+ DCHECK(is_locked_);
+
+ shared_memory_->Unlock(0, 0);
+ is_locked_ = false;
+ }
+ void* Memory() const override {
+ DCHECK(is_locked_);
+ return shared_memory_->memory();
+ }
+
+ private:
+ scoped_ptr<base::DiscardableSharedMemory> shared_memory_;
+ bool is_locked_;
+
+ DISALLOW_COPY_AND_ASSIGN(DiscardableMemoryShmemChunkImpl);
+};
+
base::LazyInstance<HostDiscardableSharedMemoryManager>
g_discardable_shared_memory_manager = LAZY_INSTANCE_INITIALIZER;
@@ -61,10 +101,16 @@ HostDiscardableSharedMemoryManager::current() {
scoped_ptr<base::DiscardableMemoryShmemChunk>
HostDiscardableSharedMemoryManager::AllocateLockedDiscardableMemory(
size_t size) {
- // TODO(reveman): Need to implement this for discardable memory support in
- // the browser process.
- NOTIMPLEMENTED();
- return nullptr;
+ // Note: Use DiscardableSharedMemoryHeap for in-process allocation
+ // of discardable memory if the cost of each allocation is too high.
+ base::SharedMemoryHandle handle;
+ AllocateLockedDiscardableSharedMemory(base::GetCurrentProcessHandle(), size,
+ &handle);
+ CHECK(base::SharedMemory::IsHandleValid(handle));
+ scoped_ptr<base::DiscardableSharedMemory> memory(
+ new base::DiscardableSharedMemory(handle));
+ CHECK(memory->Map(size));
+ return make_scoped_ptr(new DiscardableMemoryShmemChunkImpl(memory.Pass()));
}
void HostDiscardableSharedMemoryManager::
@@ -72,11 +118,60 @@ void HostDiscardableSharedMemoryManager::
base::ProcessHandle process_handle,
size_t size,
base::SharedMemoryHandle* shared_memory_handle) {
+ AllocateLockedDiscardableSharedMemory(process_handle, size,
+ shared_memory_handle);
+}
+
+void HostDiscardableSharedMemoryManager::ProcessRemoved(
+ base::ProcessHandle process_handle) {
+ base::AutoLock lock(lock_);
+
+ size_t bytes_allocated_before_purging = bytes_allocated_;
+ for (auto& segment : segments_) {
+ // Skip segments that belong to a different process.
+ if (segment.process_handle != process_handle)
+ continue;
+
+ size_t size = segment.memory->mapped_size();
+ DCHECK_GE(bytes_allocated_, size);
+
+ // This will unmap the memory segment and drop our reference. The result
+ // is that the memory will be released to the OS if the child process is
+ // no longer referencing it.
+ // Note: We intentionally leave the segment in the vector to avoid
+ // reconstructing the heap. The element will be removed from the heap
+ // when its last usage time is older than all other segments.
+ segment.memory->Close();
+ bytes_allocated_ -= size;
+ }
+
+ if (bytes_allocated_ != bytes_allocated_before_purging)
+ BytesAllocatedChanged(bytes_allocated_);
+}
+
+void HostDiscardableSharedMemoryManager::SetMemoryLimit(size_t limit) {
+ base::AutoLock lock(lock_);
+
+ memory_limit_ = limit;
+ ReduceMemoryUsageUntilWithinMemoryLimit();
+}
+
+void HostDiscardableSharedMemoryManager::EnforceMemoryPolicy() {
+ base::AutoLock lock(lock_);
+
+ enforce_memory_policy_pending_ = false;
+ ReduceMemoryUsageUntilWithinMemoryLimit();
+}
+
+void HostDiscardableSharedMemoryManager::AllocateLockedDiscardableSharedMemory(
+ base::ProcessHandle process_handle,
+ size_t size,
+ base::SharedMemoryHandle* shared_memory_handle) {
// TODO(erikchen): Remove ScopedTracker below once http://crbug.com/466405
// is fixed.
tracked_objects::ScopedTracker tracking_profile1(
FROM_HERE_WITH_EXPLICIT_FUNCTION(
- "466405 AllocateLockedDiscardableSharedMemoryForChild::Start"));
+ "466405 AllocateLockedDiscardableSharedMemory::Start"));
base::AutoLock lock(lock_);
// Memory usage must be reduced to prevent the addition of |size| from
@@ -94,8 +189,7 @@ void HostDiscardableSharedMemoryManager::
// is fixed.
tracked_objects::ScopedTracker tracking_profile2(
FROM_HERE_WITH_EXPLICIT_FUNCTION(
- "466405 "
- "AllocateLockedDiscardableSharedMemoryForChild::ReduceMemoryUsage"));
+ "466405 AllocateLockedDiscardableSharedMemory::ReduceMemoryUsage"));
if (bytes_allocated_ > limit)
ReduceMemoryUsageUntilWithinLimit(limit);
@@ -103,7 +197,7 @@ void HostDiscardableSharedMemoryManager::
// is fixed.
tracked_objects::ScopedTracker tracking_profile3(
FROM_HERE_WITH_EXPLICIT_FUNCTION(
- "466405 AllocateLockedDiscardableSharedMemoryForChild::NewMemory"));
+ "466405 AllocateLockedDiscardableSharedMemory::NewMemory"));
linked_ptr<base::DiscardableSharedMemory> memory(
new base::DiscardableSharedMemory);
if (!memory->CreateAndMap(size)) {
@@ -115,8 +209,7 @@ void HostDiscardableSharedMemoryManager::
// is fixed.
tracked_objects::ScopedTracker tracking_profile4(
FROM_HERE_WITH_EXPLICIT_FUNCTION(
- "466405 "
- "AllocateLockedDiscardableSharedMemoryForChild::ShareToProcess"));
+ "466405 AllocateLockedDiscardableSharedMemory::ShareToProcess"));
if (!memory->ShareToProcess(process_handle, shared_memory_handle)) {
LOG(ERROR) << "Cannot share discardable memory segment";
*shared_memory_handle = base::SharedMemory::NULLHandle();
@@ -135,8 +228,7 @@ void HostDiscardableSharedMemoryManager::
tracked_objects::ScopedTracker tracking_profile5(
FROM_HERE_WITH_EXPLICIT_FUNCTION(
"466405 "
- "AllocateLockedDiscardableSharedMemoryForChild::"
- "BytesAllocatedChanged"));
+ "AllocateLockedDiscardableSharedMemory::BytesAllocatedChanged"));
bytes_allocated_ = checked_bytes_allocated.ValueOrDie();
BytesAllocatedChanged(bytes_allocated_);
@@ -148,53 +240,12 @@ void HostDiscardableSharedMemoryManager::
tracked_objects::ScopedTracker tracking_profile6(
FROM_HERE_WITH_EXPLICIT_FUNCTION(
"466405 "
- "AllocateLockedDiscardableSharedMemoryForChild::"
+ "AllocateLockedDiscardableSharedMemory::"
"ScheduleEnforceMemoryPolicy"));
if (bytes_allocated_ > memory_limit_)
ScheduleEnforceMemoryPolicy();
}
-void HostDiscardableSharedMemoryManager::ProcessRemoved(
- base::ProcessHandle process_handle) {
- base::AutoLock lock(lock_);
-
- size_t bytes_allocated_before_purging = bytes_allocated_;
- for (auto& segment : segments_) {
- // Skip segments that belong to a different process.
- if (segment.process_handle != process_handle)
- continue;
-
- size_t size = segment.memory->mapped_size();
- DCHECK_GE(bytes_allocated_, size);
-
- // This will unmap the memory segment and drop our reference. The result
- // is that the memory will be released to the OS if the child process is
- // no longer referencing it.
- // Note: We intentionally leave the segment in the vector to avoid
- // reconstructing the heap. The element will be removed from the heap
- // when its last usage time is older than all other segments.
- segment.memory->Close();
- bytes_allocated_ -= size;
- }
-
- if (bytes_allocated_ != bytes_allocated_before_purging)
- BytesAllocatedChanged(bytes_allocated_);
-}
-
-void HostDiscardableSharedMemoryManager::SetMemoryLimit(size_t limit) {
- base::AutoLock lock(lock_);
-
- memory_limit_ = limit;
- ReduceMemoryUsageUntilWithinMemoryLimit();
-}
-
-void HostDiscardableSharedMemoryManager::EnforceMemoryPolicy() {
- base::AutoLock lock(lock_);
-
- enforce_memory_policy_pending_ = false;
- ReduceMemoryUsageUntilWithinMemoryLimit();
-}
-
void HostDiscardableSharedMemoryManager::OnMemoryPressure(
base::MemoryPressureListener::MemoryPressureLevel memory_pressure_level) {
base::AutoLock lock(lock_);
« 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