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 |