OLD | NEW |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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/metrics/persistent_memory_allocator.h" | 5 #include "base/metrics/persistent_memory_allocator.h" |
6 | 6 |
7 #include <memory> | 7 #include <memory> |
8 | 8 |
9 #include "base/files/file.h" | 9 #include "base/files/file.h" |
10 #include "base/files/file_util.h" | 10 #include "base/files/file_util.h" |
(...skipping 22 matching lines...) Expand all Loading... |
33 typedef PersistentMemoryAllocator::Reference Reference; | 33 typedef PersistentMemoryAllocator::Reference Reference; |
34 | 34 |
35 class PersistentMemoryAllocatorTest : public testing::Test { | 35 class PersistentMemoryAllocatorTest : public testing::Test { |
36 public: | 36 public: |
37 // This can't be statically initialized because it's value isn't defined | 37 // This can't be statically initialized because it's value isn't defined |
38 // in the PersistentMemoryAllocator header file. Instead, it's simply set | 38 // in the PersistentMemoryAllocator header file. Instead, it's simply set |
39 // in the constructor. | 39 // in the constructor. |
40 uint32_t kAllocAlignment; | 40 uint32_t kAllocAlignment; |
41 | 41 |
42 struct TestObject1 { | 42 struct TestObject1 { |
| 43 static constexpr uint32_t kPersistentTypeId = 1; |
43 static constexpr size_t kExpectedInstanceSize = 4 + 1 + 3; | 44 static constexpr size_t kExpectedInstanceSize = 4 + 1 + 3; |
44 int32_t onething; | 45 int32_t onething; |
45 char oranother; | 46 char oranother; |
46 }; | 47 }; |
47 | 48 |
48 struct TestObject2 { | 49 struct TestObject2 { |
| 50 static constexpr uint32_t kPersistentTypeId = 2; |
49 static constexpr size_t kExpectedInstanceSize = 8 + 4 + 4 + 8 + 8; | 51 static constexpr size_t kExpectedInstanceSize = 8 + 4 + 4 + 8 + 8; |
50 int64_t thiis; | 52 int64_t thiis; |
51 int32_t that; | 53 int32_t that; |
52 float andthe; | 54 float andthe; |
53 double other; | 55 double other; |
54 char thing[8]; | 56 char thing[8]; |
55 }; | 57 }; |
56 | 58 |
57 PersistentMemoryAllocatorTest() { | 59 PersistentMemoryAllocatorTest() { |
58 kAllocAlignment = GetAllocAlignment(); | 60 kAllocAlignment = GetAllocAlignment(); |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
102 allocator_->allocs_histogram_->histogram_name()); | 104 allocator_->allocs_histogram_->histogram_name()); |
103 | 105 |
104 // Get base memory info for later comparison. | 106 // Get base memory info for later comparison. |
105 PersistentMemoryAllocator::MemoryInfo meminfo0; | 107 PersistentMemoryAllocator::MemoryInfo meminfo0; |
106 allocator_->GetMemoryInfo(&meminfo0); | 108 allocator_->GetMemoryInfo(&meminfo0); |
107 EXPECT_EQ(TEST_MEMORY_SIZE, meminfo0.total); | 109 EXPECT_EQ(TEST_MEMORY_SIZE, meminfo0.total); |
108 EXPECT_GT(meminfo0.total, meminfo0.free); | 110 EXPECT_GT(meminfo0.total, meminfo0.free); |
109 | 111 |
110 // Validate allocation of test object and make sure it can be referenced | 112 // Validate allocation of test object and make sure it can be referenced |
111 // and all metadata looks correct. | 113 // and all metadata looks correct. |
112 Reference block1 = allocator_->Allocate(sizeof(TestObject1), 1); | 114 TestObject1* obj1 = allocator_->AllocateObject<TestObject1>(); |
113 EXPECT_NE(0U, block1); | 115 ASSERT_TRUE(obj1); |
114 EXPECT_NE(nullptr, allocator_->GetAsObject<TestObject1>(block1, 1)); | 116 Reference block1 = allocator_->GetAsReference(obj1); |
115 EXPECT_EQ(nullptr, allocator_->GetAsObject<TestObject2>(block1, 1)); | 117 ASSERT_NE(0U, block1); |
| 118 EXPECT_NE(nullptr, allocator_->GetAsObject<TestObject1>(block1)); |
| 119 EXPECT_EQ(nullptr, allocator_->GetAsObject<TestObject2>(block1)); |
116 EXPECT_LE(sizeof(TestObject1), allocator_->GetAllocSize(block1)); | 120 EXPECT_LE(sizeof(TestObject1), allocator_->GetAllocSize(block1)); |
117 EXPECT_GT(sizeof(TestObject1) + kAllocAlignment, | 121 EXPECT_GT(sizeof(TestObject1) + kAllocAlignment, |
118 allocator_->GetAllocSize(block1)); | 122 allocator_->GetAllocSize(block1)); |
119 PersistentMemoryAllocator::MemoryInfo meminfo1; | 123 PersistentMemoryAllocator::MemoryInfo meminfo1; |
120 allocator_->GetMemoryInfo(&meminfo1); | 124 allocator_->GetMemoryInfo(&meminfo1); |
121 EXPECT_EQ(meminfo0.total, meminfo1.total); | 125 EXPECT_EQ(meminfo0.total, meminfo1.total); |
122 EXPECT_GT(meminfo0.free, meminfo1.free); | 126 EXPECT_GT(meminfo0.free, meminfo1.free); |
123 | 127 |
124 // Verify that pointers can be turned back into references and that invalid | 128 // Verify that pointers can be turned back into references and that invalid |
125 // addresses return null. | 129 // addresses return null. |
(...skipping 14 matching lines...) Expand all Loading... |
140 EXPECT_EQ(0U, iter1a.GetNext(&type)); | 144 EXPECT_EQ(0U, iter1a.GetNext(&type)); |
141 allocator_->MakeIterable(block1); | 145 allocator_->MakeIterable(block1); |
142 EXPECT_EQ(block1, iter1a.GetNext(&type)); | 146 EXPECT_EQ(block1, iter1a.GetNext(&type)); |
143 EXPECT_EQ(1U, type); | 147 EXPECT_EQ(1U, type); |
144 EXPECT_EQ(block1, iter1a.GetLast()); | 148 EXPECT_EQ(block1, iter1a.GetLast()); |
145 EXPECT_EQ(0U, iter1a.GetNext(&type)); | 149 EXPECT_EQ(0U, iter1a.GetNext(&type)); |
146 EXPECT_EQ(block1, iter1a.GetLast()); | 150 EXPECT_EQ(block1, iter1a.GetLast()); |
147 | 151 |
148 // Create second test-object and ensure everything is good and it cannot | 152 // Create second test-object and ensure everything is good and it cannot |
149 // be confused with test-object of another type. | 153 // be confused with test-object of another type. |
150 Reference block2 = allocator_->Allocate(sizeof(TestObject2), 2); | 154 TestObject2* obj2 = allocator_->AllocateObject<TestObject2>(); |
151 EXPECT_NE(0U, block2); | 155 ASSERT_TRUE(obj2); |
152 EXPECT_NE(nullptr, allocator_->GetAsObject<TestObject2>(block2, 2)); | 156 Reference block2 = allocator_->GetAsReference(obj2); |
153 EXPECT_EQ(nullptr, allocator_->GetAsObject<TestObject2>(block2, 1)); | 157 ASSERT_NE(0U, block2); |
| 158 EXPECT_NE(nullptr, allocator_->GetAsObject<TestObject2>(block2)); |
| 159 EXPECT_EQ(nullptr, allocator_->GetAsObject<TestObject1>(block2)); |
154 EXPECT_LE(sizeof(TestObject2), allocator_->GetAllocSize(block2)); | 160 EXPECT_LE(sizeof(TestObject2), allocator_->GetAllocSize(block2)); |
155 EXPECT_GT(sizeof(TestObject2) + kAllocAlignment, | 161 EXPECT_GT(sizeof(TestObject2) + kAllocAlignment, |
156 allocator_->GetAllocSize(block2)); | 162 allocator_->GetAllocSize(block2)); |
157 PersistentMemoryAllocator::MemoryInfo meminfo2; | 163 PersistentMemoryAllocator::MemoryInfo meminfo2; |
158 allocator_->GetMemoryInfo(&meminfo2); | 164 allocator_->GetMemoryInfo(&meminfo2); |
159 EXPECT_EQ(meminfo1.total, meminfo2.total); | 165 EXPECT_EQ(meminfo1.total, meminfo2.total); |
160 EXPECT_GT(meminfo1.free, meminfo2.free); | 166 EXPECT_GT(meminfo1.free, meminfo2.free); |
161 | 167 |
162 // Ensure that second test-object can also be made iterable. | 168 // Ensure that second test-object can also be made iterable. |
163 allocator_->MakeIterable(block2); | 169 allocator_->MakeIterable(obj2); |
164 EXPECT_EQ(block2, iter1a.GetNext(&type)); | 170 EXPECT_EQ(block2, iter1a.GetNext(&type)); |
165 EXPECT_EQ(2U, type); | 171 EXPECT_EQ(2U, type); |
166 EXPECT_EQ(block2, iter1a.GetLast()); | 172 EXPECT_EQ(block2, iter1a.GetLast()); |
167 EXPECT_EQ(0U, iter1a.GetNext(&type)); | 173 EXPECT_EQ(0U, iter1a.GetNext(&type)); |
168 EXPECT_EQ(block2, iter1a.GetLast()); | 174 EXPECT_EQ(block2, iter1a.GetLast()); |
169 | 175 |
170 // Check that the iterator can be reset to the beginning. | 176 // Check that the iterator can be reset to the beginning. |
171 iter1a.Reset(); | 177 iter1a.Reset(); |
172 EXPECT_EQ(0U, iter1a.GetLast()); | 178 EXPECT_EQ(0U, iter1a.GetLast()); |
173 EXPECT_EQ(block1, iter1a.GetNext(&type)); | 179 EXPECT_EQ(block1, iter1a.GetNext(&type)); |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
207 EXPECT_EQ(0, allocs_samples->GetCount(0)); | 213 EXPECT_EQ(0, allocs_samples->GetCount(0)); |
208 EXPECT_EQ(1, allocs_samples->GetCount(sizeof(TestObject1))); | 214 EXPECT_EQ(1, allocs_samples->GetCount(sizeof(TestObject1))); |
209 EXPECT_EQ(1, allocs_samples->GetCount(sizeof(TestObject2))); | 215 EXPECT_EQ(1, allocs_samples->GetCount(sizeof(TestObject2))); |
210 #if !DCHECK_IS_ON() // DCHECK builds will die at a NOTREACHED(). | 216 #if !DCHECK_IS_ON() // DCHECK builds will die at a NOTREACHED(). |
211 EXPECT_EQ(0U, allocator_->Allocate(TEST_MEMORY_SIZE + 1, 0)); | 217 EXPECT_EQ(0U, allocator_->Allocate(TEST_MEMORY_SIZE + 1, 0)); |
212 allocs_samples = allocator_->allocs_histogram_->SnapshotSamples(); | 218 allocs_samples = allocator_->allocs_histogram_->SnapshotSamples(); |
213 EXPECT_EQ(3, allocs_samples->TotalCount()); | 219 EXPECT_EQ(3, allocs_samples->TotalCount()); |
214 EXPECT_EQ(1, allocs_samples->GetCount(0)); | 220 EXPECT_EQ(1, allocs_samples->GetCount(0)); |
215 #endif | 221 #endif |
216 | 222 |
217 // Check that an objcet's type can be changed. | 223 // Check that an object's type can be changed. |
218 EXPECT_EQ(2U, allocator_->GetType(block2)); | 224 EXPECT_EQ(2U, allocator_->GetType(block2)); |
219 allocator_->ChangeType(block2, 3, 2); | 225 allocator_->ChangeType(block2, 3, 2); |
220 EXPECT_EQ(3U, allocator_->GetType(block2)); | 226 EXPECT_EQ(3U, allocator_->GetType(block2)); |
221 allocator_->ChangeType(block2, 2, 3); | 227 allocator_->ChangeObject<TestObject2>(block2, 3); |
222 EXPECT_EQ(2U, allocator_->GetType(block2)); | 228 EXPECT_EQ(2U, allocator_->GetType(block2)); |
223 | 229 |
224 // Create second allocator (read/write) using the same memory segment. | 230 // Create second allocator (read/write) using the same memory segment. |
225 std::unique_ptr<PersistentMemoryAllocator> allocator2( | 231 std::unique_ptr<PersistentMemoryAllocator> allocator2( |
226 new PersistentMemoryAllocator(mem_segment_.get(), TEST_MEMORY_SIZE, | 232 new PersistentMemoryAllocator(mem_segment_.get(), TEST_MEMORY_SIZE, |
227 TEST_MEMORY_PAGE, 0, "", false)); | 233 TEST_MEMORY_PAGE, 0, "", false)); |
228 EXPECT_EQ(TEST_ID, allocator2->Id()); | 234 EXPECT_EQ(TEST_ID, allocator2->Id()); |
229 EXPECT_FALSE(allocator2->used_histogram_); | 235 EXPECT_FALSE(allocator2->used_histogram_); |
230 EXPECT_FALSE(allocator2->allocs_histogram_); | 236 EXPECT_FALSE(allocator2->allocs_histogram_); |
231 EXPECT_NE(allocator2->allocs_histogram_, allocator_->allocs_histogram_); | 237 EXPECT_NE(allocator2->allocs_histogram_, allocator_->allocs_histogram_); |
232 | 238 |
233 // Ensure that iteration and access through second allocator works. | 239 // Ensure that iteration and access through second allocator works. |
234 PersistentMemoryAllocator::Iterator iter2(allocator2.get()); | 240 PersistentMemoryAllocator::Iterator iter2(allocator2.get()); |
235 EXPECT_EQ(block1, iter2.GetNext(&type)); | 241 EXPECT_EQ(block1, iter2.GetNext(&type)); |
236 EXPECT_EQ(block2, iter2.GetNext(&type)); | 242 EXPECT_EQ(block2, iter2.GetNext(&type)); |
237 EXPECT_EQ(0U, iter2.GetNext(&type)); | 243 EXPECT_EQ(0U, iter2.GetNext(&type)); |
238 EXPECT_NE(nullptr, allocator2->GetAsObject<TestObject1>(block1, 1)); | 244 EXPECT_NE(nullptr, allocator2->GetAsObject<TestObject1>(block1)); |
239 EXPECT_NE(nullptr, allocator2->GetAsObject<TestObject2>(block2, 2)); | 245 EXPECT_NE(nullptr, allocator2->GetAsObject<TestObject2>(block2)); |
240 | 246 |
241 // Create a third allocator (read-only) using the same memory segment. | 247 // Create a third allocator (read-only) using the same memory segment. |
242 std::unique_ptr<const PersistentMemoryAllocator> allocator3( | 248 std::unique_ptr<const PersistentMemoryAllocator> allocator3( |
243 new PersistentMemoryAllocator(mem_segment_.get(), TEST_MEMORY_SIZE, | 249 new PersistentMemoryAllocator(mem_segment_.get(), TEST_MEMORY_SIZE, |
244 TEST_MEMORY_PAGE, 0, "", true)); | 250 TEST_MEMORY_PAGE, 0, "", true)); |
245 EXPECT_EQ(TEST_ID, allocator3->Id()); | 251 EXPECT_EQ(TEST_ID, allocator3->Id()); |
246 EXPECT_FALSE(allocator3->used_histogram_); | 252 EXPECT_FALSE(allocator3->used_histogram_); |
247 EXPECT_FALSE(allocator3->allocs_histogram_); | 253 EXPECT_FALSE(allocator3->allocs_histogram_); |
248 | 254 |
249 // Ensure that iteration and access through third allocator works. | 255 // Ensure that iteration and access through third allocator works. |
250 PersistentMemoryAllocator::Iterator iter3(allocator3.get()); | 256 PersistentMemoryAllocator::Iterator iter3(allocator3.get()); |
251 EXPECT_EQ(block1, iter3.GetNext(&type)); | 257 EXPECT_EQ(block1, iter3.GetNext(&type)); |
252 EXPECT_EQ(block2, iter3.GetNext(&type)); | 258 EXPECT_EQ(block2, iter3.GetNext(&type)); |
253 EXPECT_EQ(0U, iter3.GetNext(&type)); | 259 EXPECT_EQ(0U, iter3.GetNext(&type)); |
254 EXPECT_NE(nullptr, allocator3->GetAsObject<TestObject1>(block1, 1)); | 260 EXPECT_NE(nullptr, allocator3->GetAsObject<TestObject1>(block1)); |
255 EXPECT_NE(nullptr, allocator3->GetAsObject<TestObject2>(block2, 2)); | 261 EXPECT_NE(nullptr, allocator3->GetAsObject<TestObject2>(block2)); |
256 | 262 |
257 // Ensure that GetNextOfType works. | 263 // Ensure that GetNextOfType works. |
258 PersistentMemoryAllocator::Iterator iter1c(allocator_.get()); | 264 PersistentMemoryAllocator::Iterator iter1c(allocator_.get()); |
259 EXPECT_EQ(block2, iter1c.GetNextOfType(2)); | 265 EXPECT_EQ(block2, iter1c.GetNextOfType<TestObject2>()); |
260 EXPECT_EQ(0U, iter1c.GetNextOfType(2)); | 266 EXPECT_EQ(0U, iter1c.GetNextOfType(2)); |
| 267 |
| 268 // Ensure that GetNextOfObject works. |
| 269 PersistentMemoryAllocator::Iterator iter1d(allocator_.get()); |
| 270 EXPECT_EQ(obj2, iter1d.GetNextOfObject<TestObject2>()); |
| 271 EXPECT_EQ(nullptr, iter1d.GetNextOfObject<TestObject2>()); |
| 272 |
| 273 // Ensure that deleting an object works. |
| 274 allocator_->DeleteObject(obj2); |
| 275 PersistentMemoryAllocator::Iterator iter1z(allocator_.get()); |
| 276 EXPECT_EQ(nullptr, iter1z.GetNextOfObject<TestObject2>()); |
261 } | 277 } |
262 | 278 |
263 TEST_F(PersistentMemoryAllocatorTest, PageTest) { | 279 TEST_F(PersistentMemoryAllocatorTest, PageTest) { |
264 // This allocation will go into the first memory page. | 280 // This allocation will go into the first memory page. |
265 Reference block1 = allocator_->Allocate(TEST_MEMORY_PAGE / 2, 1); | 281 Reference block1 = allocator_->Allocate(TEST_MEMORY_PAGE / 2, 1); |
266 EXPECT_LT(0U, block1); | 282 EXPECT_LT(0U, block1); |
267 EXPECT_GT(TEST_MEMORY_PAGE, block1); | 283 EXPECT_GT(TEST_MEMORY_PAGE, block1); |
268 | 284 |
269 // This allocation won't fit in same page as previous block. | 285 // This allocation won't fit in same page as previous block. |
270 Reference block2 = | 286 Reference block2 = |
(...skipping 571 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
842 // For filesize >= minsize, the file must be acceptable. This | 858 // For filesize >= minsize, the file must be acceptable. This |
843 // else clause (file-not-acceptable) should be reached only if | 859 // else clause (file-not-acceptable) should be reached only if |
844 // filesize < minsize. | 860 // filesize < minsize. |
845 EXPECT_GT(minsize, filesize); | 861 EXPECT_GT(minsize, filesize); |
846 } | 862 } |
847 } | 863 } |
848 } | 864 } |
849 #endif // !defined(OS_NACL) | 865 #endif // !defined(OS_NACL) |
850 | 866 |
851 } // namespace base | 867 } // namespace base |
OLD | NEW |