diff options
Diffstat (limited to 'chromium/base/memory/discardable_memory_manager.cc')
-rw-r--r-- | chromium/base/memory/discardable_memory_manager.cc | 246 |
1 files changed, 0 insertions, 246 deletions
diff --git a/chromium/base/memory/discardable_memory_manager.cc b/chromium/base/memory/discardable_memory_manager.cc deleted file mode 100644 index faf583b485f..00000000000 --- a/chromium/base/memory/discardable_memory_manager.cc +++ /dev/null @@ -1,246 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "base/memory/discardable_memory_manager.h" - -#include "base/bind.h" -#include "base/containers/adapters.h" -#include "base/containers/hash_tables.h" -#include "base/containers/mru_cache.h" -#include "base/debug/crash_logging.h" -#include "base/debug/trace_event.h" -#include "base/strings/string_number_conversions.h" -#include "base/synchronization/lock.h" - -namespace base { -namespace internal { - -DiscardableMemoryManager::DiscardableMemoryManager( - size_t memory_limit, - size_t soft_memory_limit, - TimeDelta hard_memory_limit_expiration_time) - : allocations_(AllocationMap::NO_AUTO_EVICT), - bytes_allocated_(0u), - memory_limit_(memory_limit), - soft_memory_limit_(soft_memory_limit), - hard_memory_limit_expiration_time_(hard_memory_limit_expiration_time) { - BytesAllocatedChanged(bytes_allocated_); -} - -DiscardableMemoryManager::~DiscardableMemoryManager() { - DCHECK(allocations_.empty()); - DCHECK_EQ(0u, bytes_allocated_); -} - -void DiscardableMemoryManager::SetMemoryLimit(size_t bytes) { - AutoLock lock(lock_); - memory_limit_ = bytes; - PurgeIfNotUsedSinceTimestampUntilUsageIsWithinLimitWithLockAcquired( - Now(), memory_limit_); -} - -void DiscardableMemoryManager::SetSoftMemoryLimit(size_t bytes) { - AutoLock lock(lock_); - soft_memory_limit_ = bytes; -} - -void DiscardableMemoryManager::SetHardMemoryLimitExpirationTime( - TimeDelta hard_memory_limit_expiration_time) { - AutoLock lock(lock_); - hard_memory_limit_expiration_time_ = hard_memory_limit_expiration_time; -} - -void DiscardableMemoryManager::ReleaseFreeMemory() { - TRACE_EVENT0("base", "DiscardableMemoryManager::ReleaseFreeMemory"); - - AutoLock lock(lock_); - size_t bytes_allocated_before_releasing_memory = bytes_allocated_; - for (auto& entry : allocations_) { - Allocation* allocation = entry.first; - AllocationInfo* info = &entry.second; - - if (!info->purgable) - continue; - - // Skip if memory is still resident, otherwise purge and adjust - // |bytes_allocated_|. - if (allocation->IsMemoryResident()) - continue; - - size_t bytes_purgable = info->bytes; - DCHECK_LE(bytes_purgable, bytes_allocated_); - bytes_allocated_ -= bytes_purgable; - info->purgable = false; - allocation->Purge(); - } - - if (bytes_allocated_ != bytes_allocated_before_releasing_memory) - BytesAllocatedChanged(bytes_allocated_); -} - -bool DiscardableMemoryManager::ReduceMemoryUsage() { - return PurgeIfNotUsedSinceHardLimitCutoffUntilWithinSoftMemoryLimit(); -} - -void DiscardableMemoryManager::ReduceMemoryUsageUntilWithinLimit(size_t bytes) { - AutoLock lock(lock_); - PurgeIfNotUsedSinceTimestampUntilUsageIsWithinLimitWithLockAcquired(Now(), - bytes); -} - -void DiscardableMemoryManager::Register(Allocation* allocation, size_t bytes) { - AutoLock lock(lock_); - DCHECK(allocations_.Peek(allocation) == allocations_.end()); - allocations_.Put(allocation, AllocationInfo(bytes)); -} - -void DiscardableMemoryManager::Unregister(Allocation* allocation) { - AutoLock lock(lock_); - AllocationMap::iterator it = allocations_.Peek(allocation); - DCHECK(it != allocations_.end()); - const AllocationInfo& info = it->second; - - if (info.purgable) { - size_t bytes_purgable = info.bytes; - DCHECK_LE(bytes_purgable, bytes_allocated_); - bytes_allocated_ -= bytes_purgable; - BytesAllocatedChanged(bytes_allocated_); - } - allocations_.Erase(it); -} - -bool DiscardableMemoryManager::AcquireLock(Allocation* allocation, - bool* purged) { - AutoLock lock(lock_); - // Note: |allocations_| is an MRU cache, and use of |Get| here updates that - // cache. - AllocationMap::iterator it = allocations_.Get(allocation); - DCHECK(it != allocations_.end()); - AllocationInfo* info = &it->second; - - if (!info->bytes) - return false; - - TimeTicks now = Now(); - size_t bytes_required = info->purgable ? 0u : info->bytes; - - if (memory_limit_) { - size_t limit = 0; - if (bytes_required < memory_limit_) - limit = memory_limit_ - bytes_required; - - PurgeIfNotUsedSinceTimestampUntilUsageIsWithinLimitWithLockAcquired(now, - limit); - } - - // Check for overflow. - if (std::numeric_limits<size_t>::max() - bytes_required < bytes_allocated_) - return false; - - *purged = !allocation->AllocateAndAcquireLock(); - info->purgable = false; - info->last_usage = now; - if (bytes_required) { - bytes_allocated_ += bytes_required; - BytesAllocatedChanged(bytes_allocated_); - } - return true; -} - -void DiscardableMemoryManager::ReleaseLock(Allocation* allocation) { - AutoLock lock(lock_); - // Note: |allocations_| is an MRU cache, and use of |Get| here updates that - // cache. - AllocationMap::iterator it = allocations_.Get(allocation); - DCHECK(it != allocations_.end()); - AllocationInfo* info = &it->second; - - TimeTicks now = Now(); - allocation->ReleaseLock(); - info->purgable = true; - info->last_usage = now; - - PurgeIfNotUsedSinceTimestampUntilUsageIsWithinLimitWithLockAcquired( - now, memory_limit_); -} - -void DiscardableMemoryManager::PurgeAll() { - AutoLock lock(lock_); - PurgeIfNotUsedSinceTimestampUntilUsageIsWithinLimitWithLockAcquired(Now(), 0); -} - -bool DiscardableMemoryManager::IsRegisteredForTest( - Allocation* allocation) const { - AutoLock lock(lock_); - AllocationMap::const_iterator it = allocations_.Peek(allocation); - return it != allocations_.end(); -} - -bool DiscardableMemoryManager::CanBePurgedForTest( - Allocation* allocation) const { - AutoLock lock(lock_); - AllocationMap::const_iterator it = allocations_.Peek(allocation); - return it != allocations_.end() && it->second.purgable; -} - -size_t DiscardableMemoryManager::GetBytesAllocatedForTest() const { - AutoLock lock(lock_); - return bytes_allocated_; -} - -bool DiscardableMemoryManager:: - PurgeIfNotUsedSinceHardLimitCutoffUntilWithinSoftMemoryLimit() { - AutoLock lock(lock_); - - PurgeIfNotUsedSinceTimestampUntilUsageIsWithinLimitWithLockAcquired( - Now() - hard_memory_limit_expiration_time_, soft_memory_limit_); - - return bytes_allocated_ <= soft_memory_limit_; -} - -void DiscardableMemoryManager:: - PurgeIfNotUsedSinceTimestampUntilUsageIsWithinLimitWithLockAcquired( - TimeTicks timestamp, - size_t limit) { - lock_.AssertAcquired(); - - size_t bytes_allocated_before_purging = bytes_allocated_; - for (auto& entry : base::Reversed(allocations_)) { - Allocation* allocation = entry.first; - AllocationInfo* info = &entry.second; - - if (bytes_allocated_ <= limit) - break; - - bool purgable = info->purgable && info->last_usage <= timestamp; - if (!purgable) - continue; - - size_t bytes_purgable = info->bytes; - DCHECK_LE(bytes_purgable, bytes_allocated_); - bytes_allocated_ -= bytes_purgable; - info->purgable = false; - allocation->Purge(); - } - - if (bytes_allocated_ != bytes_allocated_before_purging) - BytesAllocatedChanged(bytes_allocated_); -} - -void DiscardableMemoryManager::BytesAllocatedChanged( - size_t new_bytes_allocated) const { - TRACE_COUNTER_ID1( - "base", "DiscardableMemoryUsage", this, new_bytes_allocated); - - static const char kDiscardableMemoryUsageKey[] = "dm-usage"; - base::debug::SetCrashKeyValue(kDiscardableMemoryUsageKey, - Uint64ToString(new_bytes_allocated)); -} - -TimeTicks DiscardableMemoryManager::Now() const { - return TimeTicks::Now(); -} - -} // namespace internal -} // namespace base |