| OLD | NEW |
| 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/child/child_discardable_shared_memory_manager.h" | 5 #include "content/child/child_discardable_shared_memory_manager.h" |
| 6 | 6 |
| 7 #include "base/debug/crash_logging.h" | 7 #include "base/debug/crash_logging.h" |
| 8 #include "base/memory/discardable_memory.h" |
| 8 #include "base/memory/discardable_shared_memory.h" | 9 #include "base/memory/discardable_shared_memory.h" |
| 9 #include "base/metrics/histogram.h" | 10 #include "base/metrics/histogram.h" |
| 10 #include "base/process/process_metrics.h" | 11 #include "base/process/process_metrics.h" |
| 11 #include "base/strings/string_number_conversions.h" | 12 #include "base/strings/string_number_conversions.h" |
| 12 #include "base/trace_event/trace_event.h" | 13 #include "base/trace_event/trace_event.h" |
| 13 #include "content/common/child_process_messages.h" | 14 #include "content/common/child_process_messages.h" |
| 14 | 15 |
| 15 namespace content { | 16 namespace content { |
| 16 namespace { | 17 namespace { |
| 17 | 18 |
| 18 // Default allocation size. | 19 // Default allocation size. |
| 19 #if defined(OS_ANDROID) | 20 #if defined(OS_ANDROID) |
| 20 // Larger allocation size on Android to avoid reaching the FD-limit. | 21 // Larger allocation size on Android to avoid reaching the FD-limit. |
| 21 const size_t kAllocationSize = 32 * 1024 * 1024; | 22 const size_t kAllocationSize = 32 * 1024 * 1024; |
| 22 #else | 23 #else |
| 23 const size_t kAllocationSize = 4 * 1024 * 1024; | 24 const size_t kAllocationSize = 4 * 1024 * 1024; |
| 24 #endif | 25 #endif |
| 25 | 26 |
| 26 class DiscardableMemoryShmemChunkImpl | 27 class DiscardableMemoryImpl : public base::DiscardableMemory { |
| 27 : public base::DiscardableMemoryShmemChunk { | |
| 28 public: | 28 public: |
| 29 DiscardableMemoryShmemChunkImpl( | 29 DiscardableMemoryImpl(ChildDiscardableSharedMemoryManager* manager, |
| 30 ChildDiscardableSharedMemoryManager* manager, | 30 scoped_ptr<DiscardableSharedMemoryHeap::Span> span) |
| 31 scoped_ptr<DiscardableSharedMemoryHeap::Span> span) | |
| 32 : manager_(manager), span_(span.Pass()) {} | 31 : manager_(manager), span_(span.Pass()) {} |
| 33 ~DiscardableMemoryShmemChunkImpl() override { | 32 ~DiscardableMemoryImpl() override { manager_->ReleaseSpan(span_.Pass()); } |
| 34 manager_->ReleaseSpan(span_.Pass()); | |
| 35 } | |
| 36 | 33 |
| 37 // Overridden from DiscardableMemoryShmemChunk: | 34 // Overridden from base::DiscardableMemory: |
| 38 bool Lock() override { return manager_->LockSpan(span_.get()); } | 35 bool Lock() override { return manager_->LockSpan(span_.get()); } |
| 39 void Unlock() override { manager_->UnlockSpan(span_.get()); } | 36 void Unlock() override { manager_->UnlockSpan(span_.get()); } |
| 40 void* Memory() const override { | 37 void* Memory() const override { |
| 41 return reinterpret_cast<void*>(span_->start() * base::GetPageSize()); | 38 return reinterpret_cast<void*>(span_->start() * base::GetPageSize()); |
| 42 } | 39 } |
| 43 | 40 |
| 44 private: | 41 private: |
| 45 ChildDiscardableSharedMemoryManager* manager_; | 42 ChildDiscardableSharedMemoryManager* const manager_; |
| 46 scoped_ptr<DiscardableSharedMemoryHeap::Span> span_; | 43 scoped_ptr<DiscardableSharedMemoryHeap::Span> span_; |
| 47 | 44 |
| 48 DISALLOW_COPY_AND_ASSIGN(DiscardableMemoryShmemChunkImpl); | 45 DISALLOW_COPY_AND_ASSIGN(DiscardableMemoryImpl); |
| 49 }; | 46 }; |
| 50 | 47 |
| 51 } // namespace | 48 } // namespace |
| 52 | 49 |
| 53 ChildDiscardableSharedMemoryManager::ChildDiscardableSharedMemoryManager( | 50 ChildDiscardableSharedMemoryManager::ChildDiscardableSharedMemoryManager( |
| 54 ThreadSafeSender* sender) | 51 ThreadSafeSender* sender) |
| 55 : heap_(base::GetPageSize()), sender_(sender) { | 52 : heap_(base::GetPageSize()), sender_(sender) { |
| 56 } | 53 } |
| 57 | 54 |
| 58 ChildDiscardableSharedMemoryManager::~ChildDiscardableSharedMemoryManager() { | 55 ChildDiscardableSharedMemoryManager::~ChildDiscardableSharedMemoryManager() { |
| 59 // TODO(reveman): Determine if this DCHECK can be enabled. crbug.com/430533 | 56 // TODO(reveman): Determine if this DCHECK can be enabled. crbug.com/430533 |
| 60 // DCHECK_EQ(heap_.GetSize(), heap_.GetSizeOfFreeLists()); | 57 // DCHECK_EQ(heap_.GetSize(), heap_.GetSizeOfFreeLists()); |
| 61 if (heap_.GetSize()) | 58 if (heap_.GetSize()) |
| 62 MemoryUsageChanged(0, 0); | 59 MemoryUsageChanged(0, 0); |
| 63 } | 60 } |
| 64 | 61 |
| 65 scoped_ptr<base::DiscardableMemoryShmemChunk> | 62 scoped_ptr<base::DiscardableMemory> |
| 66 ChildDiscardableSharedMemoryManager::AllocateLockedDiscardableMemory( | 63 ChildDiscardableSharedMemoryManager::AllocateLockedDiscardableMemory( |
| 67 size_t size) { | 64 size_t size) { |
| 68 base::AutoLock lock(lock_); | 65 base::AutoLock lock(lock_); |
| 69 | 66 |
| 70 DCHECK_NE(size, 0u); | 67 DCHECK_NE(size, 0u); |
| 71 | 68 |
| 72 UMA_HISTOGRAM_CUSTOM_COUNTS("Memory.DiscardableAllocationSize", | 69 UMA_HISTOGRAM_CUSTOM_COUNTS("Memory.DiscardableAllocationSize", |
| 73 size / 1024, // In KB | 70 size / 1024, // In KB |
| 74 1, | 71 1, |
| 75 4 * 1024 * 1024, // 4 GB | 72 4 * 1024 * 1024, // 4 GB |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 109 // We have to release purged memory before |free_span| can be destroyed. | 106 // We have to release purged memory before |free_span| can be destroyed. |
| 110 heap_.ReleasePurgedMemory(); | 107 heap_.ReleasePurgedMemory(); |
| 111 DCHECK(!free_span->shared_memory()); | 108 DCHECK(!free_span->shared_memory()); |
| 112 continue; | 109 continue; |
| 113 } | 110 } |
| 114 | 111 |
| 115 // Memory usage is guaranteed to have changed after having removed | 112 // Memory usage is guaranteed to have changed after having removed |
| 116 // at least one span from the free lists. | 113 // at least one span from the free lists. |
| 117 MemoryUsageChanged(heap_.GetSize(), heap_.GetSizeOfFreeLists()); | 114 MemoryUsageChanged(heap_.GetSize(), heap_.GetSizeOfFreeLists()); |
| 118 | 115 |
| 119 return make_scoped_ptr( | 116 return make_scoped_ptr(new DiscardableMemoryImpl(this, free_span.Pass())); |
| 120 new DiscardableMemoryShmemChunkImpl(this, free_span.Pass())); | |
| 121 } | 117 } |
| 122 | 118 |
| 123 // Release purged memory to free up the address space before we attempt to | 119 // Release purged memory to free up the address space before we attempt to |
| 124 // allocate more memory. | 120 // allocate more memory. |
| 125 heap_.ReleasePurgedMemory(); | 121 heap_.ReleasePurgedMemory(); |
| 126 | 122 |
| 127 // Make sure crash keys are up to date in case allocation fails. | 123 // Make sure crash keys are up to date in case allocation fails. |
| 128 if (heap_.GetSize() != heap_size_prior_to_releasing_purged_memory) | 124 if (heap_.GetSize() != heap_size_prior_to_releasing_purged_memory) |
| 129 MemoryUsageChanged(heap_.GetSize(), heap_.GetSizeOfFreeLists()); | 125 MemoryUsageChanged(heap_.GetSize(), heap_.GetSizeOfFreeLists()); |
| 130 | 126 |
| (...skipping 15 matching lines...) Expand all Loading... |
| 146 heap_.Split(new_span.get(), pages); | 142 heap_.Split(new_span.get(), pages); |
| 147 leftover->shared_memory()->Unlock( | 143 leftover->shared_memory()->Unlock( |
| 148 leftover->start() * base::GetPageSize() - | 144 leftover->start() * base::GetPageSize() - |
| 149 reinterpret_cast<size_t>(leftover->shared_memory()->memory()), | 145 reinterpret_cast<size_t>(leftover->shared_memory()->memory()), |
| 150 leftover->length() * base::GetPageSize()); | 146 leftover->length() * base::GetPageSize()); |
| 151 heap_.MergeIntoFreeLists(leftover.Pass()); | 147 heap_.MergeIntoFreeLists(leftover.Pass()); |
| 152 } | 148 } |
| 153 | 149 |
| 154 MemoryUsageChanged(heap_.GetSize(), heap_.GetSizeOfFreeLists()); | 150 MemoryUsageChanged(heap_.GetSize(), heap_.GetSizeOfFreeLists()); |
| 155 | 151 |
| 156 return make_scoped_ptr( | 152 return make_scoped_ptr(new DiscardableMemoryImpl(this, new_span.Pass())); |
| 157 new DiscardableMemoryShmemChunkImpl(this, new_span.Pass())); | |
| 158 } | 153 } |
| 159 | 154 |
| 160 void ChildDiscardableSharedMemoryManager::ReleaseFreeMemory() { | 155 void ChildDiscardableSharedMemoryManager::ReleaseFreeMemory() { |
| 161 base::AutoLock lock(lock_); | 156 base::AutoLock lock(lock_); |
| 162 | 157 |
| 163 size_t heap_size_prior_to_releasing_memory = heap_.GetSize(); | 158 size_t heap_size_prior_to_releasing_memory = heap_.GetSize(); |
| 164 | 159 |
| 165 // Release both purged and free memory. | 160 // Release both purged and free memory. |
| 166 heap_.ReleasePurgedMemory(); | 161 heap_.ReleasePurgedMemory(); |
| 167 heap_.ReleaseFreeMemory(); | 162 heap_.ReleaseFreeMemory(); |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 250 static const char kDiscardableMemoryUsageKey[] = "dm-usage"; | 245 static const char kDiscardableMemoryUsageKey[] = "dm-usage"; |
| 251 base::debug::SetCrashKeyValue(kDiscardableMemoryUsageKey, | 246 base::debug::SetCrashKeyValue(kDiscardableMemoryUsageKey, |
| 252 base::Uint64ToString(new_bytes_total)); | 247 base::Uint64ToString(new_bytes_total)); |
| 253 | 248 |
| 254 static const char kDiscardableMemoryUsageFreeKey[] = "dm-usage-free"; | 249 static const char kDiscardableMemoryUsageFreeKey[] = "dm-usage-free"; |
| 255 base::debug::SetCrashKeyValue(kDiscardableMemoryUsageFreeKey, | 250 base::debug::SetCrashKeyValue(kDiscardableMemoryUsageFreeKey, |
| 256 base::Uint64ToString(new_bytes_free)); | 251 base::Uint64ToString(new_bytes_free)); |
| 257 } | 252 } |
| 258 | 253 |
| 259 } // namespace content | 254 } // namespace content |
| OLD | NEW |