| 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 "base/memory/discardable_memory_manager.h" | 5 #include "base/memory/discardable_memory_manager.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/containers/hash_tables.h" | 8 #include "base/containers/hash_tables.h" |
| 9 #include "base/containers/mru_cache.h" | 9 #include "base/containers/mru_cache.h" |
| 10 #include "base/debug/crash_logging.h" | 10 #include "base/debug/crash_logging.h" |
| (...skipping 17 matching lines...) Expand all Loading... |
| 28 bytes_to_keep_under_moderate_pressure), | 28 bytes_to_keep_under_moderate_pressure), |
| 29 hard_memory_limit_expiration_time_(hard_memory_limit_expiration_time) { | 29 hard_memory_limit_expiration_time_(hard_memory_limit_expiration_time) { |
| 30 BytesAllocatedChanged(bytes_allocated_); | 30 BytesAllocatedChanged(bytes_allocated_); |
| 31 } | 31 } |
| 32 | 32 |
| 33 DiscardableMemoryManager::~DiscardableMemoryManager() { | 33 DiscardableMemoryManager::~DiscardableMemoryManager() { |
| 34 DCHECK(allocations_.empty()); | 34 DCHECK(allocations_.empty()); |
| 35 DCHECK_EQ(0u, bytes_allocated_); | 35 DCHECK_EQ(0u, bytes_allocated_); |
| 36 } | 36 } |
| 37 | 37 |
| 38 void DiscardableMemoryManager::RegisterMemoryPressureListener() { | |
| 39 AutoLock lock(lock_); | |
| 40 DCHECK(base::MessageLoop::current()); | |
| 41 DCHECK(!memory_pressure_listener_); | |
| 42 memory_pressure_listener_.reset(new MemoryPressureListener(base::Bind( | |
| 43 &DiscardableMemoryManager::OnMemoryPressure, Unretained(this)))); | |
| 44 } | |
| 45 | |
| 46 void DiscardableMemoryManager::UnregisterMemoryPressureListener() { | |
| 47 AutoLock lock(lock_); | |
| 48 DCHECK(memory_pressure_listener_); | |
| 49 memory_pressure_listener_.reset(); | |
| 50 } | |
| 51 | |
| 52 void DiscardableMemoryManager::SetMemoryLimit(size_t bytes) { | 38 void DiscardableMemoryManager::SetMemoryLimit(size_t bytes) { |
| 53 AutoLock lock(lock_); | 39 AutoLock lock(lock_); |
| 54 memory_limit_ = bytes; | 40 memory_limit_ = bytes; |
| 55 PurgeIfNotUsedSinceTimestampUntilUsageIsWithinLimitWithLockAcquired( | 41 PurgeIfNotUsedSinceTimestampUntilUsageIsWithinLimitWithLockAcquired( |
| 56 Now(), memory_limit_); | 42 Now(), memory_limit_); |
| 57 } | 43 } |
| 58 | 44 |
| 59 void DiscardableMemoryManager::SetSoftMemoryLimit(size_t bytes) { | 45 void DiscardableMemoryManager::SetSoftMemoryLimit(size_t bytes) { |
| 60 AutoLock lock(lock_); | 46 AutoLock lock(lock_); |
| 61 soft_memory_limit_ = bytes; | 47 soft_memory_limit_ = bytes; |
| 62 } | 48 } |
| 63 | 49 |
| 64 void DiscardableMemoryManager::SetBytesToKeepUnderModeratePressure( | 50 void DiscardableMemoryManager::SetBytesToKeepUnderModeratePressure( |
| 65 size_t bytes) { | 51 size_t bytes) { |
| 66 AutoLock lock(lock_); | 52 AutoLock lock(lock_); |
| 67 bytes_to_keep_under_moderate_pressure_ = bytes; | 53 bytes_to_keep_under_moderate_pressure_ = bytes; |
| 68 } | 54 } |
| 69 | 55 |
| 70 void DiscardableMemoryManager::SetHardMemoryLimitExpirationTime( | 56 void DiscardableMemoryManager::SetHardMemoryLimitExpirationTime( |
| 71 TimeDelta hard_memory_limit_expiration_time) { | 57 TimeDelta hard_memory_limit_expiration_time) { |
| 72 AutoLock lock(lock_); | 58 AutoLock lock(lock_); |
| 73 hard_memory_limit_expiration_time_ = hard_memory_limit_expiration_time; | 59 hard_memory_limit_expiration_time_ = hard_memory_limit_expiration_time; |
| 74 } | 60 } |
| 75 | 61 |
| 76 bool DiscardableMemoryManager::ReduceMemoryUsage() { | 62 bool DiscardableMemoryManager::ReduceMemoryUsage() { |
| 77 return PurgeIfNotUsedSinceHardLimitCutoffUntilWithinSoftMemoryLimit(); | 63 return PurgeIfNotUsedSinceHardLimitCutoffUntilWithinSoftMemoryLimit(); |
| 78 } | 64 } |
| 79 | 65 |
| 66 void |
| 67 DiscardableMemoryManager::ReduceMemoryUsageUntilWithinModeratePressureLimit() { |
| 68 PurgeUntilWithinBytesToKeepUnderModeratePressure(); |
| 69 } |
| 70 |
| 80 void DiscardableMemoryManager::Register(Allocation* allocation, size_t bytes) { | 71 void DiscardableMemoryManager::Register(Allocation* allocation, size_t bytes) { |
| 81 AutoLock lock(lock_); | 72 AutoLock lock(lock_); |
| 82 // A registered memory listener is currently required. This DCHECK can be | |
| 83 // moved or removed if we decide that it's useful to relax this condition. | |
| 84 // TODO(reveman): Enable this DCHECK when skia and blink are able to | |
| 85 // register memory pressure listeners. crbug.com/333907 | |
| 86 // DCHECK(memory_pressure_listener_); | |
| 87 DCHECK(allocations_.Peek(allocation) == allocations_.end()); | 73 DCHECK(allocations_.Peek(allocation) == allocations_.end()); |
| 88 allocations_.Put(allocation, AllocationInfo(bytes)); | 74 allocations_.Put(allocation, AllocationInfo(bytes)); |
| 89 } | 75 } |
| 90 | 76 |
| 91 void DiscardableMemoryManager::Unregister(Allocation* allocation) { | 77 void DiscardableMemoryManager::Unregister(Allocation* allocation) { |
| 92 AutoLock lock(lock_); | 78 AutoLock lock(lock_); |
| 93 AllocationMap::iterator it = allocations_.Peek(allocation); | 79 AllocationMap::iterator it = allocations_.Peek(allocation); |
| 94 DCHECK(it != allocations_.end()); | 80 DCHECK(it != allocations_.end()); |
| 95 const AllocationInfo& info = it->second; | 81 const AllocationInfo& info = it->second; |
| 96 | 82 |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 175 AutoLock lock(lock_); | 161 AutoLock lock(lock_); |
| 176 AllocationMap::const_iterator it = allocations_.Peek(allocation); | 162 AllocationMap::const_iterator it = allocations_.Peek(allocation); |
| 177 return it != allocations_.end() && it->second.purgable; | 163 return it != allocations_.end() && it->second.purgable; |
| 178 } | 164 } |
| 179 | 165 |
| 180 size_t DiscardableMemoryManager::GetBytesAllocatedForTest() const { | 166 size_t DiscardableMemoryManager::GetBytesAllocatedForTest() const { |
| 181 AutoLock lock(lock_); | 167 AutoLock lock(lock_); |
| 182 return bytes_allocated_; | 168 return bytes_allocated_; |
| 183 } | 169 } |
| 184 | 170 |
| 185 void DiscardableMemoryManager::OnMemoryPressure( | |
| 186 MemoryPressureListener::MemoryPressureLevel pressure_level) { | |
| 187 switch (pressure_level) { | |
| 188 case MemoryPressureListener::MEMORY_PRESSURE_MODERATE: | |
| 189 PurgeUntilWithinBytesToKeepUnderModeratePressure(); | |
| 190 return; | |
| 191 case MemoryPressureListener::MEMORY_PRESSURE_CRITICAL: | |
| 192 PurgeAll(); | |
| 193 return; | |
| 194 } | |
| 195 | |
| 196 NOTREACHED(); | |
| 197 } | |
| 198 | |
| 199 void | 171 void |
| 200 DiscardableMemoryManager::PurgeUntilWithinBytesToKeepUnderModeratePressure() { | 172 DiscardableMemoryManager::PurgeUntilWithinBytesToKeepUnderModeratePressure() { |
| 201 AutoLock lock(lock_); | 173 AutoLock lock(lock_); |
| 202 | 174 |
| 203 PurgeIfNotUsedSinceTimestampUntilUsageIsWithinLimitWithLockAcquired( | 175 PurgeIfNotUsedSinceTimestampUntilUsageIsWithinLimitWithLockAcquired( |
| 204 Now(), bytes_to_keep_under_moderate_pressure_); | 176 Now(), bytes_to_keep_under_moderate_pressure_); |
| 205 } | 177 } |
| 206 | 178 |
| 207 bool DiscardableMemoryManager:: | 179 bool DiscardableMemoryManager:: |
| 208 PurgeIfNotUsedSinceHardLimitCutoffUntilWithinSoftMemoryLimit() { | 180 PurgeIfNotUsedSinceHardLimitCutoffUntilWithinSoftMemoryLimit() { |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 254 base::debug::SetCrashKeyValue(kDiscardableMemoryUsageKey, | 226 base::debug::SetCrashKeyValue(kDiscardableMemoryUsageKey, |
| 255 Uint64ToString(new_bytes_allocated)); | 227 Uint64ToString(new_bytes_allocated)); |
| 256 } | 228 } |
| 257 | 229 |
| 258 TimeTicks DiscardableMemoryManager::Now() const { | 230 TimeTicks DiscardableMemoryManager::Now() const { |
| 259 return TimeTicks::Now(); | 231 return TimeTicks::Now(); |
| 260 } | 232 } |
| 261 | 233 |
| 262 } // namespace internal | 234 } // namespace internal |
| 263 } // namespace base | 235 } // namespace base |
| OLD | NEW |