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

Side by Side Diff: base/metrics/persistent_memory_allocator_unittest.cc

Issue 2578323002: Improved support for objects inside persistent memory. (Closed)
Patch Set: rebased Created 3 years, 11 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
OLDNEW
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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698