| Index: base/memory/discardable_memory_manager_unittest.cc
|
| diff --git a/base/memory/discardable_memory_manager_unittest.cc b/base/memory/discardable_memory_manager_unittest.cc
|
| index 95e7c13ef82bec0bae581b1184eb05f7a6173c22..58a9603ec86354685ac613199e204cd027deff7e 100644
|
| --- a/base/memory/discardable_memory_manager_unittest.cc
|
| +++ b/base/memory/discardable_memory_manager_unittest.cc
|
| @@ -5,156 +5,157 @@
|
| #include "base/memory/discardable_memory_manager.h"
|
|
|
| #include "base/bind.h"
|
| -#include "base/memory/discardable_memory.h"
|
| #include "base/run_loop.h"
|
| #include "base/synchronization/waitable_event.h"
|
| #include "base/threading/thread.h"
|
| #include "testing/gtest/include/gtest/gtest.h"
|
|
|
| namespace base {
|
| +namespace {
|
|
|
| -class DiscardableMemoryManagerTestBase {
|
| +class TestAllocationImpl : public internal::DiscardableMemoryManagerAllocation {
|
| public:
|
| - class TestDiscardableMemory : public DiscardableMemory {
|
| - public:
|
| - TestDiscardableMemory(
|
| - internal::DiscardableMemoryManager* manager, size_t size)
|
| - : manager_(manager),
|
| - is_locked_(false) {
|
| - manager_->Register(this, size);
|
| - }
|
| + TestAllocationImpl() : is_allocated_(false), is_locked_(false) {}
|
| + virtual ~TestAllocationImpl() { DCHECK(!is_locked_); }
|
| +
|
| + // Overridden from internal::DiscardableMemoryManagerAllocation:
|
| + virtual bool AllocateAndAcquireLock(size_t bytes) OVERRIDE {
|
| + bool was_allocated = is_allocated_;
|
| + is_allocated_ = true;
|
| + DCHECK(!is_locked_);
|
| + is_locked_ = true;
|
| + return was_allocated;
|
| + }
|
| + virtual void ReleaseLock() OVERRIDE {
|
| + DCHECK(is_locked_);
|
| + is_locked_ = false;
|
| + }
|
| + virtual void Purge() OVERRIDE {
|
| + DCHECK(is_allocated_);
|
| + is_allocated_ = false;
|
| + }
|
|
|
| - virtual ~TestDiscardableMemory() {
|
| - if (is_locked_)
|
| - Unlock();
|
| - manager_->Unregister(this);
|
| - }
|
| + bool is_locked() const { return is_locked_; }
|
|
|
| - // Overridden from DiscardableMemory:
|
| - virtual DiscardableMemoryLockStatus Lock() OVERRIDE {
|
| - DCHECK(!is_locked_);
|
| + private:
|
| + bool is_allocated_;
|
| + bool is_locked_;
|
| +};
|
|
|
| - bool purged = false;
|
| - memory_ = manager_->Acquire(this, &purged);
|
| - if (!memory_)
|
| - return DISCARDABLE_MEMORY_LOCK_STATUS_FAILED;
|
| +class DiscardableMemoryManagerTestBase {
|
| + public:
|
| + DiscardableMemoryManagerTestBase() {
|
| + manager_.RegisterMemoryPressureListener();
|
| + }
|
|
|
| - is_locked_ = true;
|
| - return purged ? DISCARDABLE_MEMORY_LOCK_STATUS_PURGED
|
| - : DISCARDABLE_MEMORY_LOCK_STATUS_SUCCESS;
|
| - }
|
| - virtual void Unlock() OVERRIDE {
|
| - DCHECK(is_locked_);
|
| - manager_->Release(this, memory_.Pass());
|
| - is_locked_ = false;
|
| - }
|
| - virtual void* Memory() const OVERRIDE {
|
| - DCHECK(memory_);
|
| - return memory_.get();
|
| - }
|
| + protected:
|
| + enum LockStatus {
|
| + LOCK_STATUS_FAILED,
|
| + LOCK_STATUS_PURGED,
|
| + LOCK_STATUS_SUCCESS
|
| + };
|
|
|
| - private:
|
| - internal::DiscardableMemoryManager* manager_;
|
| - scoped_ptr<uint8, FreeDeleter> memory_;
|
| - bool is_locked_;
|
| + size_t BytesAllocated() const { return manager_.GetBytesAllocatedForTest(); }
|
|
|
| - DISALLOW_COPY_AND_ASSIGN(TestDiscardableMemory);
|
| - };
|
| + void SetMemoryLimit(size_t bytes) { manager_.SetMemoryLimit(bytes); }
|
|
|
| - DiscardableMemoryManagerTestBase()
|
| - : manager_(new internal::DiscardableMemoryManager) {
|
| - manager_->RegisterMemoryPressureListener();
|
| + void SetBytesToKeepUnderModeratePressure(size_t bytes) {
|
| + manager_.SetBytesToKeepUnderModeratePressure(bytes);
|
| }
|
|
|
| - protected:
|
| - bool IsRegistered(const DiscardableMemory* discardable) {
|
| - return manager_->IsRegisteredForTest(discardable);
|
| + void Register(TestAllocationImpl* allocation, size_t bytes) {
|
| + manager_.Register(allocation, bytes);
|
| }
|
|
|
| - bool CanBePurged(const DiscardableMemory* discardable) {
|
| - return manager_->CanBePurgedForTest(discardable);
|
| + void Unregister(TestAllocationImpl* allocation) {
|
| + manager_.Unregister(allocation);
|
| }
|
|
|
| - size_t BytesAllocated() const {
|
| - return manager_->GetBytesAllocatedForTest();
|
| + bool IsRegistered(TestAllocationImpl* allocation) const {
|
| + return manager_.IsRegisteredForTest(allocation);
|
| }
|
|
|
| - void* Memory(const DiscardableMemory* discardable) const {
|
| - return discardable->Memory();
|
| + LockStatus Lock(TestAllocationImpl* allocation) {
|
| + bool purged;
|
| + if (!manager_.AcquireLock(allocation, &purged))
|
| + return LOCK_STATUS_FAILED;
|
| + return purged ? LOCK_STATUS_PURGED : LOCK_STATUS_SUCCESS;
|
| }
|
|
|
| - void SetDiscardableMemoryLimit(size_t bytes) {
|
| - manager_->SetDiscardableMemoryLimit(bytes);
|
| + void Unlock(TestAllocationImpl* allocation) {
|
| + manager_.ReleaseLock(allocation);
|
| }
|
|
|
| - void SetBytesToKeepUnderModeratePressure(size_t bytes) {
|
| - manager_->SetBytesToKeepUnderModeratePressure(bytes);
|
| + LockStatus RegisterAndLock(TestAllocationImpl* allocation, size_t bytes) {
|
| + manager_.Register(allocation, bytes);
|
| + return Lock(allocation);
|
| }
|
|
|
| - scoped_ptr<DiscardableMemory> CreateLockedMemory(size_t size) {
|
| - scoped_ptr<TestDiscardableMemory> memory(
|
| - new TestDiscardableMemory(manager_.get(), size));
|
| - if (memory->Lock() != DISCARDABLE_MEMORY_LOCK_STATUS_PURGED)
|
| - return scoped_ptr<DiscardableMemory>();
|
| - return memory.PassAs<DiscardableMemory>();
|
| + bool CanBePurged(TestAllocationImpl* allocation) const {
|
| + return manager_.CanBePurgedForTest(allocation);
|
| }
|
|
|
| private:
|
| MessageLoopForIO message_loop_;
|
| - scoped_ptr<internal::DiscardableMemoryManager> manager_;
|
| + internal::DiscardableMemoryManager manager_;
|
| };
|
|
|
| -class DiscardableMemoryManagerTest
|
| - : public DiscardableMemoryManagerTestBase,
|
| - public testing::Test {
|
| +class DiscardableMemoryManagerTest : public DiscardableMemoryManagerTestBase,
|
| + public testing::Test {
|
| public:
|
| DiscardableMemoryManagerTest() {}
|
| };
|
|
|
| -TEST_F(DiscardableMemoryManagerTest, CreateLockedMemory) {
|
| +TEST_F(DiscardableMemoryManagerTest, CreateAndLock) {
|
| size_t size = 1024;
|
| - const scoped_ptr<DiscardableMemory> discardable(CreateLockedMemory(size));
|
| - EXPECT_TRUE(IsRegistered(discardable.get()));
|
| - EXPECT_NE(static_cast<void*>(NULL), Memory(discardable.get()));
|
| + TestAllocationImpl allocation;
|
| + Register(&allocation, size);
|
| + EXPECT_TRUE(IsRegistered(&allocation));
|
| + EXPECT_EQ(LOCK_STATUS_PURGED, Lock(&allocation));
|
| + EXPECT_TRUE(allocation.is_locked());
|
| EXPECT_EQ(1024u, BytesAllocated());
|
| - EXPECT_FALSE(CanBePurged(discardable.get()));
|
| + EXPECT_FALSE(CanBePurged(&allocation));
|
| + Unlock(&allocation);
|
| + Unregister(&allocation);
|
| }
|
|
|
| -TEST_F(DiscardableMemoryManagerTest, CreateLockedMemoryZeroSize) {
|
| +TEST_F(DiscardableMemoryManagerTest, CreateZeroSize) {
|
| size_t size = 0;
|
| - const scoped_ptr<DiscardableMemory> discardable(CreateLockedMemory(size));
|
| - EXPECT_FALSE(discardable);
|
| - EXPECT_FALSE(IsRegistered(discardable.get()));
|
| + TestAllocationImpl allocation;
|
| + Register(&allocation, size);
|
| + EXPECT_TRUE(IsRegistered(&allocation));
|
| + EXPECT_EQ(LOCK_STATUS_FAILED, Lock(&allocation));
|
| EXPECT_EQ(0u, BytesAllocated());
|
| + Unregister(&allocation);
|
| }
|
|
|
| TEST_F(DiscardableMemoryManagerTest, LockAfterUnlock) {
|
| size_t size = 1024;
|
| - const scoped_ptr<DiscardableMemory> discardable(CreateLockedMemory(size));
|
| - EXPECT_TRUE(IsRegistered(discardable.get()));
|
| - EXPECT_NE(static_cast<void*>(NULL), Memory(discardable.get()));
|
| + TestAllocationImpl allocation;
|
| + RegisterAndLock(&allocation, size);
|
| EXPECT_EQ(1024u, BytesAllocated());
|
| - EXPECT_FALSE(CanBePurged(discardable.get()));
|
| + EXPECT_FALSE(CanBePurged(&allocation));
|
|
|
| // Now unlock so we can lock later.
|
| - discardable->Unlock();
|
| - EXPECT_TRUE(CanBePurged(discardable.get()));
|
| + Unlock(&allocation);
|
| + EXPECT_TRUE(CanBePurged(&allocation));
|
|
|
| - EXPECT_EQ(DISCARDABLE_MEMORY_LOCK_STATUS_SUCCESS, discardable->Lock());
|
| - EXPECT_FALSE(CanBePurged(discardable.get()));
|
| + EXPECT_EQ(LOCK_STATUS_SUCCESS, Lock(&allocation));
|
| + EXPECT_FALSE(CanBePurged(&allocation));
|
| + Unlock(&allocation);
|
| + Unregister(&allocation);
|
| }
|
|
|
| TEST_F(DiscardableMemoryManagerTest, LockAfterPurge) {
|
| size_t size = 1024;
|
| - const scoped_ptr<DiscardableMemory> discardable(CreateLockedMemory(size));
|
| - EXPECT_TRUE(IsRegistered(discardable.get()));
|
| - EXPECT_NE(static_cast<void*>(NULL), Memory(discardable.get()));
|
| + TestAllocationImpl allocation;
|
| + RegisterAndLock(&allocation, size);
|
| EXPECT_EQ(1024u, BytesAllocated());
|
| - EXPECT_FALSE(CanBePurged(discardable.get()));
|
| + EXPECT_FALSE(CanBePurged(&allocation));
|
|
|
| // Now unlock so we can lock later.
|
| - discardable->Unlock();
|
| - EXPECT_TRUE(CanBePurged(discardable.get()));
|
| + Unlock(&allocation);
|
| + EXPECT_TRUE(CanBePurged(&allocation));
|
|
|
| // Force the system to purge.
|
| MemoryPressureListener::NotifyMemoryPressure(
|
| @@ -163,43 +164,53 @@ TEST_F(DiscardableMemoryManagerTest, LockAfterPurge) {
|
| // Required because ObserverListThreadSafe notifies via PostTask.
|
| RunLoop().RunUntilIdle();
|
|
|
| - EXPECT_EQ(DISCARDABLE_MEMORY_LOCK_STATUS_PURGED, discardable->Lock());
|
| - EXPECT_FALSE(CanBePurged(discardable.get()));
|
| + EXPECT_EQ(LOCK_STATUS_PURGED, Lock(&allocation));
|
| + EXPECT_FALSE(CanBePurged(&allocation));
|
| +
|
| + Unlock(&allocation);
|
| + Unregister(&allocation);
|
| }
|
|
|
| TEST_F(DiscardableMemoryManagerTest, LockAfterPurgeAndCannotReallocate) {
|
| size_t size = 1024;
|
| - const scoped_ptr<DiscardableMemory> discardable(CreateLockedMemory(size));
|
| - EXPECT_TRUE(IsRegistered(discardable.get()));
|
| - EXPECT_NE(static_cast<void*>(NULL), Memory(discardable.get()));
|
| + TestAllocationImpl allocation;
|
| + RegisterAndLock(&allocation, size);
|
| EXPECT_EQ(1024u, BytesAllocated());
|
| - EXPECT_FALSE(CanBePurged(discardable.get()));
|
| + EXPECT_FALSE(CanBePurged(&allocation));
|
|
|
| // Now unlock so we can lock later.
|
| - discardable->Unlock();
|
| - EXPECT_TRUE(CanBePurged(discardable.get()));
|
| + Unlock(&allocation);
|
| + EXPECT_TRUE(CanBePurged(&allocation));
|
| +
|
| + // Set max allowed allocation to 1 byte. This will cause the memory to be
|
| + // purged.
|
| + SetMemoryLimit(1);
|
|
|
| - // Set max allowed allocation to 1 byte. This will make cause the memory
|
| - // to be purged.
|
| - SetDiscardableMemoryLimit(1);
|
| + EXPECT_EQ(LOCK_STATUS_PURGED, Lock(&allocation));
|
| + EXPECT_FALSE(CanBePurged(&allocation));
|
|
|
| - EXPECT_EQ(DISCARDABLE_MEMORY_LOCK_STATUS_PURGED, discardable->Lock());
|
| - EXPECT_FALSE(CanBePurged(discardable.get()));
|
| + Unlock(&allocation);
|
| + Unregister(&allocation);
|
| }
|
|
|
| TEST_F(DiscardableMemoryManagerTest, Overflow) {
|
| + size_t size = 1024;
|
| {
|
| - size_t size = 1024;
|
| - const scoped_ptr<DiscardableMemory> discardable(CreateLockedMemory(size));
|
| - EXPECT_TRUE(IsRegistered(discardable.get()));
|
| - EXPECT_NE(static_cast<void*>(NULL), Memory(discardable.get()));
|
| + TestAllocationImpl allocation;
|
| + RegisterAndLock(&allocation, size);
|
| EXPECT_EQ(1024u, BytesAllocated());
|
|
|
| size_t massive_size = std::numeric_limits<size_t>::max();
|
| - const scoped_ptr<DiscardableMemory> massive_discardable(
|
| - CreateLockedMemory(massive_size));
|
| - EXPECT_FALSE(massive_discardable);
|
| + TestAllocationImpl massive_allocation;
|
| + Register(&massive_allocation, massive_size);
|
| + EXPECT_EQ(LOCK_STATUS_FAILED, Lock(&massive_allocation));
|
| EXPECT_EQ(1024u, BytesAllocated());
|
| +
|
| + Unlock(&allocation);
|
| + EXPECT_EQ(LOCK_STATUS_PURGED, Lock(&massive_allocation));
|
| + Unlock(&massive_allocation);
|
| + Unregister(&massive_allocation);
|
| + Unregister(&allocation);
|
| }
|
| EXPECT_EQ(0u, BytesAllocated());
|
| }
|
| @@ -225,83 +236,93 @@ class DiscardableMemoryManagerPermutationTest
|
| DiscardableMemoryManagerPermutationTest() {}
|
|
|
| protected:
|
| - // Use discardable memory in order specified by ordering parameter.
|
| - void CreateAndUseDiscardableMemory() {
|
| + // Use memory in order specified by ordering parameter.
|
| + void RegisterAndUseAllocations() {
|
| for (int i = 0; i < 3; ++i) {
|
| - discardables_[i] = CreateLockedMemory(1024);
|
| - EXPECT_TRUE(discardables_[i]);
|
| - EXPECT_NE(static_cast<void*>(NULL), Memory(discardables_[i].get()));
|
| - discardables_[i]->Unlock();
|
| + RegisterAndLock(&allocation_[i], 1024);
|
| + Unlock(&allocation_[i]);
|
| }
|
| for (int i = 0; i < 3; ++i) {
|
| int index = GetParam().ordering()[i];
|
| - EXPECT_NE(DISCARDABLE_MEMORY_LOCK_STATUS_FAILED,
|
| - discardables_[index]->Lock());
|
| + EXPECT_NE(LOCK_STATUS_FAILED, Lock(&allocation_[index]));
|
| // Leave i == 0 locked.
|
| if (i > 0)
|
| - discardables_[index]->Unlock();
|
| + Unlock(&allocation_[index]);
|
| }
|
| }
|
|
|
| - DiscardableMemory* discardable(unsigned position) {
|
| - return discardables_[GetParam().ordering()[position]].get();
|
| + TestAllocationImpl* allocation(unsigned position) {
|
| + return &allocation_[GetParam().ordering()[position]];
|
| + }
|
| +
|
| + void UnlockAndUnregisterAllocations() {
|
| + for (int i = 0; i < 3; ++i) {
|
| + if (allocation_[i].is_locked())
|
| + Unlock(&allocation_[i]);
|
| + Unregister(&allocation_[i]);
|
| + }
|
| }
|
|
|
| private:
|
| - scoped_ptr<DiscardableMemory> discardables_[3];
|
| + TestAllocationImpl allocation_[3];
|
| };
|
|
|
| // Verify that memory was discarded in the correct order after applying
|
| // memory pressure.
|
| TEST_P(DiscardableMemoryManagerPermutationTest, LRUDiscardedModeratePressure) {
|
| - CreateAndUseDiscardableMemory();
|
| + RegisterAndUseAllocations();
|
|
|
| SetBytesToKeepUnderModeratePressure(1024);
|
| - SetDiscardableMemoryLimit(2048);
|
| + SetMemoryLimit(2048);
|
|
|
| MemoryPressureListener::NotifyMemoryPressure(
|
| MemoryPressureListener::MEMORY_PRESSURE_MODERATE);
|
| RunLoop().RunUntilIdle();
|
|
|
| - EXPECT_NE(DISCARDABLE_MEMORY_LOCK_STATUS_FAILED, discardable(2)->Lock());
|
| - EXPECT_NE(DISCARDABLE_MEMORY_LOCK_STATUS_SUCCESS, discardable(1)->Lock());
|
| + EXPECT_NE(LOCK_STATUS_FAILED, Lock(allocation(2)));
|
| + EXPECT_EQ(LOCK_STATUS_PURGED, Lock(allocation(1)));
|
| // 0 should still be locked.
|
| - EXPECT_NE(static_cast<void*>(NULL), Memory(discardable(0)));
|
| + EXPECT_TRUE(allocation(0)->is_locked());
|
| +
|
| + UnlockAndUnregisterAllocations();
|
| }
|
|
|
| // Verify that memory was discarded in the correct order after changing
|
| // memory limit.
|
| TEST_P(DiscardableMemoryManagerPermutationTest, LRUDiscardedExceedLimit) {
|
| - CreateAndUseDiscardableMemory();
|
| + RegisterAndUseAllocations();
|
|
|
| SetBytesToKeepUnderModeratePressure(1024);
|
| - SetDiscardableMemoryLimit(2048);
|
| + SetMemoryLimit(2048);
|
|
|
| - EXPECT_NE(DISCARDABLE_MEMORY_LOCK_STATUS_FAILED, discardable(2)->Lock());
|
| - EXPECT_NE(DISCARDABLE_MEMORY_LOCK_STATUS_SUCCESS, discardable(1)->Lock());
|
| + EXPECT_NE(LOCK_STATUS_FAILED, Lock(allocation(2)));
|
| + EXPECT_EQ(LOCK_STATUS_PURGED, Lock(allocation(1)));
|
| // 0 should still be locked.
|
| - EXPECT_NE(static_cast<void*>(NULL), Memory(discardable(0)));
|
| + EXPECT_TRUE(allocation(0)->is_locked());
|
| +
|
| + UnlockAndUnregisterAllocations();
|
| }
|
|
|
| // Verify that no more memory than necessary was discarded after changing
|
| // memory limit.
|
| TEST_P(DiscardableMemoryManagerPermutationTest, LRUDiscardedAmount) {
|
| SetBytesToKeepUnderModeratePressure(2048);
|
| - SetDiscardableMemoryLimit(4096);
|
| + SetMemoryLimit(4096);
|
|
|
| - CreateAndUseDiscardableMemory();
|
| + RegisterAndUseAllocations();
|
|
|
| - SetDiscardableMemoryLimit(2048);
|
| + SetMemoryLimit(2048);
|
|
|
| - EXPECT_EQ(DISCARDABLE_MEMORY_LOCK_STATUS_SUCCESS, discardable(2)->Lock());
|
| - EXPECT_EQ(DISCARDABLE_MEMORY_LOCK_STATUS_PURGED, discardable(1)->Lock());
|
| + EXPECT_EQ(LOCK_STATUS_SUCCESS, Lock(allocation(2)));
|
| + EXPECT_EQ(LOCK_STATUS_PURGED, Lock(allocation(1)));
|
| // 0 should still be locked.
|
| - EXPECT_NE(static_cast<void*>(NULL), Memory(discardable(0)));
|
| + EXPECT_TRUE(allocation(0)->is_locked());
|
| +
|
| + UnlockAndUnregisterAllocations();
|
| }
|
|
|
| -TEST_P(DiscardableMemoryManagerPermutationTest,
|
| - CriticalPressureFreesAllUnlocked) {
|
| - CreateAndUseDiscardableMemory();
|
| +TEST_P(DiscardableMemoryManagerPermutationTest, PurgeFreesAllUnlocked) {
|
| + RegisterAndUseAllocations();
|
|
|
| MemoryPressureListener::NotifyMemoryPressure(
|
| MemoryPressureListener::MEMORY_PRESSURE_CRITICAL);
|
| @@ -309,10 +330,12 @@ TEST_P(DiscardableMemoryManagerPermutationTest,
|
|
|
| for (int i = 0; i < 3; ++i) {
|
| if (i == 0)
|
| - EXPECT_NE(static_cast<void*>(NULL), Memory(discardable(i)));
|
| + EXPECT_TRUE(allocation(i)->is_locked());
|
| else
|
| - EXPECT_EQ(DISCARDABLE_MEMORY_LOCK_STATUS_PURGED, discardable(i)->Lock());
|
| + EXPECT_EQ(LOCK_STATUS_PURGED, Lock(allocation(i)));
|
| }
|
| +
|
| + UnlockAndUnregisterAllocations();
|
| }
|
|
|
| INSTANTIATE_TEST_CASE_P(DiscardableMemoryManagerPermutationTests,
|
| @@ -327,69 +350,61 @@ INSTANTIATE_TEST_CASE_P(DiscardableMemoryManagerPermutationTests,
|
| TEST_F(DiscardableMemoryManagerTest, NormalDestruction) {
|
| {
|
| size_t size = 1024;
|
| - const scoped_ptr<DiscardableMemory> discardable(CreateLockedMemory(size));
|
| - EXPECT_TRUE(IsRegistered(discardable.get()));
|
| - EXPECT_EQ(1024u, BytesAllocated());
|
| + TestAllocationImpl allocation;
|
| + Register(&allocation, size);
|
| + Unregister(&allocation);
|
| }
|
| EXPECT_EQ(0u, BytesAllocated());
|
| }
|
|
|
| -TEST_F(DiscardableMemoryManagerTest, DestructionWhileLocked) {
|
| +TEST_F(DiscardableMemoryManagerTest, DestructionAfterLocked) {
|
| {
|
| size_t size = 1024;
|
| - const scoped_ptr<DiscardableMemory> discardable(CreateLockedMemory(size));
|
| - EXPECT_TRUE(IsRegistered(discardable.get()));
|
| - EXPECT_NE(static_cast<void*>(NULL), Memory(discardable.get()));
|
| + TestAllocationImpl allocation;
|
| + RegisterAndLock(&allocation, size);
|
| EXPECT_EQ(1024u, BytesAllocated());
|
| - EXPECT_FALSE(CanBePurged(discardable.get()));
|
| + EXPECT_FALSE(CanBePurged(&allocation));
|
| + Unlock(&allocation);
|
| + Unregister(&allocation);
|
| }
|
| - // Should have ignored the "locked" status and freed the discardable memory.
|
| EXPECT_EQ(0u, BytesAllocated());
|
| }
|
|
|
| -#if !defined(NDEBUG) && !defined(OS_ANDROID) && !defined(OS_IOS)
|
| -// Death tests are not supported with Android APKs.
|
| -TEST_F(DiscardableMemoryManagerTest, UnlockedMemoryAccessCrashesInDebugMode) {
|
| - size_t size = 1024;
|
| - const scoped_ptr<DiscardableMemory> discardable(CreateLockedMemory(size));
|
| - EXPECT_TRUE(IsRegistered(discardable.get()));
|
| - EXPECT_NE(static_cast<void*>(NULL), Memory(discardable.get()));
|
| - EXPECT_EQ(1024u, BytesAllocated());
|
| - EXPECT_FALSE(CanBePurged(discardable.get()));
|
| - discardable->Unlock();
|
| - EXPECT_TRUE(CanBePurged(discardable.get()));
|
| - // We *must* die if we are asked to vend a pointer to unlocked memory.
|
| - EXPECT_DEATH(discardable->Memory(), ".*Check failed.*");
|
| +TEST_F(DiscardableMemoryManagerTest, DestructionAfterPurged) {
|
| + {
|
| + size_t size = 1024;
|
| + TestAllocationImpl allocation;
|
| + RegisterAndLock(&allocation, size);
|
| + EXPECT_EQ(1024u, BytesAllocated());
|
| + Unlock(&allocation);
|
| + EXPECT_TRUE(CanBePurged(&allocation));
|
| + SetMemoryLimit(0);
|
| + EXPECT_EQ(0u, BytesAllocated());
|
| + Unregister(&allocation);
|
| + }
|
| + EXPECT_EQ(0u, BytesAllocated());
|
| }
|
| -#endif
|
|
|
| class ThreadedDiscardableMemoryManagerTest
|
| : public DiscardableMemoryManagerTest {
|
| public:
|
| ThreadedDiscardableMemoryManagerTest()
|
| : memory_usage_thread_("memory_usage_thread"),
|
| - thread_sync_(true, false) {
|
| - }
|
| + thread_sync_(true, false) {}
|
|
|
| - virtual void SetUp() OVERRIDE {
|
| - memory_usage_thread_.Start();
|
| - }
|
| + virtual void SetUp() OVERRIDE { memory_usage_thread_.Start(); }
|
|
|
| - virtual void TearDown() OVERRIDE {
|
| - memory_usage_thread_.Stop();
|
| - }
|
| + virtual void TearDown() OVERRIDE { memory_usage_thread_.Stop(); }
|
|
|
| void UseMemoryHelper() {
|
| size_t size = 1024;
|
| - const scoped_ptr<DiscardableMemory> discardable(CreateLockedMemory(size));
|
| - EXPECT_TRUE(IsRegistered(discardable.get()));
|
| - EXPECT_NE(static_cast<void*>(NULL), Memory(discardable.get()));
|
| - discardable->Unlock();
|
| + TestAllocationImpl allocation;
|
| + RegisterAndLock(&allocation, size);
|
| + Unlock(&allocation);
|
| + Unregister(&allocation);
|
| }
|
|
|
| - void SignalHelper() {
|
| - thread_sync_.Signal();
|
| - }
|
| + void SignalHelper() { thread_sync_.Signal(); }
|
|
|
| Thread memory_usage_thread_;
|
| WaitableEvent thread_sync_;
|
| @@ -407,4 +422,5 @@ TEST_F(ThreadedDiscardableMemoryManagerTest, UseMemoryOnThread) {
|
| thread_sync_.Wait();
|
| }
|
|
|
| +} // namespace
|
| } // namespace base
|
|
|