• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "base/memory/discardable_memory.h"
6 
7 #include <limits>
8 
9 #include "testing/gtest/include/gtest/gtest.h"
10 
11 namespace base {
12 
13 const size_t kSize = 1024;
14 
15 #if defined(OS_ANDROID)
TEST(DiscardableMemoryTest,TooLargeAllocationFails)16 TEST(DiscardableMemoryTest, TooLargeAllocationFails) {
17   const size_t kPageSize = 4096;
18   const size_t max_allowed_allocation_size =
19       std::numeric_limits<size_t>::max() - kPageSize + 1;
20   scoped_ptr<DiscardableMemory> memory(
21       DiscardableMemory::CreateLockedMemory(max_allowed_allocation_size + 1));
22   // On certain platforms (e.g. Android), page-alignment would have caused an
23   // overflow resulting in a small allocation if the input size wasn't checked
24   // correctly.
25   ASSERT_FALSE(memory);
26 }
27 #endif
28 
TEST(DiscardableMemoryTest,SupportedNatively)29 TEST(DiscardableMemoryTest, SupportedNatively) {
30 #if defined(DISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY)
31   ASSERT_TRUE(DiscardableMemory::SupportedNatively());
32 #else
33   // If we ever have a platform that decides at runtime if it can support
34   // discardable memory natively, then we'll have to add a 'never supported
35   // natively' define for this case. At present, if it's not always supported
36   // natively, it's never supported.
37   ASSERT_FALSE(DiscardableMemory::SupportedNatively());
38 #endif
39 }
40 
41 // Test Lock() and Unlock() functionalities.
TEST(DiscardableMemoryTest,LockAndUnLock)42 TEST(DiscardableMemoryTest, LockAndUnLock) {
43   const scoped_ptr<DiscardableMemory> memory(
44       DiscardableMemory::CreateLockedMemory(kSize));
45   ASSERT_TRUE(memory);
46   void* addr = memory->Memory();
47   ASSERT_NE(static_cast<void*>(NULL), addr);
48 
49   memory->Unlock();
50   // The system should have no reason to purge discardable blocks in this brief
51   // interval, though technically speaking this might flake.
52   EXPECT_EQ(DISCARDABLE_MEMORY_SUCCESS, memory->Lock());
53   addr = memory->Memory();
54   ASSERT_NE(static_cast<void*>(NULL), addr);
55 
56   memory->Unlock();
57 }
58 
59 // Test delete a discardable memory while it is locked.
TEST(DiscardableMemoryTest,DeleteWhileLocked)60 TEST(DiscardableMemoryTest, DeleteWhileLocked) {
61   const scoped_ptr<DiscardableMemory> memory(
62       DiscardableMemory::CreateLockedMemory(kSize));
63   ASSERT_TRUE(memory);
64 }
65 
66 #if !defined(OS_ANDROID)
67 // Test forced purging.
TEST(DiscardableMemoryTest,Purge)68 TEST(DiscardableMemoryTest, Purge) {
69   ASSERT_TRUE(DiscardableMemory::PurgeForTestingSupported());
70 
71   const scoped_ptr<DiscardableMemory> memory(
72       DiscardableMemory::CreateLockedMemory(kSize));
73   ASSERT_TRUE(memory);
74   memory->Unlock();
75 
76   DiscardableMemory::PurgeForTesting();
77   EXPECT_EQ(DISCARDABLE_MEMORY_PURGED, memory->Lock());
78 }
79 #endif  // !OS_ANDROID
80 
81 #if !defined(NDEBUG) && !defined(OS_ANDROID)
82 // Death tests are not supported with Android APKs.
TEST(DiscardableMemoryTest,UnlockedMemoryAccessCrashesInDebugMode)83 TEST(DiscardableMemoryTest, UnlockedMemoryAccessCrashesInDebugMode) {
84   const scoped_ptr<DiscardableMemory> memory(
85       DiscardableMemory::CreateLockedMemory(kSize));
86   ASSERT_TRUE(memory);
87   memory->Unlock();
88   ASSERT_DEATH_IF_SUPPORTED(
89       { *static_cast<int*>(memory->Memory()) = 0xdeadbeef; }, ".*");
90 }
91 #endif
92 
93 }
94