Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(74)

Side by Side Diff: base/memory/discardable_memory_allocation_ashmem_factory_unittest.cc

Issue 195863005: Use DiscardableMemoryManager on Android. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Use DiscardableMemoryController on Android Created 6 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 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_allocator_android.h" 5 #include "base/memory/discardable_memory_allocation_ashmem_factory.h"
6 6
7 #include <sys/types.h> 7 #include <sys/types.h>
8 #include <unistd.h> 8 #include <unistd.h>
9 9
10 #include "base/memory/discardable_memory.h" 10 #include "base/memory/discardable_memory.h"
11 #include "base/memory/scoped_ptr.h" 11 #include "base/memory/scoped_ptr.h"
12 #include "base/strings/string_number_conversions.h" 12 #include "base/strings/string_number_conversions.h"
13 #include "base/strings/string_split.h" 13 #include "base/strings/string_split.h"
14 #include "base/strings/stringprintf.h" 14 #include "base/strings/stringprintf.h"
15 #include "build/build_config.h" 15 #include "build/build_config.h"
16 #include "testing/gtest/include/gtest/gtest.h" 16 #include "testing/gtest/include/gtest/gtest.h"
17 17
18 namespace base { 18 namespace base {
19 namespace internal { 19 namespace internal {
20 20
21 const char kAllocatorName[] = "allocator-for-testing"; 21 const char kAllocationAshmemFactoryName[] = "allocator-for-testing";
22 22
23 const size_t kAshmemRegionSizeForTesting = 32 * 1024 * 1024; 23 const size_t kAshmemRegionSizeForTesting = 32 * 1024 * 1024;
24 const size_t kPageSize = 4096; 24 const size_t kPageSize = 4096;
25 25
26 const size_t kMaxAllowedAllocationSize = 26 const size_t kMaxAllowedAllocationSize =
27 std::numeric_limits<size_t>::max() - kPageSize + 1; 27 std::numeric_limits<size_t>::max() - kPageSize + 1;
28 28
29 class DiscardableMemoryAllocatorTest : public testing::Test { 29 class DiscardableMemoryAllocationAshmemFactoryTest : public testing::Test {
30 protected: 30 protected:
31 DiscardableMemoryAllocatorTest() 31 DiscardableMemoryAllocationAshmemFactoryTest()
32 : allocator_(kAllocatorName, kAshmemRegionSizeForTesting) { 32 : factory_(kAllocationAshmemFactoryName, kAshmemRegionSizeForTesting) {
33 } 33 }
34 34
35 DiscardableMemoryAllocator allocator_; 35 DiscardableMemoryAllocationAshmemFactory factory_;
36 }; 36 };
37 37
38 void WriteToDiscardableMemory(DiscardableMemory* memory, size_t size) { 38 void WriteToDiscardableMemory(DiscardableMemoryAllocation* memory,
39 size_t size) {
39 // Write to the first and the last pages only to avoid paging in up to 64 40 // Write to the first and the last pages only to avoid paging in up to 64
40 // MBytes. 41 // MBytes.
41 static_cast<char*>(memory->Memory())[0] = 'a'; 42 static_cast<char*>(memory->Memory())[0] = 'a';
42 static_cast<char*>(memory->Memory())[size - 1] = 'a'; 43 static_cast<char*>(memory->Memory())[size - 1] = 'a';
43 } 44 }
44 45
45 TEST_F(DiscardableMemoryAllocatorTest, Basic) { 46 TEST_F(DiscardableMemoryAllocationAshmemFactoryTest, Basic) {
46 const size_t size = 128; 47 const size_t size = 128;
47 scoped_ptr<DiscardableMemory> memory(allocator_.Allocate(size)); 48 scoped_ptr<DiscardableMemoryAllocation> memory(
49 factory_.CreateLockedAllocation(size));
48 ASSERT_TRUE(memory); 50 ASSERT_TRUE(memory);
49 WriteToDiscardableMemory(memory.get(), size); 51 WriteToDiscardableMemory(memory.get(), size);
50 } 52 }
51 53
52 TEST_F(DiscardableMemoryAllocatorTest, ZeroAllocationIsNotSupported) { 54 TEST_F(DiscardableMemoryAllocationAshmemFactoryTest,
53 scoped_ptr<DiscardableMemory> memory(allocator_.Allocate(0)); 55 ZeroAllocationIsNotSupported) {
56 scoped_ptr<DiscardableMemoryAllocation> memory(
57 factory_.CreateLockedAllocation(0));
54 ASSERT_FALSE(memory); 58 ASSERT_FALSE(memory);
55 } 59 }
56 60
57 TEST_F(DiscardableMemoryAllocatorTest, TooLargeAllocationFails) { 61 TEST_F(DiscardableMemoryAllocationAshmemFactoryTest, TooLargeAllocationFails) {
58 scoped_ptr<DiscardableMemory> memory( 62 scoped_ptr<DiscardableMemoryAllocation> memory(
59 allocator_.Allocate(kMaxAllowedAllocationSize + 1)); 63 factory_.CreateLockedAllocation(kMaxAllowedAllocationSize + 1));
60 // Page-alignment would have caused an overflow resulting in a small 64 // Page-alignment would have caused an overflow resulting in a small
61 // allocation if the input size wasn't checked correctly. 65 // allocation if the input size wasn't checked correctly.
62 ASSERT_FALSE(memory); 66 ASSERT_FALSE(memory);
63 } 67 }
64 68
65 TEST_F(DiscardableMemoryAllocatorTest, 69 TEST_F(DiscardableMemoryAllocationAshmemFactoryTest,
66 AshmemRegionsAreNotSmallerThanRequestedSize) { 70 AshmemRegionsAreNotSmallerThanRequestedSize) {
67 // The creation of the underlying ashmem region is expected to fail since 71 // The creation of the underlying ashmem region is expected to fail since
68 // there should not be enough room in the address space. When ashmem creation 72 // there should not be enough room in the address space. When ashmem creation
69 // fails, the allocator repetitively retries by dividing the size by 2. This 73 // fails, the allocator repetitively retries by dividing the size by 2. This
70 // size should not be smaller than the size the user requested so the 74 // size should not be smaller than the size the user requested so the
71 // allocation here should just fail (and not succeed with the minimum ashmem 75 // allocation here should just fail (and not succeed with the minimum ashmem
72 // region size). 76 // region size).
73 scoped_ptr<DiscardableMemory> memory( 77 scoped_ptr<DiscardableMemoryAllocation> memory(
74 allocator_.Allocate(kMaxAllowedAllocationSize)); 78 factory_.CreateLockedAllocation(kMaxAllowedAllocationSize));
75 ASSERT_FALSE(memory); 79 ASSERT_FALSE(memory);
76 } 80 }
77 81
78 TEST_F(DiscardableMemoryAllocatorTest, AshmemRegionsAreAlwaysPageAligned) { 82 TEST_F(DiscardableMemoryAllocationAshmemFactoryTest,
83 AshmemRegionsAreAlwaysPageAligned) {
79 // Use a separate allocator here so that we can override the ashmem region 84 // Use a separate allocator here so that we can override the ashmem region
80 // size. 85 // size.
81 DiscardableMemoryAllocator allocator( 86 DiscardableMemoryAllocationAshmemFactory allocator(
82 kAllocatorName, kMaxAllowedAllocationSize); 87 kAllocationAshmemFactoryName, kMaxAllowedAllocationSize);
83 scoped_ptr<DiscardableMemory> memory(allocator.Allocate(kPageSize)); 88 scoped_ptr<DiscardableMemoryAllocation> memory(
89 allocator.CreateLockedAllocation(kPageSize));
84 ASSERT_TRUE(memory); 90 ASSERT_TRUE(memory);
85 EXPECT_GT(kMaxAllowedAllocationSize, allocator.last_ashmem_region_size()); 91 EXPECT_GT(kMaxAllowedAllocationSize, allocator.last_ashmem_region_size());
86 ASSERT_TRUE(allocator.last_ashmem_region_size() % kPageSize == 0); 92 ASSERT_TRUE(allocator.last_ashmem_region_size() % kPageSize == 0);
87 } 93 }
88 94
89 TEST_F(DiscardableMemoryAllocatorTest, LargeAllocation) { 95 TEST_F(DiscardableMemoryAllocationAshmemFactoryTest, LargeAllocation) {
90 // Note that large allocations should just use DiscardableMemoryAndroidSimple 96 // Note that large allocations should just use DiscardableMemoryAndroidSimple
91 // instead. 97 // instead.
92 const size_t size = 64 * 1024 * 1024; 98 const size_t size = 64 * 1024 * 1024;
93 scoped_ptr<DiscardableMemory> memory(allocator_.Allocate(size)); 99 scoped_ptr<DiscardableMemoryAllocation> memory(
100 factory_.CreateLockedAllocation(size));
94 ASSERT_TRUE(memory); 101 ASSERT_TRUE(memory);
95 WriteToDiscardableMemory(memory.get(), size); 102 WriteToDiscardableMemory(memory.get(), size);
96 } 103 }
97 104
98 TEST_F(DiscardableMemoryAllocatorTest, ChunksArePageAligned) { 105 TEST_F(DiscardableMemoryAllocationAshmemFactoryTest, ChunksArePageAligned) {
99 scoped_ptr<DiscardableMemory> memory(allocator_.Allocate(kPageSize)); 106 scoped_ptr<DiscardableMemoryAllocation> memory(
107 factory_.CreateLockedAllocation(kPageSize));
100 ASSERT_TRUE(memory); 108 ASSERT_TRUE(memory);
101 EXPECT_EQ(0U, reinterpret_cast<uint64_t>(memory->Memory()) % kPageSize); 109 EXPECT_EQ(0U, reinterpret_cast<uint64_t>(memory->Memory()) % kPageSize);
102 WriteToDiscardableMemory(memory.get(), kPageSize); 110 WriteToDiscardableMemory(memory.get(), kPageSize);
103 } 111 }
104 112
105 TEST_F(DiscardableMemoryAllocatorTest, AllocateFreeAllocate) { 113 TEST_F(DiscardableMemoryAllocationAshmemFactoryTest, AllocateFreeAllocate) {
106 scoped_ptr<DiscardableMemory> memory(allocator_.Allocate(kPageSize)); 114 scoped_ptr<DiscardableMemoryAllocation> memory(
115 factory_.CreateLockedAllocation(kPageSize));
107 // Extra allocation that prevents the region from being deleted when |memory| 116 // Extra allocation that prevents the region from being deleted when |memory|
108 // gets deleted. 117 // gets deleted.
109 scoped_ptr<DiscardableMemory> memory_lock(allocator_.Allocate(kPageSize)); 118 scoped_ptr<DiscardableMemoryAllocation> memory_lock(
119 factory_.CreateLockedAllocation(kPageSize));
110 ASSERT_TRUE(memory); 120 ASSERT_TRUE(memory);
111 void* const address = memory->Memory(); 121 void* const address = memory->Memory();
112 memory->Unlock(); // Tests that the reused chunk is being locked correctly. 122 memory->Unlock(); // Tests that the reused chunk is being locked correctly.
113 memory.reset(); 123 memory.reset();
114 memory = allocator_.Allocate(kPageSize); 124 memory = factory_.CreateLockedAllocation(kPageSize);
115 ASSERT_TRUE(memory); 125 ASSERT_TRUE(memory);
116 // The previously freed chunk should be reused. 126 // The previously freed chunk should be reused.
117 EXPECT_EQ(address, memory->Memory()); 127 EXPECT_EQ(address, memory->Memory());
118 WriteToDiscardableMemory(memory.get(), kPageSize); 128 WriteToDiscardableMemory(memory.get(), kPageSize);
119 } 129 }
120 130
121 TEST_F(DiscardableMemoryAllocatorTest, FreeingWholeAshmemRegionClosesAshmem) { 131 TEST_F(DiscardableMemoryAllocationAshmemFactoryTest,
122 scoped_ptr<DiscardableMemory> memory(allocator_.Allocate(kPageSize)); 132 FreeingWholeAshmemRegionClosesAshmem) {
133 scoped_ptr<DiscardableMemoryAllocation> memory(
134 factory_.CreateLockedAllocation(kPageSize));
123 ASSERT_TRUE(memory); 135 ASSERT_TRUE(memory);
124 const int kMagic = 0xdeadbeef; 136 const int kMagic = 0xdeadbeef;
125 *static_cast<int*>(memory->Memory()) = kMagic; 137 *static_cast<int*>(memory->Memory()) = kMagic;
126 memory.reset(); 138 memory.reset();
127 // The previous ashmem region should have been closed thus it should not be 139 // The previous ashmem region should have been closed thus it should not be
128 // reused. 140 // reused.
129 memory = allocator_.Allocate(kPageSize); 141 memory = factory_.CreateLockedAllocation(kPageSize);
130 ASSERT_TRUE(memory); 142 ASSERT_TRUE(memory);
131 EXPECT_NE(kMagic, *static_cast<const int*>(memory->Memory())); 143 EXPECT_NE(kMagic, *static_cast<const int*>(memory->Memory()));
132 } 144 }
133 145
134 TEST_F(DiscardableMemoryAllocatorTest, AllocateUsesBestFitAlgorithm) { 146 TEST_F(DiscardableMemoryAllocationAshmemFactoryTest,
135 scoped_ptr<DiscardableMemory> memory1(allocator_.Allocate(3 * kPageSize)); 147 AllocateUsesBestFitAlgorithm) {
148 scoped_ptr<DiscardableMemoryAllocation> memory1(
149 factory_.CreateLockedAllocation(3 * kPageSize));
136 ASSERT_TRUE(memory1); 150 ASSERT_TRUE(memory1);
137 scoped_ptr<DiscardableMemory> memory2(allocator_.Allocate(2 * kPageSize)); 151 scoped_ptr<DiscardableMemoryAllocation> memory2(
152 factory_.CreateLockedAllocation(2 * kPageSize));
138 ASSERT_TRUE(memory2); 153 ASSERT_TRUE(memory2);
139 scoped_ptr<DiscardableMemory> memory3(allocator_.Allocate(1 * kPageSize)); 154 scoped_ptr<DiscardableMemoryAllocation> memory3(
155 factory_.CreateLockedAllocation(1 * kPageSize));
140 ASSERT_TRUE(memory3); 156 ASSERT_TRUE(memory3);
141 void* const address_3 = memory3->Memory(); 157 void* const address_3 = memory3->Memory();
142 memory1.reset(); 158 memory1.reset();
143 // Don't free |memory2| to avoid merging the 3 blocks together. 159 // Don't free |memory2| to avoid merging the 3 blocks together.
144 memory3.reset(); 160 memory3.reset();
145 memory1 = allocator_.Allocate(1 * kPageSize); 161 memory1 = factory_.CreateLockedAllocation(1 * kPageSize);
146 ASSERT_TRUE(memory1); 162 ASSERT_TRUE(memory1);
147 // The chunk whose size is closest to the requested size should be reused. 163 // The chunk whose size is closest to the requested size should be reused.
148 EXPECT_EQ(address_3, memory1->Memory()); 164 EXPECT_EQ(address_3, memory1->Memory());
149 WriteToDiscardableMemory(memory1.get(), kPageSize); 165 WriteToDiscardableMemory(memory1.get(), kPageSize);
150 } 166 }
151 167
152 TEST_F(DiscardableMemoryAllocatorTest, MergeFreeChunks) { 168 TEST_F(DiscardableMemoryAllocationAshmemFactoryTest, MergeFreeChunks) {
153 scoped_ptr<DiscardableMemory> memory1(allocator_.Allocate(kPageSize)); 169 scoped_ptr<DiscardableMemoryAllocation> memory1(
170 factory_.CreateLockedAllocation(kPageSize));
154 ASSERT_TRUE(memory1); 171 ASSERT_TRUE(memory1);
155 scoped_ptr<DiscardableMemory> memory2(allocator_.Allocate(kPageSize)); 172 scoped_ptr<DiscardableMemoryAllocation> memory2(
173 factory_.CreateLockedAllocation(kPageSize));
156 ASSERT_TRUE(memory2); 174 ASSERT_TRUE(memory2);
157 scoped_ptr<DiscardableMemory> memory3(allocator_.Allocate(kPageSize)); 175 scoped_ptr<DiscardableMemoryAllocation> memory3(
176 factory_.CreateLockedAllocation(kPageSize));
158 ASSERT_TRUE(memory3); 177 ASSERT_TRUE(memory3);
159 scoped_ptr<DiscardableMemory> memory4(allocator_.Allocate(kPageSize)); 178 scoped_ptr<DiscardableMemoryAllocation> memory4(
179 factory_.CreateLockedAllocation(kPageSize));
160 ASSERT_TRUE(memory4); 180 ASSERT_TRUE(memory4);
161 void* const memory1_address = memory1->Memory(); 181 void* const memory1_address = memory1->Memory();
162 memory1.reset(); 182 memory1.reset();
163 memory3.reset(); 183 memory3.reset();
164 // Freeing |memory2| (located between memory1 and memory3) should merge the 184 // Freeing |memory2| (located between memory1 and memory3) should merge the
165 // three free blocks together. 185 // three free blocks together.
166 memory2.reset(); 186 memory2.reset();
167 memory1 = allocator_.Allocate(3 * kPageSize); 187 memory1 = factory_.CreateLockedAllocation(3 * kPageSize);
168 EXPECT_EQ(memory1_address, memory1->Memory()); 188 EXPECT_EQ(memory1_address, memory1->Memory());
169 } 189 }
170 190
171 TEST_F(DiscardableMemoryAllocatorTest, MergeFreeChunksAdvanced) { 191 TEST_F(DiscardableMemoryAllocationAshmemFactoryTest, MergeFreeChunksAdvanced) {
172 scoped_ptr<DiscardableMemory> memory1(allocator_.Allocate(4 * kPageSize)); 192 scoped_ptr<DiscardableMemoryAllocation> memory1(
193 factory_.CreateLockedAllocation(4 * kPageSize));
173 ASSERT_TRUE(memory1); 194 ASSERT_TRUE(memory1);
174 scoped_ptr<DiscardableMemory> memory2(allocator_.Allocate(4 * kPageSize)); 195 scoped_ptr<DiscardableMemoryAllocation> memory2(
196 factory_.CreateLockedAllocation(4 * kPageSize));
175 ASSERT_TRUE(memory2); 197 ASSERT_TRUE(memory2);
176 void* const memory1_address = memory1->Memory(); 198 void* const memory1_address = memory1->Memory();
177 memory1.reset(); 199 memory1.reset();
178 memory1 = allocator_.Allocate(2 * kPageSize); 200 memory1 = factory_.CreateLockedAllocation(2 * kPageSize);
179 memory2.reset(); 201 memory2.reset();
180 // At this point, the region should be in this state: 202 // At this point, the region should be in this state:
181 // 8 KBytes (used), 24 KBytes (free). 203 // 8 KBytes (used), 24 KBytes (free).
182 memory2 = allocator_.Allocate(6 * kPageSize); 204 memory2 = factory_.CreateLockedAllocation(6 * kPageSize);
183 EXPECT_EQ( 205 EXPECT_EQ(
184 static_cast<const char*>(memory2->Memory()), 206 static_cast<const char*>(memory2->Memory()),
185 static_cast<const char*>(memory1_address) + 2 * kPageSize); 207 static_cast<const char*>(memory1_address) + 2 * kPageSize);
186 } 208 }
187 209
188 TEST_F(DiscardableMemoryAllocatorTest, MergeFreeChunksAdvanced2) { 210 TEST_F(DiscardableMemoryAllocationAshmemFactoryTest, MergeFreeChunksAdvanced2) {
189 scoped_ptr<DiscardableMemory> memory1(allocator_.Allocate(4 * kPageSize)); 211 scoped_ptr<DiscardableMemoryAllocation> memory1(
212 factory_.CreateLockedAllocation(4 * kPageSize));
190 ASSERT_TRUE(memory1); 213 ASSERT_TRUE(memory1);
191 scoped_ptr<DiscardableMemory> memory2(allocator_.Allocate(4 * kPageSize)); 214 scoped_ptr<DiscardableMemoryAllocation> memory2(
215 factory_.CreateLockedAllocation(4 * kPageSize));
192 ASSERT_TRUE(memory2); 216 ASSERT_TRUE(memory2);
193 void* const memory1_address = memory1->Memory(); 217 void* const memory1_address = memory1->Memory();
194 memory1.reset(); 218 memory1.reset();
195 memory1 = allocator_.Allocate(2 * kPageSize); 219 memory1 = factory_.CreateLockedAllocation(2 * kPageSize);
196 scoped_ptr<DiscardableMemory> memory3(allocator_.Allocate(2 * kPageSize)); 220 scoped_ptr<DiscardableMemoryAllocation> memory3(
221 factory_.CreateLockedAllocation(2 * kPageSize));
197 // At this point, the region should be in this state: 222 // At this point, the region should be in this state:
198 // 8 KBytes (used), 8 KBytes (used), 16 KBytes (used). 223 // 8 KBytes (used), 8 KBytes (used), 16 KBytes (used).
199 memory3.reset(); 224 memory3.reset();
200 memory2.reset(); 225 memory2.reset();
201 // At this point, the region should be in this state: 226 // At this point, the region should be in this state:
202 // 8 KBytes (used), 24 KBytes (free). 227 // 8 KBytes (used), 24 KBytes (free).
203 memory2 = allocator_.Allocate(6 * kPageSize); 228 memory2 = factory_.CreateLockedAllocation(6 * kPageSize);
204 EXPECT_EQ( 229 EXPECT_EQ(
205 static_cast<const char*>(memory2->Memory()), 230 static_cast<const char*>(memory2->Memory()),
206 static_cast<const char*>(memory1_address) + 2 * kPageSize); 231 static_cast<const char*>(memory1_address) + 2 * kPageSize);
207 } 232 }
208 233
209 TEST_F(DiscardableMemoryAllocatorTest, MergeFreeChunksAndDeleteAshmemRegion) { 234 TEST_F(DiscardableMemoryAllocationAshmemFactoryTest,
210 scoped_ptr<DiscardableMemory> memory1(allocator_.Allocate(4 * kPageSize)); 235 MergeFreeChunksAndDeleteAshmemRegion) {
236 scoped_ptr<DiscardableMemoryAllocation> memory1(
237 factory_.CreateLockedAllocation(4 * kPageSize));
211 ASSERT_TRUE(memory1); 238 ASSERT_TRUE(memory1);
212 scoped_ptr<DiscardableMemory> memory2(allocator_.Allocate(4 * kPageSize)); 239 scoped_ptr<DiscardableMemoryAllocation> memory2(
240 factory_.CreateLockedAllocation(4 * kPageSize));
213 ASSERT_TRUE(memory2); 241 ASSERT_TRUE(memory2);
214 memory1.reset(); 242 memory1.reset();
215 memory1 = allocator_.Allocate(2 * kPageSize); 243 memory1 = factory_.CreateLockedAllocation(2 * kPageSize);
216 scoped_ptr<DiscardableMemory> memory3(allocator_.Allocate(2 * kPageSize)); 244 scoped_ptr<DiscardableMemoryAllocation> memory3(
245 factory_.CreateLockedAllocation(2 * kPageSize));
217 // At this point, the region should be in this state: 246 // At this point, the region should be in this state:
218 // 8 KBytes (used), 8 KBytes (used), 16 KBytes (used). 247 // 8 KBytes (used), 8 KBytes (used), 16 KBytes (used).
219 memory1.reset(); 248 memory1.reset();
220 memory3.reset(); 249 memory3.reset();
221 // At this point, the region should be in this state: 250 // At this point, the region should be in this state:
222 // 8 KBytes (free), 8 KBytes (used), 8 KBytes (free). 251 // 8 KBytes (free), 8 KBytes (used), 8 KBytes (free).
223 const int kMagic = 0xdeadbeef; 252 const int kMagic = 0xdeadbeef;
224 *static_cast<int*>(memory2->Memory()) = kMagic; 253 *static_cast<int*>(memory2->Memory()) = kMagic;
225 memory2.reset(); 254 memory2.reset();
226 // The whole region should have been deleted. 255 // The whole region should have been deleted.
227 memory2 = allocator_.Allocate(2 * kPageSize); 256 memory2 = factory_.CreateLockedAllocation(2 * kPageSize);
228 EXPECT_NE(kMagic, *static_cast<int*>(memory2->Memory())); 257 EXPECT_NE(kMagic, *static_cast<int*>(memory2->Memory()));
229 } 258 }
230 259
231 TEST_F(DiscardableMemoryAllocatorTest, 260 TEST_F(DiscardableMemoryAllocationAshmemFactoryTest,
232 TooLargeFreeChunksDontCauseTooMuchFragmentationWhenRecycled) { 261 TooLargeFreeChunksDontCauseTooMuchFragmentationWhenRecycled) {
233 // Keep |memory_1| below allocated so that the ashmem region doesn't get 262 // Keep |memory_1| below allocated so that the ashmem region doesn't get
234 // closed when |memory_2| is deleted. 263 // closed when |memory_2| is deleted.
235 scoped_ptr<DiscardableMemory> memory_1(allocator_.Allocate(64 * 1024)); 264 scoped_ptr<DiscardableMemoryAllocation> memory_1(
265 factory_.CreateLockedAllocation(64 * 1024));
236 ASSERT_TRUE(memory_1); 266 ASSERT_TRUE(memory_1);
237 scoped_ptr<DiscardableMemory> memory_2(allocator_.Allocate(32 * 1024)); 267 scoped_ptr<DiscardableMemoryAllocation> memory_2(
268 factory_.CreateLockedAllocation(32 * 1024));
238 ASSERT_TRUE(memory_2); 269 ASSERT_TRUE(memory_2);
239 void* const address = memory_2->Memory(); 270 void* const address = memory_2->Memory();
240 memory_2.reset(); 271 memory_2.reset();
241 const size_t size = 16 * 1024; 272 const size_t size = 16 * 1024;
242 memory_2 = allocator_.Allocate(size); 273 memory_2 = factory_.CreateLockedAllocation(size);
243 ASSERT_TRUE(memory_2); 274 ASSERT_TRUE(memory_2);
244 EXPECT_EQ(address, memory_2->Memory()); 275 EXPECT_EQ(address, memory_2->Memory());
245 WriteToDiscardableMemory(memory_2.get(), size); 276 WriteToDiscardableMemory(memory_2.get(), size);
246 scoped_ptr<DiscardableMemory> memory_3(allocator_.Allocate(size)); 277 scoped_ptr<DiscardableMemoryAllocation> memory_3(
278 factory_.CreateLockedAllocation(size));
247 // The unused tail (16 KBytes large) of the previously freed chunk should be 279 // The unused tail (16 KBytes large) of the previously freed chunk should be
248 // reused. 280 // reused.
249 EXPECT_EQ(static_cast<char*>(address) + size, memory_3->Memory()); 281 EXPECT_EQ(static_cast<char*>(address) + size, memory_3->Memory());
250 WriteToDiscardableMemory(memory_3.get(), size); 282 WriteToDiscardableMemory(memory_3.get(), size);
251 } 283 }
252 284
253 TEST_F(DiscardableMemoryAllocatorTest, UseMultipleAshmemRegions) { 285 TEST_F(DiscardableMemoryAllocationAshmemFactoryTest, UseMultipleAshmemRegions) {
254 // Leave one page untouched at the end of the ashmem region. 286 // Leave one page untouched at the end of the ashmem region.
255 const size_t size = kAshmemRegionSizeForTesting - kPageSize; 287 const size_t size = kAshmemRegionSizeForTesting - kPageSize;
256 scoped_ptr<DiscardableMemory> memory1(allocator_.Allocate(size)); 288 scoped_ptr<DiscardableMemoryAllocation> memory1(
289 factory_.CreateLockedAllocation(size));
257 ASSERT_TRUE(memory1); 290 ASSERT_TRUE(memory1);
258 WriteToDiscardableMemory(memory1.get(), size); 291 WriteToDiscardableMemory(memory1.get(), size);
259 292
260 scoped_ptr<DiscardableMemory> memory2( 293 scoped_ptr<DiscardableMemoryAllocation> memory2(
261 allocator_.Allocate(kAshmemRegionSizeForTesting)); 294 factory_.CreateLockedAllocation(kAshmemRegionSizeForTesting));
262 ASSERT_TRUE(memory2); 295 ASSERT_TRUE(memory2);
263 WriteToDiscardableMemory(memory2.get(), kAshmemRegionSizeForTesting); 296 WriteToDiscardableMemory(memory2.get(), kAshmemRegionSizeForTesting);
264 // The last page of the first ashmem region should be used for this 297 // The last page of the first ashmem region should be used for this
265 // allocation. 298 // allocation.
266 scoped_ptr<DiscardableMemory> memory3(allocator_.Allocate(kPageSize)); 299 scoped_ptr<DiscardableMemoryAllocation> memory3(
300 factory_.CreateLockedAllocation(kPageSize));
267 ASSERT_TRUE(memory3); 301 ASSERT_TRUE(memory3);
268 WriteToDiscardableMemory(memory3.get(), kPageSize); 302 WriteToDiscardableMemory(memory3.get(), kPageSize);
269 EXPECT_EQ(memory3->Memory(), static_cast<char*>(memory1->Memory()) + size); 303 EXPECT_EQ(memory3->Memory(), static_cast<char*>(memory1->Memory()) + size);
270 } 304 }
271 305
272 TEST_F(DiscardableMemoryAllocatorTest, 306 TEST_F(DiscardableMemoryAllocationAshmemFactoryTest,
273 HighestAllocatedChunkPointerIsUpdatedWhenHighestChunkGetsSplit) { 307 HighestAllocatedChunkPointerIsUpdatedWhenHighestChunkGetsSplit) {
274 // Prevents the ashmem region from getting closed when |memory2| gets freed. 308 // Prevents the ashmem region from getting closed when |memory2| gets freed.
275 scoped_ptr<DiscardableMemory> memory1(allocator_.Allocate(kPageSize)); 309 scoped_ptr<DiscardableMemoryAllocation> memory1(
310 factory_.CreateLockedAllocation(kPageSize));
276 ASSERT_TRUE(memory1); 311 ASSERT_TRUE(memory1);
277 312
278 scoped_ptr<DiscardableMemory> memory2(allocator_.Allocate(4 * kPageSize)); 313 scoped_ptr<DiscardableMemoryAllocation> memory2(
314 factory_.CreateLockedAllocation(4 * kPageSize));
279 ASSERT_TRUE(memory2); 315 ASSERT_TRUE(memory2);
280 316
281 memory2.reset(); 317 memory2.reset();
282 memory2 = allocator_.Allocate(kPageSize); 318 memory2 = factory_.CreateLockedAllocation(kPageSize);
283 // There should now be a free chunk of size 3 * |kPageSize| starting at offset 319 // There should now be a free chunk of size 3 * |kPageSize| starting at offset
284 // 2 * |kPageSize| and the pointer to the highest allocated chunk should have 320 // 2 * |kPageSize| and the pointer to the highest allocated chunk should have
285 // also been updated to |base_| + 2 * |kPageSize|. This pointer is used to 321 // also been updated to |base_| + 2 * |kPageSize|. This pointer is used to
286 // maintain the container mapping a chunk address to its previous chunk and 322 // maintain the container mapping a chunk address to its previous chunk and
287 // this map is in turn used while merging previous contiguous chunks. 323 // this map is in turn used while merging previous contiguous chunks.
288 324
289 // Allocate more than 3 * |kPageSize| so that the free chunk of size 3 * 325 // Allocate more than 3 * |kPageSize| so that the free chunk of size 3 *
290 // |kPageSize| is not reused and |highest_allocated_chunk_| gets used instead. 326 // |kPageSize| is not reused and |highest_allocated_chunk_| gets used instead.
291 scoped_ptr<DiscardableMemory> memory3(allocator_.Allocate(4 * kPageSize)); 327 scoped_ptr<DiscardableMemoryAllocation> memory3(
328 factory_.CreateLockedAllocation(4 * kPageSize));
292 ASSERT_TRUE(memory3); 329 ASSERT_TRUE(memory3);
293 330
294 // Deleting |memory3| (whose size is 4 * |kPageSize|) should result in a merge 331 // Deleting |memory3| (whose size is 4 * |kPageSize|) should result in a merge
295 // with its previous chunk which is the free chunk of size |3 * kPageSize|. 332 // with its previous chunk which is the free chunk of size |3 * kPageSize|.
296 memory3.reset(); 333 memory3.reset();
297 memory3 = allocator_.Allocate((3 + 4) * kPageSize); 334 memory3 = factory_.CreateLockedAllocation((3 + 4) * kPageSize);
298 EXPECT_EQ(memory3->Memory(), 335 EXPECT_EQ(memory3->Memory(),
299 static_cast<const char*>(memory2->Memory()) + kPageSize); 336 static_cast<const char*>(memory2->Memory()) + kPageSize);
300 } 337 }
301 338
302 } // namespace internal 339 } // namespace internal
303 } // namespace base 340 } // namespace base
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698