X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=src%2Fbase%2Fmemory%2Fdiscardable_memory_manager.cc;h=d976da203c4a88494dfffa6e73dd167bee6c2c11;hb=490a4587e7e356282cb1453efaf36de4acc9762f;hp=49ecc484a7a6ff195f4e5cb23316eaef4625a73f;hpb=3a51af92707b9c600d06a404c9db8f07fcd50959;p=platform%2Fframework%2Fweb%2Fcrosswalk.git diff --git a/src/base/memory/discardable_memory_manager.cc b/src/base/memory/discardable_memory_manager.cc index 49ecc48..d976da2 100644 --- a/src/base/memory/discardable_memory_manager.cc +++ b/src/base/memory/discardable_memory_manager.cc @@ -17,13 +17,17 @@ namespace internal { DiscardableMemoryManager::DiscardableMemoryManager( size_t memory_limit, - size_t bytes_to_keep_under_moderate_pressure) + size_t soft_memory_limit, + size_t bytes_to_keep_under_moderate_pressure, + TimeDelta hard_memory_limit_expiration_time) : allocations_(AllocationMap::NO_AUTO_EVICT), - bytes_allocated_(0), + bytes_allocated_(0u), memory_limit_(memory_limit), + soft_memory_limit_(soft_memory_limit), bytes_to_keep_under_moderate_pressure_( - bytes_to_keep_under_moderate_pressure) { - BytesAllocatedChanged(); + bytes_to_keep_under_moderate_pressure), + hard_memory_limit_expiration_time_(hard_memory_limit_expiration_time) { + BytesAllocatedChanged(bytes_allocated_); } DiscardableMemoryManager::~DiscardableMemoryManager() { @@ -48,7 +52,13 @@ void DiscardableMemoryManager::UnregisterMemoryPressureListener() { void DiscardableMemoryManager::SetMemoryLimit(size_t bytes) { AutoLock lock(lock_); memory_limit_ = bytes; - EnforcePolicyWithLockAcquired(); + PurgeIfNotUsedSinceTimestampUntilUsageIsWithinLimitWithLockAcquired( + Now(), memory_limit_); +} + +void DiscardableMemoryManager::SetSoftMemoryLimit(size_t bytes) { + AutoLock lock(lock_); + soft_memory_limit_ = bytes; } void DiscardableMemoryManager::SetBytesToKeepUnderModeratePressure( @@ -57,6 +67,16 @@ void DiscardableMemoryManager::SetBytesToKeepUnderModeratePressure( bytes_to_keep_under_moderate_pressure_ = bytes; } +void DiscardableMemoryManager::SetHardMemoryLimitExpirationTime( + TimeDelta hard_memory_limit_expiration_time) { + AutoLock lock(lock_); + hard_memory_limit_expiration_time_ = hard_memory_limit_expiration_time; +} + +bool DiscardableMemoryManager::ReduceMemoryUsage() { + return PurgeIfNotUsedSinceHardLimitCutoffUntilWithinSoftMemoryLimit(); +} + void DiscardableMemoryManager::Register(Allocation* allocation, size_t bytes) { AutoLock lock(lock_); // A registered memory listener is currently required. This DCHECK can be @@ -78,7 +98,7 @@ void DiscardableMemoryManager::Unregister(Allocation* allocation) { size_t bytes_purgable = info.bytes; DCHECK_LE(bytes_purgable, bytes_allocated_); bytes_allocated_ -= bytes_purgable; - BytesAllocatedChanged(); + BytesAllocatedChanged(bytes_allocated_); } allocations_.Erase(it); } @@ -95,6 +115,7 @@ bool DiscardableMemoryManager::AcquireLock(Allocation* allocation, if (!info->bytes) return false; + TimeTicks now = Now(); size_t bytes_required = info->purgable ? 0u : info->bytes; if (memory_limit_) { @@ -102,7 +123,8 @@ bool DiscardableMemoryManager::AcquireLock(Allocation* allocation, if (bytes_required < memory_limit_) limit = memory_limit_ - bytes_required; - PurgeLRUWithLockAcquiredUntilUsageIsWithin(limit); + PurgeIfNotUsedSinceTimestampUntilUsageIsWithinLimitWithLockAcquired(now, + limit); } // Check for overflow. @@ -111,9 +133,10 @@ bool DiscardableMemoryManager::AcquireLock(Allocation* allocation, *purged = !allocation->AllocateAndAcquireLock(); info->purgable = false; + info->last_usage = now; if (bytes_required) { bytes_allocated_ += bytes_required; - BytesAllocatedChanged(); + BytesAllocatedChanged(bytes_allocated_); } return true; } @@ -126,14 +149,18 @@ void DiscardableMemoryManager::ReleaseLock(Allocation* allocation) { DCHECK(it != allocations_.end()); AllocationInfo* info = &it->second; + TimeTicks now = Now(); allocation->ReleaseLock(); info->purgable = true; - EnforcePolicyWithLockAcquired(); + info->last_usage = now; + + PurgeIfNotUsedSinceTimestampUntilUsageIsWithinLimitWithLockAcquired( + now, memory_limit_); } void DiscardableMemoryManager::PurgeAll() { AutoLock lock(lock_); - PurgeLRUWithLockAcquiredUntilUsageIsWithin(0); + PurgeIfNotUsedSinceTimestampUntilUsageIsWithinLimitWithLockAcquired(Now(), 0); } bool DiscardableMemoryManager::IsRegisteredForTest( @@ -159,7 +186,7 @@ void DiscardableMemoryManager::OnMemoryPressure( MemoryPressureListener::MemoryPressureLevel pressure_level) { switch (pressure_level) { case MemoryPressureListener::MEMORY_PRESSURE_MODERATE: - Purge(); + PurgeUntilWithinBytesToKeepUnderModeratePressure(); return; case MemoryPressureListener::MEMORY_PRESSURE_CRITICAL: PurgeAll(); @@ -169,21 +196,28 @@ void DiscardableMemoryManager::OnMemoryPressure( NOTREACHED(); } -void DiscardableMemoryManager::Purge() { +void +DiscardableMemoryManager::PurgeUntilWithinBytesToKeepUnderModeratePressure() { AutoLock lock(lock_); - PurgeLRUWithLockAcquiredUntilUsageIsWithin( - bytes_to_keep_under_moderate_pressure_); + PurgeIfNotUsedSinceTimestampUntilUsageIsWithinLimitWithLockAcquired( + Now(), bytes_to_keep_under_moderate_pressure_); } -void DiscardableMemoryManager::PurgeLRUWithLockAcquiredUntilUsageIsWithin( - size_t limit) { - TRACE_EVENT1( - "base", - "DiscardableMemoryManager::PurgeLRUWithLockAcquiredUntilUsageIsWithin", - "limit", - limit); +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_; @@ -195,7 +229,9 @@ void DiscardableMemoryManager::PurgeLRUWithLockAcquiredUntilUsageIsWithin( if (bytes_allocated_ <= limit) break; - if (!info->purgable) + + bool purgable = info->purgable && info->last_usage <= timestamp; + if (!purgable) continue; size_t bytes_purgable = info->bytes; @@ -206,19 +242,21 @@ void DiscardableMemoryManager::PurgeLRUWithLockAcquiredUntilUsageIsWithin( } if (bytes_allocated_ != bytes_allocated_before_purging) - BytesAllocatedChanged(); + BytesAllocatedChanged(bytes_allocated_); } -void DiscardableMemoryManager::EnforcePolicyWithLockAcquired() { - PurgeLRUWithLockAcquiredUntilUsageIsWithin(memory_limit_); -} - -void DiscardableMemoryManager::BytesAllocatedChanged() const { - TRACE_COUNTER_ID1("base", "DiscardableMemoryUsage", this, 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(bytes_allocated_)); + Uint64ToString(new_bytes_allocated)); +} + +TimeTicks DiscardableMemoryManager::Now() const { + return TimeTicks::Now(); } } // namespace internal