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

Side by Side Diff: Source/wtf/PartitionAllocTest.cpp

Issue 1184043002: Fix unit test style in Source/wtf/. (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Created 5 years, 6 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 /* 1 /*
2 * Copyright (C) 2013 Google Inc. All rights reserved. 2 * Copyright (C) 2013 Google Inc. All rights reserved.
3 * 3 *
4 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are 5 * modification, are permitted provided that the following conditions are
6 * met: 6 * met:
7 * 7 *
8 * * Redistributions of source code must retain the above copyright 8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer. 9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above 10 * * Redistributions in binary form must reproduce the above
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
45 #include <sys/resource.h> 45 #include <sys/resource.h>
46 #include <sys/time.h> 46 #include <sys/time.h>
47 47
48 #ifndef MAP_ANONYMOUS 48 #ifndef MAP_ANONYMOUS
49 #define MAP_ANONYMOUS MAP_ANON 49 #define MAP_ANONYMOUS MAP_ANON
50 #endif 50 #endif
51 #endif // OS(POSIX) 51 #endif // OS(POSIX)
52 52
53 #if !defined(MEMORY_TOOL_REPLACES_ALLOCATOR) 53 #if !defined(MEMORY_TOOL_REPLACES_ALLOCATOR)
54 54
55 namespace { 55 namespace WTF {
56 56
57 static const size_t kTestMaxAllocation = 4096; 57 static const size_t kTestMaxAllocation = 4096;
kochi 2015/06/15 03:34:22 How about using 'namespace {}' to remove all the '
tkent 2015/06/15 04:45:57 Done.
58 static SizeSpecificPartitionAllocator<kTestMaxAllocation> allocator; 58 static SizeSpecificPartitionAllocator<kTestMaxAllocation> allocator;
59 static PartitionAllocatorGeneric genericAllocator; 59 static PartitionAllocatorGeneric genericAllocator;
60 60
61 static const size_t kTestAllocSize = 16; 61 static const size_t kTestAllocSize = 16;
62 #if !ENABLE(ASSERT) 62 #if !ENABLE(ASSERT)
63 static const size_t kPointerOffset = 0; 63 static const size_t kPointerOffset = 0;
64 static const size_t kExtraAllocSize = 0; 64 static const size_t kExtraAllocSize = 0;
65 #else 65 #else
66 static const size_t kPointerOffset = WTF::kCookieSize; 66 static const size_t kPointerOffset = WTF::kCookieSize;
67 static const size_t kExtraAllocSize = WTF::kCookieSize * 2; 67 static const size_t kExtraAllocSize = WTF::kCookieSize * 2;
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
116 return false; 116 return false;
117 limit.rlim_cur = limit.rlim_max; 117 limit.rlim_cur = limit.rlim_max;
118 if (setrlimit(RLIMIT_AS, &limit) != 0) 118 if (setrlimit(RLIMIT_AS, &limit) != 0)
119 return false; 119 return false;
120 return true; 120 return true;
121 #else 121 #else
122 return false; 122 return false;
123 #endif 123 #endif
124 } 124 }
125 125
126 static WTF::PartitionPage* GetFullPage(size_t size) 126 static PartitionPage* GetFullPage(size_t size)
127 { 127 {
128 size_t realSize = size + kExtraAllocSize; 128 size_t realSize = size + kExtraAllocSize;
129 size_t bucketIdx = realSize >> WTF::kBucketShift; 129 size_t bucketIdx = realSize >> kBucketShift;
130 WTF::PartitionBucket* bucket = &allocator.root()->buckets()[bucketIdx]; 130 PartitionBucket* bucket = &allocator.root()->buckets()[bucketIdx];
131 size_t numSlots = (bucket->numSystemPagesPerSlotSpan * WTF::kSystemPageSize) / realSize; 131 size_t numSlots = (bucket->numSystemPagesPerSlotSpan * kSystemPageSize) / re alSize;
132 void* first = 0; 132 void* first = 0;
133 void* last = 0; 133 void* last = 0;
134 size_t i; 134 size_t i;
135 for (i = 0; i < numSlots; ++i) { 135 for (i = 0; i < numSlots; ++i) {
136 void* ptr = partitionAlloc(allocator.root(), size); 136 void* ptr = partitionAlloc(allocator.root(), size);
137 EXPECT_TRUE(ptr); 137 EXPECT_TRUE(ptr);
138 if (!i) 138 if (!i)
139 first = WTF::partitionCookieFreePointerAdjust(ptr); 139 first = partitionCookieFreePointerAdjust(ptr);
140 else if (i == numSlots - 1) 140 else if (i == numSlots - 1)
141 last = WTF::partitionCookieFreePointerAdjust(ptr); 141 last = partitionCookieFreePointerAdjust(ptr);
142 } 142 }
143 EXPECT_EQ(WTF::partitionPointerToPage(first), WTF::partitionPointerToPage(la st)); 143 EXPECT_EQ(partitionPointerToPage(first), partitionPointerToPage(last));
144 if (bucket->numSystemPagesPerSlotSpan == WTF::kNumSystemPagesPerPartitionPag e) 144 if (bucket->numSystemPagesPerSlotSpan == kNumSystemPagesPerPartitionPage)
145 EXPECT_EQ(reinterpret_cast<size_t>(first) & WTF::kPartitionPageBaseMask, reinterpret_cast<size_t>(last) & WTF::kPartitionPageBaseMask); 145 EXPECT_EQ(reinterpret_cast<size_t>(first) & kPartitionPageBaseMask, rein terpret_cast<size_t>(last) & kPartitionPageBaseMask);
146 EXPECT_EQ(numSlots, static_cast<size_t>(bucket->activePagesHead->numAllocate dSlots)); 146 EXPECT_EQ(numSlots, static_cast<size_t>(bucket->activePagesHead->numAllocate dSlots));
147 EXPECT_EQ(0, bucket->activePagesHead->freelistHead); 147 EXPECT_EQ(0, bucket->activePagesHead->freelistHead);
148 EXPECT_TRUE(bucket->activePagesHead); 148 EXPECT_TRUE(bucket->activePagesHead);
149 EXPECT_TRUE(bucket->activePagesHead != &WTF::PartitionRootGeneric::gSeedPage ); 149 EXPECT_TRUE(bucket->activePagesHead != &PartitionRootGeneric::gSeedPage);
150 return bucket->activePagesHead; 150 return bucket->activePagesHead;
151 } 151 }
152 152
153 static void FreeFullPage(WTF::PartitionPage* page) 153 static void FreeFullPage(PartitionPage* page)
154 { 154 {
155 size_t size = page->bucket->slotSize; 155 size_t size = page->bucket->slotSize;
156 size_t numSlots = (page->bucket->numSystemPagesPerSlotSpan * WTF::kSystemPag eSize) / size; 156 size_t numSlots = (page->bucket->numSystemPagesPerSlotSpan * kSystemPageSize ) / size;
157 EXPECT_EQ(numSlots, static_cast<size_t>(abs(page->numAllocatedSlots))); 157 EXPECT_EQ(numSlots, static_cast<size_t>(abs(page->numAllocatedSlots)));
158 char* ptr = reinterpret_cast<char*>(partitionPageToPointer(page)); 158 char* ptr = reinterpret_cast<char*>(partitionPageToPointer(page));
159 size_t i; 159 size_t i;
160 for (i = 0; i < numSlots; ++i) { 160 for (i = 0; i < numSlots; ++i) {
161 partitionFree(ptr + kPointerOffset); 161 partitionFree(ptr + kPointerOffset);
162 ptr += size; 162 ptr += size;
163 } 163 }
164 } 164 }
165 165
166 static void CycleFreeCache(size_t size) 166 static void CycleFreeCache(size_t size)
167 { 167 {
168 size_t realSize = size + kExtraAllocSize; 168 size_t realSize = size + kExtraAllocSize;
169 size_t bucketIdx = realSize >> WTF::kBucketShift; 169 size_t bucketIdx = realSize >> kBucketShift;
170 WTF::PartitionBucket* bucket = &allocator.root()->buckets()[bucketIdx]; 170 PartitionBucket* bucket = &allocator.root()->buckets()[bucketIdx];
171 ASSERT(!bucket->activePagesHead->numAllocatedSlots); 171 ASSERT(!bucket->activePagesHead->numAllocatedSlots);
172 172
173 for (size_t i = 0; i < WTF::kMaxFreeableSpans; ++i) { 173 for (size_t i = 0; i < kMaxFreeableSpans; ++i) {
174 void* ptr = partitionAlloc(allocator.root(), size); 174 void* ptr = partitionAlloc(allocator.root(), size);
175 EXPECT_EQ(1, bucket->activePagesHead->numAllocatedSlots); 175 EXPECT_EQ(1, bucket->activePagesHead->numAllocatedSlots);
176 partitionFree(ptr); 176 partitionFree(ptr);
177 EXPECT_EQ(0, bucket->activePagesHead->numAllocatedSlots); 177 EXPECT_EQ(0, bucket->activePagesHead->numAllocatedSlots);
178 EXPECT_NE(-1, bucket->activePagesHead->emptyCacheIndex); 178 EXPECT_NE(-1, bucket->activePagesHead->emptyCacheIndex);
179 } 179 }
180 } 180 }
181 181
182 static void CycleGenericFreeCache(size_t size) 182 static void CycleGenericFreeCache(size_t size)
183 { 183 {
184 for (size_t i = 0; i < WTF::kMaxFreeableSpans; ++i) { 184 for (size_t i = 0; i < kMaxFreeableSpans; ++i) {
185 void* ptr = partitionAllocGeneric(genericAllocator.root(), size); 185 void* ptr = partitionAllocGeneric(genericAllocator.root(), size);
186 WTF::PartitionPage* page = WTF::partitionPointerToPage(WTF::partitionCoo kieFreePointerAdjust(ptr)); 186 PartitionPage* page = partitionPointerToPage(partitionCookieFreePointerA djust(ptr));
187 WTF::PartitionBucket* bucket = page->bucket; 187 PartitionBucket* bucket = page->bucket;
188 EXPECT_EQ(1, bucket->activePagesHead->numAllocatedSlots); 188 EXPECT_EQ(1, bucket->activePagesHead->numAllocatedSlots);
189 partitionFreeGeneric(genericAllocator.root(), ptr); 189 partitionFreeGeneric(genericAllocator.root(), ptr);
190 EXPECT_EQ(0, bucket->activePagesHead->numAllocatedSlots); 190 EXPECT_EQ(0, bucket->activePagesHead->numAllocatedSlots);
191 EXPECT_NE(-1, bucket->activePagesHead->emptyCacheIndex); 191 EXPECT_NE(-1, bucket->activePagesHead->emptyCacheIndex);
192 } 192 }
193 } 193 }
194 194
195 class MockPartitionStatsDumper : public WTF::PartitionStatsDumper { 195 class MockPartitionStatsDumper : public PartitionStatsDumper {
196 public: 196 public:
197 MockPartitionStatsDumper() 197 MockPartitionStatsDumper()
198 : m_totalResidentBytes(0) 198 : m_totalResidentBytes(0)
199 , m_totalActiveBytes(0) { } 199 , m_totalActiveBytes(0) { }
200 200
201 virtual void partitionsDumpBucketStats(const char* partitionName, const WTF: :PartitionBucketMemoryStats* memoryStats) override 201 virtual void partitionsDumpBucketStats(const char* partitionName, const Part itionBucketMemoryStats* memoryStats) override
202 { 202 {
203 (void) partitionName; 203 (void) partitionName;
204 EXPECT_TRUE(memoryStats->isValid); 204 EXPECT_TRUE(memoryStats->isValid);
205 EXPECT_EQ(0u, memoryStats->bucketSlotSize & WTF::kAllocationGranularityM ask); 205 EXPECT_EQ(0u, memoryStats->bucketSlotSize & kAllocationGranularityMask);
206 m_bucketStats.append(*memoryStats); 206 m_bucketStats.append(*memoryStats);
207 m_totalResidentBytes += memoryStats->residentBytes; 207 m_totalResidentBytes += memoryStats->residentBytes;
208 m_totalActiveBytes += memoryStats->activeBytes; 208 m_totalActiveBytes += memoryStats->activeBytes;
209 } 209 }
210 210
211 bool IsMemoryAllocationRecorded() 211 bool IsMemoryAllocationRecorded()
212 { 212 {
213 return m_totalResidentBytes != 0 && m_totalActiveBytes != 0; 213 return m_totalResidentBytes != 0 && m_totalActiveBytes != 0;
214 } 214 }
215 215
216 const WTF::PartitionBucketMemoryStats* GetBucketStats(size_t bucketSize) 216 const PartitionBucketMemoryStats* GetBucketStats(size_t bucketSize)
217 { 217 {
218 for (size_t i = 0; i < m_bucketStats.size(); ++i) { 218 for (size_t i = 0; i < m_bucketStats.size(); ++i) {
219 if (m_bucketStats[i].bucketSlotSize == bucketSize) 219 if (m_bucketStats[i].bucketSlotSize == bucketSize)
220 return &m_bucketStats[i]; 220 return &m_bucketStats[i];
221 } 221 }
222 return 0; 222 return 0;
223 } 223 }
224 224
225 private: 225 private:
226 size_t m_totalResidentBytes; 226 size_t m_totalResidentBytes;
227 size_t m_totalActiveBytes; 227 size_t m_totalActiveBytes;
228 228
229 Vector<WTF::PartitionBucketMemoryStats> m_bucketStats; 229 Vector<PartitionBucketMemoryStats> m_bucketStats;
230 }; 230 };
231 231
232 // Check that the most basic of allocate / free pairs work. 232 // Check that the most basic of allocate / free pairs work.
233 TEST(PartitionAllocTest, Basic) 233 TEST(PartitionAllocTest, Basic)
234 { 234 {
235 TestSetup(); 235 TestSetup();
236 WTF::PartitionBucket* bucket = &allocator.root()->buckets()[kTestBucketIndex ]; 236 PartitionBucket* bucket = &allocator.root()->buckets()[kTestBucketIndex];
237 WTF::PartitionPage* seedPage = &WTF::PartitionRootGeneric::gSeedPage; 237 PartitionPage* seedPage = &PartitionRootGeneric::gSeedPage;
238 238
239 EXPECT_FALSE(bucket->emptyPagesHead); 239 EXPECT_FALSE(bucket->emptyPagesHead);
240 EXPECT_EQ(seedPage, bucket->activePagesHead); 240 EXPECT_EQ(seedPage, bucket->activePagesHead);
241 EXPECT_EQ(0, bucket->activePagesHead->nextPage); 241 EXPECT_EQ(0, bucket->activePagesHead->nextPage);
242 242
243 void* ptr = partitionAlloc(allocator.root(), kTestAllocSize); 243 void* ptr = partitionAlloc(allocator.root(), kTestAllocSize);
244 EXPECT_TRUE(ptr); 244 EXPECT_TRUE(ptr);
245 EXPECT_EQ(kPointerOffset, reinterpret_cast<size_t>(ptr) & WTF::kPartitionPag eOffsetMask); 245 EXPECT_EQ(kPointerOffset, reinterpret_cast<size_t>(ptr) & kPartitionPageOffs etMask);
246 // Check that the offset appears to include a guard page. 246 // Check that the offset appears to include a guard page.
247 EXPECT_EQ(WTF::kPartitionPageSize + kPointerOffset, reinterpret_cast<size_t> (ptr) & WTF::kSuperPageOffsetMask); 247 EXPECT_EQ(kPartitionPageSize + kPointerOffset, reinterpret_cast<size_t>(ptr) & kSuperPageOffsetMask);
248 248
249 partitionFree(ptr); 249 partitionFree(ptr);
250 // Expect that the last active page does not get tossed to the freelist. 250 // Expect that the last active page does not get tossed to the freelist.
251 EXPECT_FALSE(bucket->emptyPagesHead); 251 EXPECT_FALSE(bucket->emptyPagesHead);
252 252
253 TestShutdown(); 253 TestShutdown();
254 } 254 }
255 255
256 // Check that we can detect a memory leak. 256 // Check that we can detect a memory leak.
257 TEST(PartitionAllocTest, SimpleLeak) 257 TEST(PartitionAllocTest, SimpleLeak)
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
298 partitionFree(ptr2); 298 partitionFree(ptr2);
299 partitionFree(ptr3); 299 partitionFree(ptr3);
300 300
301 TestShutdown(); 301 TestShutdown();
302 } 302 }
303 303
304 // Test a bucket with multiple pages. 304 // Test a bucket with multiple pages.
305 TEST(PartitionAllocTest, MultiPages) 305 TEST(PartitionAllocTest, MultiPages)
306 { 306 {
307 TestSetup(); 307 TestSetup();
308 WTF::PartitionBucket* bucket = &allocator.root()->buckets()[kTestBucketIndex ]; 308 PartitionBucket* bucket = &allocator.root()->buckets()[kTestBucketIndex];
309 309
310 WTF::PartitionPage* page = GetFullPage(kTestAllocSize); 310 PartitionPage* page = GetFullPage(kTestAllocSize);
311 FreeFullPage(page); 311 FreeFullPage(page);
312 EXPECT_FALSE(bucket->emptyPagesHead); 312 EXPECT_FALSE(bucket->emptyPagesHead);
313 EXPECT_EQ(page, bucket->activePagesHead); 313 EXPECT_EQ(page, bucket->activePagesHead);
314 EXPECT_EQ(0, page->nextPage); 314 EXPECT_EQ(0, page->nextPage);
315 EXPECT_EQ(0, page->numAllocatedSlots); 315 EXPECT_EQ(0, page->numAllocatedSlots);
316 316
317 page = GetFullPage(kTestAllocSize); 317 page = GetFullPage(kTestAllocSize);
318 WTF::PartitionPage* page2 = GetFullPage(kTestAllocSize); 318 PartitionPage* page2 = GetFullPage(kTestAllocSize);
319 319
320 EXPECT_EQ(page2, bucket->activePagesHead); 320 EXPECT_EQ(page2, bucket->activePagesHead);
321 EXPECT_EQ(0, page2->nextPage); 321 EXPECT_EQ(0, page2->nextPage);
322 EXPECT_EQ(reinterpret_cast<uintptr_t>(partitionPageToPointer(page)) & WTF::k SuperPageBaseMask, reinterpret_cast<uintptr_t>(partitionPageToPointer(page2)) & WTF::kSuperPageBaseMask); 322 EXPECT_EQ(reinterpret_cast<uintptr_t>(partitionPageToPointer(page)) & kSuper PageBaseMask, reinterpret_cast<uintptr_t>(partitionPageToPointer(page2)) & kSupe rPageBaseMask);
323 323
324 // Fully free the non-current page. It should not be freelisted because 324 // Fully free the non-current page. It should not be freelisted because
325 // there is no other immediately useable page. The other page is full. 325 // there is no other immediately useable page. The other page is full.
326 FreeFullPage(page); 326 FreeFullPage(page);
327 EXPECT_EQ(0, page->numAllocatedSlots); 327 EXPECT_EQ(0, page->numAllocatedSlots);
328 EXPECT_FALSE(bucket->emptyPagesHead); 328 EXPECT_FALSE(bucket->emptyPagesHead);
329 EXPECT_EQ(page, bucket->activePagesHead); 329 EXPECT_EQ(page, bucket->activePagesHead);
330 330
331 // Allocate a new page, it should pull from the freelist. 331 // Allocate a new page, it should pull from the freelist.
332 page = GetFullPage(kTestAllocSize); 332 page = GetFullPage(kTestAllocSize);
333 EXPECT_FALSE(bucket->emptyPagesHead); 333 EXPECT_FALSE(bucket->emptyPagesHead);
334 EXPECT_EQ(page, bucket->activePagesHead); 334 EXPECT_EQ(page, bucket->activePagesHead);
335 335
336 FreeFullPage(page); 336 FreeFullPage(page);
337 FreeFullPage(page2); 337 FreeFullPage(page2);
338 EXPECT_EQ(0, page->numAllocatedSlots); 338 EXPECT_EQ(0, page->numAllocatedSlots);
339 EXPECT_EQ(0, page2->numAllocatedSlots); 339 EXPECT_EQ(0, page2->numAllocatedSlots);
340 EXPECT_EQ(0, page2->numUnprovisionedSlots); 340 EXPECT_EQ(0, page2->numUnprovisionedSlots);
341 EXPECT_NE(-1, page2->emptyCacheIndex); 341 EXPECT_NE(-1, page2->emptyCacheIndex);
342 342
343 TestShutdown(); 343 TestShutdown();
344 } 344 }
345 345
346 // Test some finer aspects of internal page transitions. 346 // Test some finer aspects of internal page transitions.
347 TEST(PartitionAllocTest, PageTransitions) 347 TEST(PartitionAllocTest, PageTransitions)
348 { 348 {
349 TestSetup(); 349 TestSetup();
350 WTF::PartitionBucket* bucket = &allocator.root()->buckets()[kTestBucketIndex ]; 350 PartitionBucket* bucket = &allocator.root()->buckets()[kTestBucketIndex];
351 351
352 WTF::PartitionPage* page1 = GetFullPage(kTestAllocSize); 352 PartitionPage* page1 = GetFullPage(kTestAllocSize);
353 EXPECT_EQ(page1, bucket->activePagesHead); 353 EXPECT_EQ(page1, bucket->activePagesHead);
354 EXPECT_EQ(0, page1->nextPage); 354 EXPECT_EQ(0, page1->nextPage);
355 WTF::PartitionPage* page2 = GetFullPage(kTestAllocSize); 355 PartitionPage* page2 = GetFullPage(kTestAllocSize);
356 EXPECT_EQ(page2, bucket->activePagesHead); 356 EXPECT_EQ(page2, bucket->activePagesHead);
357 EXPECT_EQ(0, page2->nextPage); 357 EXPECT_EQ(0, page2->nextPage);
358 358
359 // Bounce page1 back into the non-full list then fill it up again. 359 // Bounce page1 back into the non-full list then fill it up again.
360 char* ptr = reinterpret_cast<char*>(partitionPageToPointer(page1)) + kPointe rOffset; 360 char* ptr = reinterpret_cast<char*>(partitionPageToPointer(page1)) + kPointe rOffset;
361 partitionFree(ptr); 361 partitionFree(ptr);
362 EXPECT_EQ(page1, bucket->activePagesHead); 362 EXPECT_EQ(page1, bucket->activePagesHead);
363 (void) partitionAlloc(allocator.root(), kTestAllocSize); 363 (void) partitionAlloc(allocator.root(), kTestAllocSize);
364 EXPECT_EQ(page1, bucket->activePagesHead); 364 EXPECT_EQ(page1, bucket->activePagesHead);
365 EXPECT_EQ(page2, bucket->activePagesHead->nextPage); 365 EXPECT_EQ(page2, bucket->activePagesHead->nextPage);
366 366
367 // Allocating another page at this point should cause us to scan over page1 367 // Allocating another page at this point should cause us to scan over page1
368 // (which is both full and NOT our current page), and evict it from the 368 // (which is both full and NOT our current page), and evict it from the
369 // freelist. Older code had a O(n^2) condition due to failure to do this. 369 // freelist. Older code had a O(n^2) condition due to failure to do this.
370 WTF::PartitionPage* page3 = GetFullPage(kTestAllocSize); 370 PartitionPage* page3 = GetFullPage(kTestAllocSize);
371 EXPECT_EQ(page3, bucket->activePagesHead); 371 EXPECT_EQ(page3, bucket->activePagesHead);
372 EXPECT_EQ(0, page3->nextPage); 372 EXPECT_EQ(0, page3->nextPage);
373 373
374 // Work out a pointer into page2 and free it. 374 // Work out a pointer into page2 and free it.
375 ptr = reinterpret_cast<char*>(partitionPageToPointer(page2)) + kPointerOffse t; 375 ptr = reinterpret_cast<char*>(partitionPageToPointer(page2)) + kPointerOffse t;
376 partitionFree(ptr); 376 partitionFree(ptr);
377 // Trying to allocate at this time should cause us to cycle around to page2 377 // Trying to allocate at this time should cause us to cycle around to page2
378 // and find the recently freed slot. 378 // and find the recently freed slot.
379 char* newPtr = reinterpret_cast<char*>(partitionAlloc(allocator.root(), kTes tAllocSize)); 379 char* newPtr = reinterpret_cast<char*>(partitionAlloc(allocator.root(), kTes tAllocSize));
380 EXPECT_EQ(ptr, newPtr); 380 EXPECT_EQ(ptr, newPtr);
(...skipping 19 matching lines...) Expand all
400 partitionFree(ptr); 400 partitionFree(ptr);
401 401
402 TestShutdown(); 402 TestShutdown();
403 } 403 }
404 404
405 // Test some corner cases relating to page transitions in the internal 405 // Test some corner cases relating to page transitions in the internal
406 // free page list metadata bucket. 406 // free page list metadata bucket.
407 TEST(PartitionAllocTest, FreePageListPageTransitions) 407 TEST(PartitionAllocTest, FreePageListPageTransitions)
408 { 408 {
409 TestSetup(); 409 TestSetup();
410 WTF::PartitionBucket* bucket = &allocator.root()->buckets()[kTestBucketIndex ]; 410 PartitionBucket* bucket = &allocator.root()->buckets()[kTestBucketIndex];
411 411
412 size_t numToFillFreeListPage = WTF::kPartitionPageSize / (sizeof(WTF::Partit ionPage) + kExtraAllocSize); 412 size_t numToFillFreeListPage = kPartitionPageSize / (sizeof(PartitionPage) + kExtraAllocSize);
413 // The +1 is because we need to account for the fact that the current page 413 // The +1 is because we need to account for the fact that the current page
414 // never gets thrown on the freelist. 414 // never gets thrown on the freelist.
415 ++numToFillFreeListPage; 415 ++numToFillFreeListPage;
416 OwnPtr<WTF::PartitionPage*[]> pages = adoptArrayPtr(new WTF::PartitionPage*[ numToFillFreeListPage]); 416 OwnPtr<PartitionPage*[]> pages = adoptArrayPtr(new PartitionPage*[numToFillF reeListPage]);
417 417
418 size_t i; 418 size_t i;
419 for (i = 0; i < numToFillFreeListPage; ++i) { 419 for (i = 0; i < numToFillFreeListPage; ++i) {
420 pages[i] = GetFullPage(kTestAllocSize); 420 pages[i] = GetFullPage(kTestAllocSize);
421 } 421 }
422 EXPECT_EQ(pages[numToFillFreeListPage - 1], bucket->activePagesHead); 422 EXPECT_EQ(pages[numToFillFreeListPage - 1], bucket->activePagesHead);
423 for (i = 0; i < numToFillFreeListPage; ++i) 423 for (i = 0; i < numToFillFreeListPage; ++i)
424 FreeFullPage(pages[i]); 424 FreeFullPage(pages[i]);
425 EXPECT_EQ(0, bucket->activePagesHead->numAllocatedSlots); 425 EXPECT_EQ(0, bucket->activePagesHead->numAllocatedSlots);
426 EXPECT_NE(-1, bucket->activePagesHead->nextPage->emptyCacheIndex); 426 EXPECT_NE(-1, bucket->activePagesHead->nextPage->emptyCacheIndex);
427 EXPECT_EQ(0, bucket->activePagesHead->nextPage->numAllocatedSlots); 427 EXPECT_EQ(0, bucket->activePagesHead->nextPage->numAllocatedSlots);
428 EXPECT_EQ(0, bucket->activePagesHead->nextPage->numUnprovisionedSlots); 428 EXPECT_EQ(0, bucket->activePagesHead->nextPage->numUnprovisionedSlots);
429 429
430 // Allocate / free in a different bucket size so we get control of a 430 // Allocate / free in a different bucket size so we get control of a
431 // different free page list. We need two pages because one will be the last 431 // different free page list. We need two pages because one will be the last
432 // active page and not get freed. 432 // active page and not get freed.
433 WTF::PartitionPage* page1 = GetFullPage(kTestAllocSize * 2); 433 PartitionPage* page1 = GetFullPage(kTestAllocSize * 2);
434 WTF::PartitionPage* page2 = GetFullPage(kTestAllocSize * 2); 434 PartitionPage* page2 = GetFullPage(kTestAllocSize * 2);
435 FreeFullPage(page1); 435 FreeFullPage(page1);
436 FreeFullPage(page2); 436 FreeFullPage(page2);
437 437
438 // If we re-allocate all kTestAllocSize allocations, we'll pull all the 438 // If we re-allocate all kTestAllocSize allocations, we'll pull all the
439 // free pages and end up freeing the first page for free page objects. 439 // free pages and end up freeing the first page for free page objects.
440 // It's getting a bit tricky but a nice re-entrancy is going on: 440 // It's getting a bit tricky but a nice re-entrancy is going on:
441 // alloc(kTestAllocSize) -> pulls page from free page list -> 441 // alloc(kTestAllocSize) -> pulls page from free page list ->
442 // free(PartitionFreepagelistEntry) -> last entry in page freed -> 442 // free(PartitionFreepagelistEntry) -> last entry in page freed ->
443 // alloc(PartitionFreepagelistEntry). 443 // alloc(PartitionFreepagelistEntry).
444 for (i = 0; i < numToFillFreeListPage; ++i) { 444 for (i = 0; i < numToFillFreeListPage; ++i) {
(...skipping 15 matching lines...) Expand all
460 TestShutdown(); 460 TestShutdown();
461 } 461 }
462 462
463 // Test a large series of allocations that cross more than one underlying 463 // Test a large series of allocations that cross more than one underlying
464 // 64KB super page allocation. 464 // 64KB super page allocation.
465 TEST(PartitionAllocTest, MultiPageAllocs) 465 TEST(PartitionAllocTest, MultiPageAllocs)
466 { 466 {
467 TestSetup(); 467 TestSetup();
468 // This is guaranteed to cross a super page boundary because the first 468 // This is guaranteed to cross a super page boundary because the first
469 // partition page "slot" will be taken up by a guard page. 469 // partition page "slot" will be taken up by a guard page.
470 size_t numPagesNeeded = WTF::kNumPartitionPagesPerSuperPage; 470 size_t numPagesNeeded = kNumPartitionPagesPerSuperPage;
471 // The super page should begin and end in a guard so we one less page in 471 // The super page should begin and end in a guard so we one less page in
472 // order to allocate a single page in the new super page. 472 // order to allocate a single page in the new super page.
473 --numPagesNeeded; 473 --numPagesNeeded;
474 474
475 EXPECT_GT(numPagesNeeded, 1u); 475 EXPECT_GT(numPagesNeeded, 1u);
476 OwnPtr<WTF::PartitionPage*[]> pages; 476 OwnPtr<PartitionPage*[]> pages;
477 pages = adoptArrayPtr(new WTF::PartitionPage*[numPagesNeeded]); 477 pages = adoptArrayPtr(new PartitionPage*[numPagesNeeded]);
478 uintptr_t firstSuperPageBase = 0; 478 uintptr_t firstSuperPageBase = 0;
479 size_t i; 479 size_t i;
480 for (i = 0; i < numPagesNeeded; ++i) { 480 for (i = 0; i < numPagesNeeded; ++i) {
481 pages[i] = GetFullPage(kTestAllocSize); 481 pages[i] = GetFullPage(kTestAllocSize);
482 void* storagePtr = partitionPageToPointer(pages[i]); 482 void* storagePtr = partitionPageToPointer(pages[i]);
483 if (!i) 483 if (!i)
484 firstSuperPageBase = reinterpret_cast<uintptr_t>(storagePtr) & WTF:: kSuperPageBaseMask; 484 firstSuperPageBase = reinterpret_cast<uintptr_t>(storagePtr) & kSupe rPageBaseMask;
485 if (i == numPagesNeeded - 1) { 485 if (i == numPagesNeeded - 1) {
486 uintptr_t secondSuperPageBase = reinterpret_cast<uintptr_t>(storageP tr) & WTF::kSuperPageBaseMask; 486 uintptr_t secondSuperPageBase = reinterpret_cast<uintptr_t>(storageP tr) & kSuperPageBaseMask;
487 uintptr_t secondSuperPageOffset = reinterpret_cast<uintptr_t>(storag ePtr) & WTF::kSuperPageOffsetMask; 487 uintptr_t secondSuperPageOffset = reinterpret_cast<uintptr_t>(storag ePtr) & kSuperPageOffsetMask;
488 EXPECT_FALSE(secondSuperPageBase == firstSuperPageBase); 488 EXPECT_FALSE(secondSuperPageBase == firstSuperPageBase);
489 // Check that we allocated a guard page for the second page. 489 // Check that we allocated a guard page for the second page.
490 EXPECT_EQ(WTF::kPartitionPageSize, secondSuperPageOffset); 490 EXPECT_EQ(kPartitionPageSize, secondSuperPageOffset);
491 } 491 }
492 } 492 }
493 for (i = 0; i < numPagesNeeded; ++i) 493 for (i = 0; i < numPagesNeeded; ++i)
494 FreeFullPage(pages[i]); 494 FreeFullPage(pages[i]);
495 495
496 TestShutdown(); 496 TestShutdown();
497 } 497 }
498 498
499 // Test the generic allocation functions that can handle arbitrary sizes and 499 // Test the generic allocation functions that can handle arbitrary sizes and
500 // reallocing etc. 500 // reallocing etc.
501 TEST(PartitionAllocTest, GenericAlloc) 501 TEST(PartitionAllocTest, GenericAlloc)
502 { 502 {
503 TestSetup(); 503 TestSetup();
504 504
505 void* ptr = partitionAllocGeneric(genericAllocator.root(), 1); 505 void* ptr = partitionAllocGeneric(genericAllocator.root(), 1);
506 EXPECT_TRUE(ptr); 506 EXPECT_TRUE(ptr);
507 partitionFreeGeneric(genericAllocator.root(), ptr); 507 partitionFreeGeneric(genericAllocator.root(), ptr);
508 ptr = partitionAllocGeneric(genericAllocator.root(), WTF::kGenericMaxBuckete d + 1); 508 ptr = partitionAllocGeneric(genericAllocator.root(), kGenericMaxBucketed + 1 );
509 EXPECT_TRUE(ptr); 509 EXPECT_TRUE(ptr);
510 partitionFreeGeneric(genericAllocator.root(), ptr); 510 partitionFreeGeneric(genericAllocator.root(), ptr);
511 511
512 ptr = partitionAllocGeneric(genericAllocator.root(), 1); 512 ptr = partitionAllocGeneric(genericAllocator.root(), 1);
513 EXPECT_TRUE(ptr); 513 EXPECT_TRUE(ptr);
514 void* origPtr = ptr; 514 void* origPtr = ptr;
515 char* charPtr = static_cast<char*>(ptr); 515 char* charPtr = static_cast<char*>(ptr);
516 *charPtr = 'A'; 516 *charPtr = 'A';
517 517
518 // Change the size of the realloc, remaining inside the same bucket. 518 // Change the size of the realloc, remaining inside the same bucket.
519 void* newPtr = partitionReallocGeneric(genericAllocator.root(), ptr, 2); 519 void* newPtr = partitionReallocGeneric(genericAllocator.root(), ptr, 2);
520 EXPECT_EQ(ptr, newPtr); 520 EXPECT_EQ(ptr, newPtr);
521 newPtr = partitionReallocGeneric(genericAllocator.root(), ptr, 1); 521 newPtr = partitionReallocGeneric(genericAllocator.root(), ptr, 1);
522 EXPECT_EQ(ptr, newPtr); 522 EXPECT_EQ(ptr, newPtr);
523 newPtr = partitionReallocGeneric(genericAllocator.root(), ptr, WTF::kGeneric SmallestBucket); 523 newPtr = partitionReallocGeneric(genericAllocator.root(), ptr, kGenericSmall estBucket);
524 EXPECT_EQ(ptr, newPtr); 524 EXPECT_EQ(ptr, newPtr);
525 525
526 // Change the size of the realloc, switching buckets. 526 // Change the size of the realloc, switching buckets.
527 newPtr = partitionReallocGeneric(genericAllocator.root(), ptr, WTF::kGeneric SmallestBucket + 1); 527 newPtr = partitionReallocGeneric(genericAllocator.root(), ptr, kGenericSmall estBucket + 1);
528 EXPECT_NE(newPtr, ptr); 528 EXPECT_NE(newPtr, ptr);
529 // Check that the realloc copied correctly. 529 // Check that the realloc copied correctly.
530 char* newCharPtr = static_cast<char*>(newPtr); 530 char* newCharPtr = static_cast<char*>(newPtr);
531 EXPECT_EQ(*newCharPtr, 'A'); 531 EXPECT_EQ(*newCharPtr, 'A');
532 #if ENABLE(ASSERT) 532 #if ENABLE(ASSERT)
533 // Subtle: this checks for an old bug where we copied too much from the 533 // Subtle: this checks for an old bug where we copied too much from the
534 // source of the realloc. The condition can be detected by a trashing of 534 // source of the realloc. The condition can be detected by a trashing of
535 // the uninitialized value in the space of the upsized allocation. 535 // the uninitialized value in the space of the upsized allocation.
536 EXPECT_EQ(WTF::kUninitializedByte, static_cast<unsigned char>(*(newCharPtr + WTF::kGenericSmallestBucket))); 536 EXPECT_EQ(kUninitializedByte, static_cast<unsigned char>(*(newCharPtr + kGen ericSmallestBucket)));
537 #endif 537 #endif
538 *newCharPtr = 'B'; 538 *newCharPtr = 'B';
539 // The realloc moved. To check that the old allocation was freed, we can 539 // The realloc moved. To check that the old allocation was freed, we can
540 // do an alloc of the old allocation size and check that the old allocation 540 // do an alloc of the old allocation size and check that the old allocation
541 // address is at the head of the freelist and reused. 541 // address is at the head of the freelist and reused.
542 void* reusedPtr = partitionAllocGeneric(genericAllocator.root(), 1); 542 void* reusedPtr = partitionAllocGeneric(genericAllocator.root(), 1);
543 EXPECT_EQ(reusedPtr, origPtr); 543 EXPECT_EQ(reusedPtr, origPtr);
544 partitionFreeGeneric(genericAllocator.root(), reusedPtr); 544 partitionFreeGeneric(genericAllocator.root(), reusedPtr);
545 545
546 // Downsize the realloc. 546 // Downsize the realloc.
547 ptr = newPtr; 547 ptr = newPtr;
548 newPtr = partitionReallocGeneric(genericAllocator.root(), ptr, 1); 548 newPtr = partitionReallocGeneric(genericAllocator.root(), ptr, 1);
549 EXPECT_EQ(newPtr, origPtr); 549 EXPECT_EQ(newPtr, origPtr);
550 newCharPtr = static_cast<char*>(newPtr); 550 newCharPtr = static_cast<char*>(newPtr);
551 EXPECT_EQ(*newCharPtr, 'B'); 551 EXPECT_EQ(*newCharPtr, 'B');
552 *newCharPtr = 'C'; 552 *newCharPtr = 'C';
553 553
554 // Upsize the realloc to outside the partition. 554 // Upsize the realloc to outside the partition.
555 ptr = newPtr; 555 ptr = newPtr;
556 newPtr = partitionReallocGeneric(genericAllocator.root(), ptr, WTF::kGeneric MaxBucketed + 1); 556 newPtr = partitionReallocGeneric(genericAllocator.root(), ptr, kGenericMaxBu cketed + 1);
557 EXPECT_NE(newPtr, ptr); 557 EXPECT_NE(newPtr, ptr);
558 newCharPtr = static_cast<char*>(newPtr); 558 newCharPtr = static_cast<char*>(newPtr);
559 EXPECT_EQ(*newCharPtr, 'C'); 559 EXPECT_EQ(*newCharPtr, 'C');
560 *newCharPtr = 'D'; 560 *newCharPtr = 'D';
561 561
562 // Upsize and downsize the realloc, remaining outside the partition. 562 // Upsize and downsize the realloc, remaining outside the partition.
563 ptr = newPtr; 563 ptr = newPtr;
564 newPtr = partitionReallocGeneric(genericAllocator.root(), ptr, WTF::kGeneric MaxBucketed * 10); 564 newPtr = partitionReallocGeneric(genericAllocator.root(), ptr, kGenericMaxBu cketed * 10);
565 newCharPtr = static_cast<char*>(newPtr); 565 newCharPtr = static_cast<char*>(newPtr);
566 EXPECT_EQ(*newCharPtr, 'D'); 566 EXPECT_EQ(*newCharPtr, 'D');
567 *newCharPtr = 'E'; 567 *newCharPtr = 'E';
568 ptr = newPtr; 568 ptr = newPtr;
569 newPtr = partitionReallocGeneric(genericAllocator.root(), ptr, WTF::kGeneric MaxBucketed * 2); 569 newPtr = partitionReallocGeneric(genericAllocator.root(), ptr, kGenericMaxBu cketed * 2);
570 newCharPtr = static_cast<char*>(newPtr); 570 newCharPtr = static_cast<char*>(newPtr);
571 EXPECT_EQ(*newCharPtr, 'E'); 571 EXPECT_EQ(*newCharPtr, 'E');
572 *newCharPtr = 'F'; 572 *newCharPtr = 'F';
573 573
574 // Downsize the realloc to inside the partition. 574 // Downsize the realloc to inside the partition.
575 ptr = newPtr; 575 ptr = newPtr;
576 newPtr = partitionReallocGeneric(genericAllocator.root(), ptr, 1); 576 newPtr = partitionReallocGeneric(genericAllocator.root(), ptr, 1);
577 EXPECT_NE(newPtr, ptr); 577 EXPECT_NE(newPtr, ptr);
578 EXPECT_EQ(newPtr, origPtr); 578 EXPECT_EQ(newPtr, origPtr);
579 newCharPtr = static_cast<char*>(newPtr); 579 newCharPtr = static_cast<char*>(newPtr);
580 EXPECT_EQ(*newCharPtr, 'F'); 580 EXPECT_EQ(*newCharPtr, 'F');
581 581
582 partitionFreeGeneric(genericAllocator.root(), newPtr); 582 partitionFreeGeneric(genericAllocator.root(), newPtr);
583 TestShutdown(); 583 TestShutdown();
584 } 584 }
585 585
586 // Test the generic allocation functions can handle some specific sizes of 586 // Test the generic allocation functions can handle some specific sizes of
587 // interest. 587 // interest.
588 TEST(PartitionAllocTest, GenericAllocSizes) 588 TEST(PartitionAllocTest, GenericAllocSizes)
589 { 589 {
590 TestSetup(); 590 TestSetup();
591 591
592 void* ptr = partitionAllocGeneric(genericAllocator.root(), 0); 592 void* ptr = partitionAllocGeneric(genericAllocator.root(), 0);
593 EXPECT_TRUE(ptr); 593 EXPECT_TRUE(ptr);
594 partitionFreeGeneric(genericAllocator.root(), ptr); 594 partitionFreeGeneric(genericAllocator.root(), ptr);
595 595
596 // kPartitionPageSize is interesting because it results in just one 596 // kPartitionPageSize is interesting because it results in just one
597 // allocation per page, which tripped up some corner cases. 597 // allocation per page, which tripped up some corner cases.
598 size_t size = WTF::kPartitionPageSize - kExtraAllocSize; 598 size_t size = kPartitionPageSize - kExtraAllocSize;
599 ptr = partitionAllocGeneric(genericAllocator.root(), size); 599 ptr = partitionAllocGeneric(genericAllocator.root(), size);
600 EXPECT_TRUE(ptr); 600 EXPECT_TRUE(ptr);
601 void* ptr2 = partitionAllocGeneric(genericAllocator.root(), size); 601 void* ptr2 = partitionAllocGeneric(genericAllocator.root(), size);
602 EXPECT_TRUE(ptr2); 602 EXPECT_TRUE(ptr2);
603 partitionFreeGeneric(genericAllocator.root(), ptr); 603 partitionFreeGeneric(genericAllocator.root(), ptr);
604 // Should be freeable at this point. 604 // Should be freeable at this point.
605 WTF::PartitionPage* page = WTF::partitionPointerToPage(WTF::partitionCookieF reePointerAdjust(ptr)); 605 PartitionPage* page = partitionPointerToPage(partitionCookieFreePointerAdjus t(ptr));
606 EXPECT_NE(-1, page->emptyCacheIndex); 606 EXPECT_NE(-1, page->emptyCacheIndex);
607 partitionFreeGeneric(genericAllocator.root(), ptr2); 607 partitionFreeGeneric(genericAllocator.root(), ptr2);
608 608
609 size = (((WTF::kPartitionPageSize * WTF::kMaxPartitionPagesPerSlotSpan) - WT F::kSystemPageSize) / 2) - kExtraAllocSize; 609 size = (((kPartitionPageSize * kMaxPartitionPagesPerSlotSpan) - kSystemPageS ize) / 2) - kExtraAllocSize;
610 ptr = partitionAllocGeneric(genericAllocator.root(), size); 610 ptr = partitionAllocGeneric(genericAllocator.root(), size);
611 EXPECT_TRUE(ptr); 611 EXPECT_TRUE(ptr);
612 memset(ptr, 'A', size); 612 memset(ptr, 'A', size);
613 ptr2 = partitionAllocGeneric(genericAllocator.root(), size); 613 ptr2 = partitionAllocGeneric(genericAllocator.root(), size);
614 EXPECT_TRUE(ptr2); 614 EXPECT_TRUE(ptr2);
615 void* ptr3 = partitionAllocGeneric(genericAllocator.root(), size); 615 void* ptr3 = partitionAllocGeneric(genericAllocator.root(), size);
616 EXPECT_TRUE(ptr3); 616 EXPECT_TRUE(ptr3);
617 void* ptr4 = partitionAllocGeneric(genericAllocator.root(), size); 617 void* ptr4 = partitionAllocGeneric(genericAllocator.root(), size);
618 EXPECT_TRUE(ptr4); 618 EXPECT_TRUE(ptr4);
619 619
620 page = WTF::partitionPointerToPage(WTF::partitionCookieFreePointerAdjust(ptr )); 620 page = partitionPointerToPage(partitionCookieFreePointerAdjust(ptr));
621 WTF::PartitionPage* page2 = WTF::partitionPointerToPage(WTF::partitionCookie FreePointerAdjust(ptr3)); 621 PartitionPage* page2 = partitionPointerToPage(partitionCookieFreePointerAdju st(ptr3));
622 EXPECT_NE(page, page2); 622 EXPECT_NE(page, page2);
623 623
624 partitionFreeGeneric(genericAllocator.root(), ptr); 624 partitionFreeGeneric(genericAllocator.root(), ptr);
625 partitionFreeGeneric(genericAllocator.root(), ptr3); 625 partitionFreeGeneric(genericAllocator.root(), ptr3);
626 partitionFreeGeneric(genericAllocator.root(), ptr2); 626 partitionFreeGeneric(genericAllocator.root(), ptr2);
627 // Should be freeable at this point. 627 // Should be freeable at this point.
628 EXPECT_NE(-1, page->emptyCacheIndex); 628 EXPECT_NE(-1, page->emptyCacheIndex);
629 EXPECT_EQ(0, page->numAllocatedSlots); 629 EXPECT_EQ(0, page->numAllocatedSlots);
630 EXPECT_EQ(0, page->numUnprovisionedSlots); 630 EXPECT_EQ(0, page->numUnprovisionedSlots);
631 void* newPtr = partitionAllocGeneric(genericAllocator.root(), size); 631 void* newPtr = partitionAllocGeneric(genericAllocator.root(), size);
(...skipping 14 matching lines...) Expand all
646 partitionFreeGeneric(genericAllocator.root(), ptr3); 646 partitionFreeGeneric(genericAllocator.root(), ptr3);
647 partitionFreeGeneric(genericAllocator.root(), ptr4); 647 partitionFreeGeneric(genericAllocator.root(), ptr4);
648 648
649 // Can we allocate a massive (512MB) size? 649 // Can we allocate a massive (512MB) size?
650 ptr = partitionAllocGeneric(genericAllocator.root(), 512 * 1024 * 1024); 650 ptr = partitionAllocGeneric(genericAllocator.root(), 512 * 1024 * 1024);
651 partitionFreeGeneric(genericAllocator.root(), ptr); 651 partitionFreeGeneric(genericAllocator.root(), ptr);
652 652
653 // Check a more reasonable, but still direct mapped, size. 653 // Check a more reasonable, but still direct mapped, size.
654 // Chop a system page and a byte off to test for rounding errors. 654 // Chop a system page and a byte off to test for rounding errors.
655 size = 20 * 1024 * 1024; 655 size = 20 * 1024 * 1024;
656 size -= WTF::kSystemPageSize; 656 size -= kSystemPageSize;
657 size -= 1; 657 size -= 1;
658 ptr = partitionAllocGeneric(genericAllocator.root(), size); 658 ptr = partitionAllocGeneric(genericAllocator.root(), size);
659 char* charPtr = reinterpret_cast<char*>(ptr); 659 char* charPtr = reinterpret_cast<char*>(ptr);
660 *(charPtr + (size - 1)) = 'A'; 660 *(charPtr + (size - 1)) = 'A';
661 partitionFreeGeneric(genericAllocator.root(), ptr); 661 partitionFreeGeneric(genericAllocator.root(), ptr);
662 662
663 // Can we free null? 663 // Can we free null?
664 partitionFreeGeneric(genericAllocator.root(), 0); 664 partitionFreeGeneric(genericAllocator.root(), 0);
665 665
666 // Do we correctly get a null for a failed allocation? 666 // Do we correctly get a null for a failed allocation?
667 EXPECT_EQ(0, partitionAllocGenericFlags(genericAllocator.root(), WTF::Partit ionAllocReturnNull, 3u * 1024 * 1024 * 1024)); 667 EXPECT_EQ(0, partitionAllocGenericFlags(genericAllocator.root(), PartitionAl locReturnNull, 3u * 1024 * 1024 * 1024));
668 668
669 TestShutdown(); 669 TestShutdown();
670 } 670 }
671 671
672 // Test that we can fetch the real allocated size after an allocation. 672 // Test that we can fetch the real allocated size after an allocation.
673 TEST(PartitionAllocTest, GenericAllocGetSize) 673 TEST(PartitionAllocTest, GenericAllocGetSize)
674 { 674 {
675 TestSetup(); 675 TestSetup();
676 676
677 void* ptr; 677 void* ptr;
(...skipping 17 matching lines...) Expand all
695 predictedSize = partitionAllocActualSize(genericAllocator.root(), requestedS ize); 695 predictedSize = partitionAllocActualSize(genericAllocator.root(), requestedS ize);
696 ptr = partitionAllocGeneric(genericAllocator.root(), requestedSize); 696 ptr = partitionAllocGeneric(genericAllocator.root(), requestedSize);
697 EXPECT_TRUE(ptr); 697 EXPECT_TRUE(ptr);
698 actualSize = partitionAllocGetSize(ptr); 698 actualSize = partitionAllocGetSize(ptr);
699 EXPECT_EQ(predictedSize, actualSize); 699 EXPECT_EQ(predictedSize, actualSize);
700 EXPECT_EQ(requestedSize, actualSize); 700 EXPECT_EQ(requestedSize, actualSize);
701 partitionFreeGeneric(genericAllocator.root(), ptr); 701 partitionFreeGeneric(genericAllocator.root(), ptr);
702 702
703 // Allocate a size that is a system page smaller than a bucket. GetSize() 703 // Allocate a size that is a system page smaller than a bucket. GetSize()
704 // should return a larger size than we asked for now. 704 // should return a larger size than we asked for now.
705 requestedSize = (256 * 1024) - WTF::kSystemPageSize - kExtraAllocSize; 705 requestedSize = (256 * 1024) - kSystemPageSize - kExtraAllocSize;
706 predictedSize = partitionAllocActualSize(genericAllocator.root(), requestedS ize); 706 predictedSize = partitionAllocActualSize(genericAllocator.root(), requestedS ize);
707 ptr = partitionAllocGeneric(genericAllocator.root(), requestedSize); 707 ptr = partitionAllocGeneric(genericAllocator.root(), requestedSize);
708 EXPECT_TRUE(ptr); 708 EXPECT_TRUE(ptr);
709 actualSize = partitionAllocGetSize(ptr); 709 actualSize = partitionAllocGetSize(ptr);
710 EXPECT_EQ(predictedSize, actualSize); 710 EXPECT_EQ(predictedSize, actualSize);
711 EXPECT_EQ(requestedSize + WTF::kSystemPageSize, actualSize); 711 EXPECT_EQ(requestedSize + kSystemPageSize, actualSize);
712 // Check that we can write at the end of the reported size too. 712 // Check that we can write at the end of the reported size too.
713 char* charPtr = reinterpret_cast<char*>(ptr); 713 char* charPtr = reinterpret_cast<char*>(ptr);
714 *(charPtr + (actualSize - 1)) = 'A'; 714 *(charPtr + (actualSize - 1)) = 'A';
715 partitionFreeGeneric(genericAllocator.root(), ptr); 715 partitionFreeGeneric(genericAllocator.root(), ptr);
716 716
717 // Allocate something very large, and uneven. 717 // Allocate something very large, and uneven.
718 requestedSize = 512 * 1024 * 1024 - 1; 718 requestedSize = 512 * 1024 * 1024 - 1;
719 predictedSize = partitionAllocActualSize(genericAllocator.root(), requestedS ize); 719 predictedSize = partitionAllocActualSize(genericAllocator.root(), requestedS ize);
720 ptr = partitionAllocGeneric(genericAllocator.root(), requestedSize); 720 ptr = partitionAllocGeneric(genericAllocator.root(), requestedSize);
721 EXPECT_TRUE(ptr); 721 EXPECT_TRUE(ptr);
(...skipping 11 matching lines...) Expand all
733 } 733 }
734 734
735 // Test the realloc() contract. 735 // Test the realloc() contract.
736 TEST(PartitionAllocTest, Realloc) 736 TEST(PartitionAllocTest, Realloc)
737 { 737 {
738 TestSetup(); 738 TestSetup();
739 739
740 // realloc(0, size) should be equivalent to malloc(). 740 // realloc(0, size) should be equivalent to malloc().
741 void* ptr = partitionReallocGeneric(genericAllocator.root(), 0, kTestAllocSi ze); 741 void* ptr = partitionReallocGeneric(genericAllocator.root(), 0, kTestAllocSi ze);
742 memset(ptr, 'A', kTestAllocSize); 742 memset(ptr, 'A', kTestAllocSize);
743 WTF::PartitionPage* page = WTF::partitionPointerToPage(WTF::partitionCookieF reePointerAdjust(ptr)); 743 PartitionPage* page = partitionPointerToPage(partitionCookieFreePointerAdjus t(ptr));
744 // realloc(ptr, 0) should be equivalent to free(). 744 // realloc(ptr, 0) should be equivalent to free().
745 void* ptr2 = partitionReallocGeneric(genericAllocator.root(), ptr, 0); 745 void* ptr2 = partitionReallocGeneric(genericAllocator.root(), ptr, 0);
746 EXPECT_EQ(0, ptr2); 746 EXPECT_EQ(0, ptr2);
747 EXPECT_EQ(WTF::partitionCookieFreePointerAdjust(ptr), page->freelistHead); 747 EXPECT_EQ(partitionCookieFreePointerAdjust(ptr), page->freelistHead);
748 748
749 // Test that growing an allocation with realloc() copies everything from the 749 // Test that growing an allocation with realloc() copies everything from the
750 // old allocation. 750 // old allocation.
751 size_t size = WTF::kSystemPageSize - kExtraAllocSize; 751 size_t size = kSystemPageSize - kExtraAllocSize;
752 EXPECT_EQ(size, partitionAllocActualSize(genericAllocator.root(), size)); 752 EXPECT_EQ(size, partitionAllocActualSize(genericAllocator.root(), size));
753 ptr = partitionAllocGeneric(genericAllocator.root(), size); 753 ptr = partitionAllocGeneric(genericAllocator.root(), size);
754 memset(ptr, 'A', size); 754 memset(ptr, 'A', size);
755 ptr2 = partitionReallocGeneric(genericAllocator.root(), ptr, size + 1); 755 ptr2 = partitionReallocGeneric(genericAllocator.root(), ptr, size + 1);
756 EXPECT_NE(ptr, ptr2); 756 EXPECT_NE(ptr, ptr2);
757 char* charPtr2 = static_cast<char*>(ptr2); 757 char* charPtr2 = static_cast<char*>(ptr2);
758 EXPECT_EQ('A', charPtr2[0]); 758 EXPECT_EQ('A', charPtr2[0]);
759 EXPECT_EQ('A', charPtr2[size - 1]); 759 EXPECT_EQ('A', charPtr2[size - 1]);
760 #if ENABLE(ASSERT) 760 #if ENABLE(ASSERT)
761 EXPECT_EQ(WTF::kUninitializedByte, static_cast<unsigned char>(charPtr2[size] )); 761 EXPECT_EQ(kUninitializedByte, static_cast<unsigned char>(charPtr2[size]));
762 #endif 762 #endif
763 763
764 // Test that shrinking an allocation with realloc() also copies everything 764 // Test that shrinking an allocation with realloc() also copies everything
765 // from the old allocation. 765 // from the old allocation.
766 ptr = partitionReallocGeneric(genericAllocator.root(), ptr2, size - 1); 766 ptr = partitionReallocGeneric(genericAllocator.root(), ptr2, size - 1);
767 EXPECT_NE(ptr2, ptr); 767 EXPECT_NE(ptr2, ptr);
768 char* charPtr = static_cast<char*>(ptr); 768 char* charPtr = static_cast<char*>(ptr);
769 EXPECT_EQ('A', charPtr[0]); 769 EXPECT_EQ('A', charPtr[0]);
770 EXPECT_EQ('A', charPtr[size - 2]); 770 EXPECT_EQ('A', charPtr[size - 2]);
771 #if ENABLE(ASSERT) 771 #if ENABLE(ASSERT)
772 EXPECT_EQ(WTF::kUninitializedByte, static_cast<unsigned char>(charPtr[size - 1])); 772 EXPECT_EQ(kUninitializedByte, static_cast<unsigned char>(charPtr[size - 1])) ;
773 #endif 773 #endif
774 774
775 partitionFreeGeneric(genericAllocator.root(), ptr); 775 partitionFreeGeneric(genericAllocator.root(), ptr);
776 776
777 // Test that shrinking a direct mapped allocation happens in-place. 777 // Test that shrinking a direct mapped allocation happens in-place.
778 size = WTF::kGenericMaxBucketed + 16 * WTF::kSystemPageSize; 778 size = kGenericMaxBucketed + 16 * kSystemPageSize;
779 ptr = partitionAllocGeneric(genericAllocator.root(), size); 779 ptr = partitionAllocGeneric(genericAllocator.root(), size);
780 size_t actualSize = partitionAllocGetSize(ptr); 780 size_t actualSize = partitionAllocGetSize(ptr);
781 ptr2 = partitionReallocGeneric(genericAllocator.root(), ptr, WTF::kGenericMa xBucketed + 8 * WTF::kSystemPageSize); 781 ptr2 = partitionReallocGeneric(genericAllocator.root(), ptr, kGenericMaxBuck eted + 8 * kSystemPageSize);
782 EXPECT_EQ(ptr, ptr2); 782 EXPECT_EQ(ptr, ptr2);
783 EXPECT_EQ(actualSize - 8 * WTF::kSystemPageSize, partitionAllocGetSize(ptr2) ); 783 EXPECT_EQ(actualSize - 8 * kSystemPageSize, partitionAllocGetSize(ptr2));
784 784
785 // Test that a previously in-place shrunk direct mapped allocation can be 785 // Test that a previously in-place shrunk direct mapped allocation can be
786 // expanded up again within its original size. 786 // expanded up again within its original size.
787 ptr = partitionReallocGeneric(genericAllocator.root(), ptr2, size - WTF::kSy stemPageSize); 787 ptr = partitionReallocGeneric(genericAllocator.root(), ptr2, size - kSystemP ageSize);
788 EXPECT_EQ(ptr2, ptr); 788 EXPECT_EQ(ptr2, ptr);
789 EXPECT_EQ(actualSize - WTF::kSystemPageSize, partitionAllocGetSize(ptr)); 789 EXPECT_EQ(actualSize - kSystemPageSize, partitionAllocGetSize(ptr));
790 790
791 // Test that a direct mapped allocation is performed not in-place when the 791 // Test that a direct mapped allocation is performed not in-place when the
792 // new size is small enough. 792 // new size is small enough.
793 ptr2 = partitionReallocGeneric(genericAllocator.root(), ptr, WTF::kSystemPag eSize); 793 ptr2 = partitionReallocGeneric(genericAllocator.root(), ptr, kSystemPageSize );
794 EXPECT_NE(ptr, ptr2); 794 EXPECT_NE(ptr, ptr2);
795 795
796 partitionFreeGeneric(genericAllocator.root(), ptr2); 796 partitionFreeGeneric(genericAllocator.root(), ptr2);
797 797
798 TestShutdown(); 798 TestShutdown();
799 } 799 }
800 800
801 // Tests the handing out of freelists for partial pages. 801 // Tests the handing out of freelists for partial pages.
802 TEST(PartitionAllocTest, PartialPageFreelists) 802 TEST(PartitionAllocTest, PartialPageFreelists)
803 { 803 {
804 TestSetup(); 804 TestSetup();
805 805
806 size_t bigSize = allocator.root()->maxAllocation - kExtraAllocSize; 806 size_t bigSize = allocator.root()->maxAllocation - kExtraAllocSize;
807 EXPECT_EQ(WTF::kSystemPageSize - WTF::kAllocationGranularity, bigSize + kExt raAllocSize); 807 EXPECT_EQ(kSystemPageSize - kAllocationGranularity, bigSize + kExtraAllocSiz e);
808 size_t bucketIdx = (bigSize + kExtraAllocSize) >> WTF::kBucketShift; 808 size_t bucketIdx = (bigSize + kExtraAllocSize) >> kBucketShift;
809 WTF::PartitionBucket* bucket = &allocator.root()->buckets()[bucketIdx]; 809 PartitionBucket* bucket = &allocator.root()->buckets()[bucketIdx];
810 EXPECT_EQ(0, bucket->emptyPagesHead); 810 EXPECT_EQ(0, bucket->emptyPagesHead);
811 811
812 void* ptr = partitionAlloc(allocator.root(), bigSize); 812 void* ptr = partitionAlloc(allocator.root(), bigSize);
813 EXPECT_TRUE(ptr); 813 EXPECT_TRUE(ptr);
814 814
815 WTF::PartitionPage* page = WTF::partitionPointerToPage(WTF::partitionCookieF reePointerAdjust(ptr)); 815 PartitionPage* page = partitionPointerToPage(partitionCookieFreePointerAdjus t(ptr));
816 size_t totalSlots = (page->bucket->numSystemPagesPerSlotSpan * WTF::kSystemP ageSize) / (bigSize + kExtraAllocSize); 816 size_t totalSlots = (page->bucket->numSystemPagesPerSlotSpan * kSystemPageSi ze) / (bigSize + kExtraAllocSize);
817 EXPECT_EQ(4u, totalSlots); 817 EXPECT_EQ(4u, totalSlots);
818 // The freelist should have one entry, because we were able to exactly fit 818 // The freelist should have one entry, because we were able to exactly fit
819 // one object slot and one freelist pointer (the null that the head points 819 // one object slot and one freelist pointer (the null that the head points
820 // to) into a system page. 820 // to) into a system page.
821 EXPECT_TRUE(page->freelistHead); 821 EXPECT_TRUE(page->freelistHead);
822 EXPECT_EQ(1, page->numAllocatedSlots); 822 EXPECT_EQ(1, page->numAllocatedSlots);
823 EXPECT_EQ(2, page->numUnprovisionedSlots); 823 EXPECT_EQ(2, page->numUnprovisionedSlots);
824 824
825 void* ptr2 = partitionAlloc(allocator.root(), bigSize); 825 void* ptr2 = partitionAlloc(allocator.root(), bigSize);
826 EXPECT_TRUE(ptr2); 826 EXPECT_TRUE(ptr2);
827 EXPECT_FALSE(page->freelistHead); 827 EXPECT_FALSE(page->freelistHead);
828 EXPECT_EQ(2, page->numAllocatedSlots); 828 EXPECT_EQ(2, page->numAllocatedSlots);
829 EXPECT_EQ(2, page->numUnprovisionedSlots); 829 EXPECT_EQ(2, page->numUnprovisionedSlots);
830 830
831 void* ptr3 = partitionAlloc(allocator.root(), bigSize); 831 void* ptr3 = partitionAlloc(allocator.root(), bigSize);
832 EXPECT_TRUE(ptr3); 832 EXPECT_TRUE(ptr3);
833 EXPECT_TRUE(page->freelistHead); 833 EXPECT_TRUE(page->freelistHead);
834 EXPECT_EQ(3, page->numAllocatedSlots); 834 EXPECT_EQ(3, page->numAllocatedSlots);
835 EXPECT_EQ(0, page->numUnprovisionedSlots); 835 EXPECT_EQ(0, page->numUnprovisionedSlots);
836 836
837 void* ptr4 = partitionAlloc(allocator.root(), bigSize); 837 void* ptr4 = partitionAlloc(allocator.root(), bigSize);
838 EXPECT_TRUE(ptr4); 838 EXPECT_TRUE(ptr4);
839 EXPECT_FALSE(page->freelistHead); 839 EXPECT_FALSE(page->freelistHead);
840 EXPECT_EQ(4, page->numAllocatedSlots); 840 EXPECT_EQ(4, page->numAllocatedSlots);
841 EXPECT_EQ(0, page->numUnprovisionedSlots); 841 EXPECT_EQ(0, page->numUnprovisionedSlots);
842 842
843 void* ptr5 = partitionAlloc(allocator.root(), bigSize); 843 void* ptr5 = partitionAlloc(allocator.root(), bigSize);
844 EXPECT_TRUE(ptr5); 844 EXPECT_TRUE(ptr5);
845 845
846 WTF::PartitionPage* page2 = WTF::partitionPointerToPage(WTF::partitionCookie FreePointerAdjust(ptr5)); 846 PartitionPage* page2 = partitionPointerToPage(partitionCookieFreePointerAdju st(ptr5));
847 EXPECT_EQ(1, page2->numAllocatedSlots); 847 EXPECT_EQ(1, page2->numAllocatedSlots);
848 848
849 // Churn things a little whilst there's a partial page freelist. 849 // Churn things a little whilst there's a partial page freelist.
850 partitionFree(ptr); 850 partitionFree(ptr);
851 ptr = partitionAlloc(allocator.root(), bigSize); 851 ptr = partitionAlloc(allocator.root(), bigSize);
852 void* ptr6 = partitionAlloc(allocator.root(), bigSize); 852 void* ptr6 = partitionAlloc(allocator.root(), bigSize);
853 853
854 partitionFree(ptr); 854 partitionFree(ptr);
855 partitionFree(ptr2); 855 partitionFree(ptr2);
856 partitionFree(ptr3); 856 partitionFree(ptr3);
857 partitionFree(ptr4); 857 partitionFree(ptr4);
858 partitionFree(ptr5); 858 partitionFree(ptr5);
859 partitionFree(ptr6); 859 partitionFree(ptr6);
860 EXPECT_NE(-1, page->emptyCacheIndex); 860 EXPECT_NE(-1, page->emptyCacheIndex);
861 EXPECT_NE(-1, page2->emptyCacheIndex); 861 EXPECT_NE(-1, page2->emptyCacheIndex);
862 EXPECT_TRUE(page2->freelistHead); 862 EXPECT_TRUE(page2->freelistHead);
863 EXPECT_EQ(0, page2->numAllocatedSlots); 863 EXPECT_EQ(0, page2->numAllocatedSlots);
864 864
865 // And test a couple of sizes that do not cross kSystemPageSize with a singl e allocation. 865 // And test a couple of sizes that do not cross kSystemPageSize with a singl e allocation.
866 size_t mediumSize = (WTF::kSystemPageSize / 2) - kExtraAllocSize; 866 size_t mediumSize = (kSystemPageSize / 2) - kExtraAllocSize;
867 bucketIdx = (mediumSize + kExtraAllocSize) >> WTF::kBucketShift; 867 bucketIdx = (mediumSize + kExtraAllocSize) >> kBucketShift;
868 bucket = &allocator.root()->buckets()[bucketIdx]; 868 bucket = &allocator.root()->buckets()[bucketIdx];
869 EXPECT_EQ(0, bucket->emptyPagesHead); 869 EXPECT_EQ(0, bucket->emptyPagesHead);
870 870
871 ptr = partitionAlloc(allocator.root(), mediumSize); 871 ptr = partitionAlloc(allocator.root(), mediumSize);
872 EXPECT_TRUE(ptr); 872 EXPECT_TRUE(ptr);
873 page = WTF::partitionPointerToPage(WTF::partitionCookieFreePointerAdjust(ptr )); 873 page = partitionPointerToPage(partitionCookieFreePointerAdjust(ptr));
874 EXPECT_EQ(1, page->numAllocatedSlots); 874 EXPECT_EQ(1, page->numAllocatedSlots);
875 totalSlots = (page->bucket->numSystemPagesPerSlotSpan * WTF::kSystemPageSize ) / (mediumSize + kExtraAllocSize); 875 totalSlots = (page->bucket->numSystemPagesPerSlotSpan * kSystemPageSize) / ( mediumSize + kExtraAllocSize);
876 size_t firstPageSlots = WTF::kSystemPageSize / (mediumSize + kExtraAllocSize ); 876 size_t firstPageSlots = kSystemPageSize / (mediumSize + kExtraAllocSize);
877 EXPECT_EQ(2u, firstPageSlots); 877 EXPECT_EQ(2u, firstPageSlots);
878 EXPECT_EQ(totalSlots - firstPageSlots, page->numUnprovisionedSlots); 878 EXPECT_EQ(totalSlots - firstPageSlots, page->numUnprovisionedSlots);
879 879
880 partitionFree(ptr); 880 partitionFree(ptr);
881 881
882 size_t smallSize = (WTF::kSystemPageSize / 4) - kExtraAllocSize; 882 size_t smallSize = (kSystemPageSize / 4) - kExtraAllocSize;
883 bucketIdx = (smallSize + kExtraAllocSize) >> WTF::kBucketShift; 883 bucketIdx = (smallSize + kExtraAllocSize) >> kBucketShift;
884 bucket = &allocator.root()->buckets()[bucketIdx]; 884 bucket = &allocator.root()->buckets()[bucketIdx];
885 EXPECT_EQ(0, bucket->emptyPagesHead); 885 EXPECT_EQ(0, bucket->emptyPagesHead);
886 886
887 ptr = partitionAlloc(allocator.root(), smallSize); 887 ptr = partitionAlloc(allocator.root(), smallSize);
888 EXPECT_TRUE(ptr); 888 EXPECT_TRUE(ptr);
889 page = WTF::partitionPointerToPage(WTF::partitionCookieFreePointerAdjust(ptr )); 889 page = partitionPointerToPage(partitionCookieFreePointerAdjust(ptr));
890 EXPECT_EQ(1, page->numAllocatedSlots); 890 EXPECT_EQ(1, page->numAllocatedSlots);
891 totalSlots = (page->bucket->numSystemPagesPerSlotSpan * WTF::kSystemPageSize ) / (smallSize + kExtraAllocSize); 891 totalSlots = (page->bucket->numSystemPagesPerSlotSpan * kSystemPageSize) / ( smallSize + kExtraAllocSize);
892 firstPageSlots = WTF::kSystemPageSize / (smallSize + kExtraAllocSize); 892 firstPageSlots = kSystemPageSize / (smallSize + kExtraAllocSize);
893 EXPECT_EQ(totalSlots - firstPageSlots, page->numUnprovisionedSlots); 893 EXPECT_EQ(totalSlots - firstPageSlots, page->numUnprovisionedSlots);
894 894
895 partitionFree(ptr); 895 partitionFree(ptr);
896 EXPECT_TRUE(page->freelistHead); 896 EXPECT_TRUE(page->freelistHead);
897 EXPECT_EQ(0, page->numAllocatedSlots); 897 EXPECT_EQ(0, page->numAllocatedSlots);
898 898
899 size_t verySmallSize = 32 - kExtraAllocSize; 899 size_t verySmallSize = 32 - kExtraAllocSize;
900 bucketIdx = (verySmallSize + kExtraAllocSize) >> WTF::kBucketShift; 900 bucketIdx = (verySmallSize + kExtraAllocSize) >> kBucketShift;
901 bucket = &allocator.root()->buckets()[bucketIdx]; 901 bucket = &allocator.root()->buckets()[bucketIdx];
902 EXPECT_EQ(0, bucket->emptyPagesHead); 902 EXPECT_EQ(0, bucket->emptyPagesHead);
903 903
904 ptr = partitionAlloc(allocator.root(), verySmallSize); 904 ptr = partitionAlloc(allocator.root(), verySmallSize);
905 EXPECT_TRUE(ptr); 905 EXPECT_TRUE(ptr);
906 page = WTF::partitionPointerToPage(WTF::partitionCookieFreePointerAdjust(ptr )); 906 page = partitionPointerToPage(partitionCookieFreePointerAdjust(ptr));
907 EXPECT_EQ(1, page->numAllocatedSlots); 907 EXPECT_EQ(1, page->numAllocatedSlots);
908 totalSlots = (page->bucket->numSystemPagesPerSlotSpan * WTF::kSystemPageSize ) / (verySmallSize + kExtraAllocSize); 908 totalSlots = (page->bucket->numSystemPagesPerSlotSpan * kSystemPageSize) / ( verySmallSize + kExtraAllocSize);
909 firstPageSlots = WTF::kSystemPageSize / (verySmallSize + kExtraAllocSize); 909 firstPageSlots = kSystemPageSize / (verySmallSize + kExtraAllocSize);
910 EXPECT_EQ(totalSlots - firstPageSlots, page->numUnprovisionedSlots); 910 EXPECT_EQ(totalSlots - firstPageSlots, page->numUnprovisionedSlots);
911 911
912 partitionFree(ptr); 912 partitionFree(ptr);
913 EXPECT_TRUE(page->freelistHead); 913 EXPECT_TRUE(page->freelistHead);
914 EXPECT_EQ(0, page->numAllocatedSlots); 914 EXPECT_EQ(0, page->numAllocatedSlots);
915 915
916 // And try an allocation size (against the generic allocator) that is 916 // And try an allocation size (against the generic allocator) that is
917 // larger than a system page. 917 // larger than a system page.
918 size_t pageAndAHalfSize = (WTF::kSystemPageSize + (WTF::kSystemPageSize / 2) ) - kExtraAllocSize; 918 size_t pageAndAHalfSize = (kSystemPageSize + (kSystemPageSize / 2)) - kExtra AllocSize;
919 ptr = partitionAllocGeneric(genericAllocator.root(), pageAndAHalfSize); 919 ptr = partitionAllocGeneric(genericAllocator.root(), pageAndAHalfSize);
920 EXPECT_TRUE(ptr); 920 EXPECT_TRUE(ptr);
921 page = WTF::partitionPointerToPage(WTF::partitionCookieFreePointerAdjust(ptr )); 921 page = partitionPointerToPage(partitionCookieFreePointerAdjust(ptr));
922 EXPECT_EQ(1, page->numAllocatedSlots); 922 EXPECT_EQ(1, page->numAllocatedSlots);
923 EXPECT_TRUE(page->freelistHead); 923 EXPECT_TRUE(page->freelistHead);
924 totalSlots = (page->bucket->numSystemPagesPerSlotSpan * WTF::kSystemPageSize ) / (pageAndAHalfSize + kExtraAllocSize); 924 totalSlots = (page->bucket->numSystemPagesPerSlotSpan * kSystemPageSize) / ( pageAndAHalfSize + kExtraAllocSize);
925 EXPECT_EQ(totalSlots - 2, page->numUnprovisionedSlots); 925 EXPECT_EQ(totalSlots - 2, page->numUnprovisionedSlots);
926 partitionFreeGeneric(genericAllocator.root(), ptr); 926 partitionFreeGeneric(genericAllocator.root(), ptr);
927 927
928 // And then make sure than exactly the page size only faults one page. 928 // And then make sure than exactly the page size only faults one page.
929 size_t pageSize = WTF::kSystemPageSize - kExtraAllocSize; 929 size_t pageSize = kSystemPageSize - kExtraAllocSize;
930 ptr = partitionAllocGeneric(genericAllocator.root(), pageSize); 930 ptr = partitionAllocGeneric(genericAllocator.root(), pageSize);
931 EXPECT_TRUE(ptr); 931 EXPECT_TRUE(ptr);
932 page = WTF::partitionPointerToPage(WTF::partitionCookieFreePointerAdjust(ptr )); 932 page = partitionPointerToPage(partitionCookieFreePointerAdjust(ptr));
933 EXPECT_EQ(1, page->numAllocatedSlots); 933 EXPECT_EQ(1, page->numAllocatedSlots);
934 EXPECT_FALSE(page->freelistHead); 934 EXPECT_FALSE(page->freelistHead);
935 totalSlots = (page->bucket->numSystemPagesPerSlotSpan * WTF::kSystemPageSize ) / (pageSize + kExtraAllocSize); 935 totalSlots = (page->bucket->numSystemPagesPerSlotSpan * kSystemPageSize) / ( pageSize + kExtraAllocSize);
936 EXPECT_EQ(totalSlots - 1, page->numUnprovisionedSlots); 936 EXPECT_EQ(totalSlots - 1, page->numUnprovisionedSlots);
937 partitionFreeGeneric(genericAllocator.root(), ptr); 937 partitionFreeGeneric(genericAllocator.root(), ptr);
938 938
939 TestShutdown(); 939 TestShutdown();
940 } 940 }
941 941
942 // Test some of the fragmentation-resistant properties of the allocator. 942 // Test some of the fragmentation-resistant properties of the allocator.
943 TEST(PartitionAllocTest, PageRefilling) 943 TEST(PartitionAllocTest, PageRefilling)
944 { 944 {
945 TestSetup(); 945 TestSetup();
946 WTF::PartitionBucket* bucket = &allocator.root()->buckets()[kTestBucketIndex ]; 946 PartitionBucket* bucket = &allocator.root()->buckets()[kTestBucketIndex];
947 947
948 // Grab two full pages and a non-full page. 948 // Grab two full pages and a non-full page.
949 WTF::PartitionPage* page1 = GetFullPage(kTestAllocSize); 949 PartitionPage* page1 = GetFullPage(kTestAllocSize);
950 WTF::PartitionPage* page2 = GetFullPage(kTestAllocSize); 950 PartitionPage* page2 = GetFullPage(kTestAllocSize);
951 void* ptr = partitionAlloc(allocator.root(), kTestAllocSize); 951 void* ptr = partitionAlloc(allocator.root(), kTestAllocSize);
952 EXPECT_TRUE(ptr); 952 EXPECT_TRUE(ptr);
953 EXPECT_NE(page1, bucket->activePagesHead); 953 EXPECT_NE(page1, bucket->activePagesHead);
954 EXPECT_NE(page2, bucket->activePagesHead); 954 EXPECT_NE(page2, bucket->activePagesHead);
955 WTF::PartitionPage* page = WTF::partitionPointerToPage(WTF::partitionCookieF reePointerAdjust(ptr)); 955 PartitionPage* page = partitionPointerToPage(partitionCookieFreePointerAdjus t(ptr));
956 EXPECT_EQ(1, page->numAllocatedSlots); 956 EXPECT_EQ(1, page->numAllocatedSlots);
957 957
958 // Work out a pointer into page2 and free it; and then page1 and free it. 958 // Work out a pointer into page2 and free it; and then page1 and free it.
959 char* ptr2 = reinterpret_cast<char*>(WTF::partitionPageToPointer(page1)) + k PointerOffset; 959 char* ptr2 = reinterpret_cast<char*>(partitionPageToPointer(page1)) + kPoint erOffset;
960 partitionFree(ptr2); 960 partitionFree(ptr2);
961 ptr2 = reinterpret_cast<char*>(WTF::partitionPageToPointer(page2)) + kPointe rOffset; 961 ptr2 = reinterpret_cast<char*>(partitionPageToPointer(page2)) + kPointerOffs et;
962 partitionFree(ptr2); 962 partitionFree(ptr2);
963 963
964 // If we perform two allocations from the same bucket now, we expect to 964 // If we perform two allocations from the same bucket now, we expect to
965 // refill both the nearly full pages. 965 // refill both the nearly full pages.
966 (void) partitionAlloc(allocator.root(), kTestAllocSize); 966 (void) partitionAlloc(allocator.root(), kTestAllocSize);
967 (void) partitionAlloc(allocator.root(), kTestAllocSize); 967 (void) partitionAlloc(allocator.root(), kTestAllocSize);
968 EXPECT_EQ(1, page->numAllocatedSlots); 968 EXPECT_EQ(1, page->numAllocatedSlots);
969 969
970 FreeFullPage(page2); 970 FreeFullPage(page2);
971 FreeFullPage(page1); 971 FreeFullPage(page1);
972 partitionFree(ptr); 972 partitionFree(ptr);
973 973
974 TestShutdown(); 974 TestShutdown();
975 } 975 }
976 976
977 // Basic tests to ensure that allocations work for partial page buckets. 977 // Basic tests to ensure that allocations work for partial page buckets.
978 TEST(PartitionAllocTest, PartialPages) 978 TEST(PartitionAllocTest, PartialPages)
979 { 979 {
980 TestSetup(); 980 TestSetup();
981 981
982 // Find a size that is backed by a partial partition page. 982 // Find a size that is backed by a partial partition page.
983 size_t size = sizeof(void*); 983 size_t size = sizeof(void*);
984 WTF::PartitionBucket* bucket = 0; 984 PartitionBucket* bucket = 0;
985 while (size < kTestMaxAllocation) { 985 while (size < kTestMaxAllocation) {
986 bucket = &allocator.root()->buckets()[size >> WTF::kBucketShift]; 986 bucket = &allocator.root()->buckets()[size >> kBucketShift];
987 if (bucket->numSystemPagesPerSlotSpan % WTF::kNumSystemPagesPerPartition Page) 987 if (bucket->numSystemPagesPerSlotSpan % kNumSystemPagesPerPartitionPage)
988 break; 988 break;
989 size += sizeof(void*); 989 size += sizeof(void*);
990 } 990 }
991 EXPECT_LT(size, kTestMaxAllocation); 991 EXPECT_LT(size, kTestMaxAllocation);
992 992
993 WTF::PartitionPage* page1 = GetFullPage(size); 993 PartitionPage* page1 = GetFullPage(size);
994 WTF::PartitionPage* page2 = GetFullPage(size); 994 PartitionPage* page2 = GetFullPage(size);
995 FreeFullPage(page2); 995 FreeFullPage(page2);
996 FreeFullPage(page1); 996 FreeFullPage(page1);
997 997
998 TestShutdown(); 998 TestShutdown();
999 } 999 }
1000 1000
1001 // Test correct handling if our mapping collides with another. 1001 // Test correct handling if our mapping collides with another.
1002 TEST(PartitionAllocTest, MappingCollision) 1002 TEST(PartitionAllocTest, MappingCollision)
1003 { 1003 {
1004 TestSetup(); 1004 TestSetup();
1005 // The -2 is because the first and last partition pages in a super page are 1005 // The -2 is because the first and last partition pages in a super page are
1006 // guard pages. 1006 // guard pages.
1007 size_t numPartitionPagesNeeded = WTF::kNumPartitionPagesPerSuperPage - 2; 1007 size_t numPartitionPagesNeeded = kNumPartitionPagesPerSuperPage - 2;
1008 OwnPtr<WTF::PartitionPage*[]> firstSuperPagePages = adoptArrayPtr(new WTF::P artitionPage*[numPartitionPagesNeeded]); 1008 OwnPtr<PartitionPage*[]> firstSuperPagePages = adoptArrayPtr(new PartitionPa ge*[numPartitionPagesNeeded]);
1009 OwnPtr<WTF::PartitionPage*[]> secondSuperPagePages = adoptArrayPtr(new WTF:: PartitionPage*[numPartitionPagesNeeded]); 1009 OwnPtr<PartitionPage*[]> secondSuperPagePages = adoptArrayPtr(new PartitionP age*[numPartitionPagesNeeded]);
1010 1010
1011 size_t i; 1011 size_t i;
1012 for (i = 0; i < numPartitionPagesNeeded; ++i) 1012 for (i = 0; i < numPartitionPagesNeeded; ++i)
1013 firstSuperPagePages[i] = GetFullPage(kTestAllocSize); 1013 firstSuperPagePages[i] = GetFullPage(kTestAllocSize);
1014 1014
1015 char* pageBase = reinterpret_cast<char*>(WTF::partitionPageToPointer(firstSu perPagePages[0])); 1015 char* pageBase = reinterpret_cast<char*>(partitionPageToPointer(firstSuperPa gePages[0]));
1016 EXPECT_EQ(WTF::kPartitionPageSize, reinterpret_cast<uintptr_t>(pageBase) & W TF::kSuperPageOffsetMask); 1016 EXPECT_EQ(kPartitionPageSize, reinterpret_cast<uintptr_t>(pageBase) & kSuper PageOffsetMask);
1017 pageBase -= WTF::kPartitionPageSize; 1017 pageBase -= kPartitionPageSize;
1018 // Map a single system page either side of the mapping for our allocations, 1018 // Map a single system page either side of the mapping for our allocations,
1019 // with the goal of tripping up alignment of the next mapping. 1019 // with the goal of tripping up alignment of the next mapping.
1020 void* map1 = WTF::allocPages(pageBase - WTF::kPageAllocationGranularity, WTF ::kPageAllocationGranularity, WTF::kPageAllocationGranularity, WTF::PageInaccess ible); 1020 void* map1 = allocPages(pageBase - kPageAllocationGranularity, kPageAllocati onGranularity, kPageAllocationGranularity, PageInaccessible);
1021 EXPECT_TRUE(map1); 1021 EXPECT_TRUE(map1);
1022 void* map2 = WTF::allocPages(pageBase + WTF::kSuperPageSize, WTF::kPageAlloc ationGranularity, WTF::kPageAllocationGranularity, WTF::PageInaccessible); 1022 void* map2 = allocPages(pageBase + kSuperPageSize, kPageAllocationGranularit y, kPageAllocationGranularity, PageInaccessible);
1023 EXPECT_TRUE(map2); 1023 EXPECT_TRUE(map2);
1024 1024
1025 for (i = 0; i < numPartitionPagesNeeded; ++i) 1025 for (i = 0; i < numPartitionPagesNeeded; ++i)
1026 secondSuperPagePages[i] = GetFullPage(kTestAllocSize); 1026 secondSuperPagePages[i] = GetFullPage(kTestAllocSize);
1027 1027
1028 WTF::freePages(map1, WTF::kPageAllocationGranularity); 1028 freePages(map1, kPageAllocationGranularity);
1029 WTF::freePages(map2, WTF::kPageAllocationGranularity); 1029 freePages(map2, kPageAllocationGranularity);
1030 1030
1031 pageBase = reinterpret_cast<char*>(partitionPageToPointer(secondSuperPagePag es[0])); 1031 pageBase = reinterpret_cast<char*>(partitionPageToPointer(secondSuperPagePag es[0]));
1032 EXPECT_EQ(WTF::kPartitionPageSize, reinterpret_cast<uintptr_t>(pageBase) & W TF::kSuperPageOffsetMask); 1032 EXPECT_EQ(kPartitionPageSize, reinterpret_cast<uintptr_t>(pageBase) & kSuper PageOffsetMask);
1033 pageBase -= WTF::kPartitionPageSize; 1033 pageBase -= kPartitionPageSize;
1034 // Map a single system page either side of the mapping for our allocations, 1034 // Map a single system page either side of the mapping for our allocations,
1035 // with the goal of tripping up alignment of the next mapping. 1035 // with the goal of tripping up alignment of the next mapping.
1036 map1 = WTF::allocPages(pageBase - WTF::kPageAllocationGranularity, WTF::kPag eAllocationGranularity, WTF::kPageAllocationGranularity, WTF::PageAccessible); 1036 map1 = allocPages(pageBase - kPageAllocationGranularity, kPageAllocationGran ularity, kPageAllocationGranularity, PageAccessible);
1037 EXPECT_TRUE(map1); 1037 EXPECT_TRUE(map1);
1038 map2 = WTF::allocPages(pageBase + WTF::kSuperPageSize, WTF::kPageAllocationG ranularity, WTF::kPageAllocationGranularity, WTF::PageAccessible); 1038 map2 = allocPages(pageBase + kSuperPageSize, kPageAllocationGranularity, kPa geAllocationGranularity, PageAccessible);
1039 EXPECT_TRUE(map2); 1039 EXPECT_TRUE(map2);
1040 WTF::setSystemPagesInaccessible(map1, WTF::kPageAllocationGranularity); 1040 setSystemPagesInaccessible(map1, kPageAllocationGranularity);
1041 WTF::setSystemPagesInaccessible(map2, WTF::kPageAllocationGranularity); 1041 setSystemPagesInaccessible(map2, kPageAllocationGranularity);
1042 1042
1043 WTF::PartitionPage* pageInThirdSuperPage = GetFullPage(kTestAllocSize); 1043 PartitionPage* pageInThirdSuperPage = GetFullPage(kTestAllocSize);
1044 WTF::freePages(map1, WTF::kPageAllocationGranularity); 1044 freePages(map1, kPageAllocationGranularity);
1045 WTF::freePages(map2, WTF::kPageAllocationGranularity); 1045 freePages(map2, kPageAllocationGranularity);
1046 1046
1047 EXPECT_EQ(0u, reinterpret_cast<uintptr_t>(partitionPageToPointer(pageInThird SuperPage)) & WTF::kPartitionPageOffsetMask); 1047 EXPECT_EQ(0u, reinterpret_cast<uintptr_t>(partitionPageToPointer(pageInThird SuperPage)) & kPartitionPageOffsetMask);
1048 1048
1049 // And make sure we really did get a page in a new superpage. 1049 // And make sure we really did get a page in a new superpage.
1050 EXPECT_NE(reinterpret_cast<uintptr_t>(partitionPageToPointer(firstSuperPageP ages[0])) & WTF::kSuperPageBaseMask, reinterpret_cast<uintptr_t>(partitionPageTo Pointer(pageInThirdSuperPage)) & WTF::kSuperPageBaseMask); 1050 EXPECT_NE(reinterpret_cast<uintptr_t>(partitionPageToPointer(firstSuperPageP ages[0])) & kSuperPageBaseMask, reinterpret_cast<uintptr_t>(partitionPageToPoint er(pageInThirdSuperPage)) & kSuperPageBaseMask);
1051 EXPECT_NE(reinterpret_cast<uintptr_t>(partitionPageToPointer(secondSuperPage Pages[0])) & WTF::kSuperPageBaseMask, reinterpret_cast<uintptr_t>(partitionPageT oPointer(pageInThirdSuperPage)) & WTF::kSuperPageBaseMask); 1051 EXPECT_NE(reinterpret_cast<uintptr_t>(partitionPageToPointer(secondSuperPage Pages[0])) & kSuperPageBaseMask, reinterpret_cast<uintptr_t>(partitionPageToPoin ter(pageInThirdSuperPage)) & kSuperPageBaseMask);
1052 1052
1053 FreeFullPage(pageInThirdSuperPage); 1053 FreeFullPage(pageInThirdSuperPage);
1054 for (i = 0; i < numPartitionPagesNeeded; ++i) { 1054 for (i = 0; i < numPartitionPagesNeeded; ++i) {
1055 FreeFullPage(firstSuperPagePages[i]); 1055 FreeFullPage(firstSuperPagePages[i]);
1056 FreeFullPage(secondSuperPagePages[i]); 1056 FreeFullPage(secondSuperPagePages[i]);
1057 } 1057 }
1058 1058
1059 TestShutdown(); 1059 TestShutdown();
1060 } 1060 }
1061 1061
1062 // Tests that pages in the free page cache do get freed as appropriate. 1062 // Tests that pages in the free page cache do get freed as appropriate.
1063 TEST(PartitionAllocTest, FreeCache) 1063 TEST(PartitionAllocTest, FreeCache)
1064 { 1064 {
1065 TestSetup(); 1065 TestSetup();
1066 1066
1067 EXPECT_EQ(0U, allocator.root()->totalSizeOfCommittedPages); 1067 EXPECT_EQ(0U, allocator.root()->totalSizeOfCommittedPages);
1068 1068
1069 size_t bigSize = allocator.root()->maxAllocation - kExtraAllocSize; 1069 size_t bigSize = allocator.root()->maxAllocation - kExtraAllocSize;
1070 size_t bucketIdx = (bigSize + kExtraAllocSize) >> WTF::kBucketShift; 1070 size_t bucketIdx = (bigSize + kExtraAllocSize) >> kBucketShift;
1071 WTF::PartitionBucket* bucket = &allocator.root()->buckets()[bucketIdx]; 1071 PartitionBucket* bucket = &allocator.root()->buckets()[bucketIdx];
1072 1072
1073 void* ptr = partitionAlloc(allocator.root(), bigSize); 1073 void* ptr = partitionAlloc(allocator.root(), bigSize);
1074 EXPECT_TRUE(ptr); 1074 EXPECT_TRUE(ptr);
1075 WTF::PartitionPage* page = WTF::partitionPointerToPage(WTF::partitionCookieF reePointerAdjust(ptr)); 1075 PartitionPage* page = partitionPointerToPage(partitionCookieFreePointerAdjus t(ptr));
1076 EXPECT_EQ(0, bucket->emptyPagesHead); 1076 EXPECT_EQ(0, bucket->emptyPagesHead);
1077 EXPECT_EQ(1, page->numAllocatedSlots); 1077 EXPECT_EQ(1, page->numAllocatedSlots);
1078 EXPECT_EQ(WTF::kPartitionPageSize, allocator.root()->totalSizeOfCommittedPag es); 1078 EXPECT_EQ(kPartitionPageSize, allocator.root()->totalSizeOfCommittedPages);
1079 partitionFree(ptr); 1079 partitionFree(ptr);
1080 EXPECT_EQ(0, page->numAllocatedSlots); 1080 EXPECT_EQ(0, page->numAllocatedSlots);
1081 EXPECT_NE(-1, page->emptyCacheIndex); 1081 EXPECT_NE(-1, page->emptyCacheIndex);
1082 EXPECT_TRUE(page->freelistHead); 1082 EXPECT_TRUE(page->freelistHead);
1083 1083
1084 CycleFreeCache(kTestAllocSize); 1084 CycleFreeCache(kTestAllocSize);
1085 1085
1086 // Flushing the cache should have really freed the unused page. 1086 // Flushing the cache should have really freed the unused page.
1087 EXPECT_FALSE(page->freelistHead); 1087 EXPECT_FALSE(page->freelistHead);
1088 EXPECT_EQ(-1, page->emptyCacheIndex); 1088 EXPECT_EQ(-1, page->emptyCacheIndex);
1089 EXPECT_EQ(0, page->numAllocatedSlots); 1089 EXPECT_EQ(0, page->numAllocatedSlots);
1090 WTF::PartitionBucket* cycleFreeCacheBucket = &allocator.root()->buckets()[kT estBucketIndex]; 1090 PartitionBucket* cycleFreeCacheBucket = &allocator.root()->buckets()[kTestBu cketIndex];
1091 EXPECT_EQ(cycleFreeCacheBucket->numSystemPagesPerSlotSpan * WTF::kSystemPage Size, allocator.root()->totalSizeOfCommittedPages); 1091 EXPECT_EQ(cycleFreeCacheBucket->numSystemPagesPerSlotSpan * kSystemPageSize, allocator.root()->totalSizeOfCommittedPages);
1092 1092
1093 // Check that an allocation works ok whilst in this state (a free'd page 1093 // Check that an allocation works ok whilst in this state (a free'd page
1094 // as the active pages head). 1094 // as the active pages head).
1095 ptr = partitionAlloc(allocator.root(), bigSize); 1095 ptr = partitionAlloc(allocator.root(), bigSize);
1096 EXPECT_FALSE(bucket->emptyPagesHead); 1096 EXPECT_FALSE(bucket->emptyPagesHead);
1097 partitionFree(ptr); 1097 partitionFree(ptr);
1098 1098
1099 // Also check that a page that is bouncing immediately between empty and 1099 // Also check that a page that is bouncing immediately between empty and
1100 // used does not get freed. 1100 // used does not get freed.
1101 for (size_t i = 0; i < WTF::kMaxFreeableSpans * 2; ++i) { 1101 for (size_t i = 0; i < kMaxFreeableSpans * 2; ++i) {
1102 ptr = partitionAlloc(allocator.root(), bigSize); 1102 ptr = partitionAlloc(allocator.root(), bigSize);
1103 EXPECT_TRUE(page->freelistHead); 1103 EXPECT_TRUE(page->freelistHead);
1104 partitionFree(ptr); 1104 partitionFree(ptr);
1105 EXPECT_TRUE(page->freelistHead); 1105 EXPECT_TRUE(page->freelistHead);
1106 } 1106 }
1107 EXPECT_EQ(WTF::kPartitionPageSize, allocator.root()->totalSizeOfCommittedPag es); 1107 EXPECT_EQ(kPartitionPageSize, allocator.root()->totalSizeOfCommittedPages);
1108 TestShutdown(); 1108 TestShutdown();
1109 } 1109 }
1110 1110
1111 // Tests for a bug we had with losing references to free pages. 1111 // Tests for a bug we had with losing references to free pages.
1112 TEST(PartitionAllocTest, LostFreePagesBug) 1112 TEST(PartitionAllocTest, LostFreePagesBug)
1113 { 1113 {
1114 TestSetup(); 1114 TestSetup();
1115 1115
1116 size_t size = WTF::kPartitionPageSize - kExtraAllocSize; 1116 size_t size = kPartitionPageSize - kExtraAllocSize;
1117 1117
1118 void* ptr = partitionAllocGeneric(genericAllocator.root(), size); 1118 void* ptr = partitionAllocGeneric(genericAllocator.root(), size);
1119 EXPECT_TRUE(ptr); 1119 EXPECT_TRUE(ptr);
1120 void* ptr2 = partitionAllocGeneric(genericAllocator.root(), size); 1120 void* ptr2 = partitionAllocGeneric(genericAllocator.root(), size);
1121 EXPECT_TRUE(ptr2); 1121 EXPECT_TRUE(ptr2);
1122 1122
1123 WTF::PartitionPage* page = WTF::partitionPointerToPage(WTF::partitionCookieF reePointerAdjust(ptr)); 1123 PartitionPage* page = partitionPointerToPage(partitionCookieFreePointerAdjus t(ptr));
1124 WTF::PartitionPage* page2 = WTF::partitionPointerToPage(WTF::partitionCookie FreePointerAdjust(ptr2)); 1124 PartitionPage* page2 = partitionPointerToPage(partitionCookieFreePointerAdju st(ptr2));
1125 WTF::PartitionBucket* bucket = page->bucket; 1125 PartitionBucket* bucket = page->bucket;
1126 1126
1127 EXPECT_EQ(0, bucket->emptyPagesHead); 1127 EXPECT_EQ(0, bucket->emptyPagesHead);
1128 EXPECT_EQ(-1, page->numAllocatedSlots); 1128 EXPECT_EQ(-1, page->numAllocatedSlots);
1129 EXPECT_EQ(1, page2->numAllocatedSlots); 1129 EXPECT_EQ(1, page2->numAllocatedSlots);
1130 1130
1131 partitionFreeGeneric(genericAllocator.root(), ptr); 1131 partitionFreeGeneric(genericAllocator.root(), ptr);
1132 partitionFreeGeneric(genericAllocator.root(), ptr2); 1132 partitionFreeGeneric(genericAllocator.root(), ptr2);
1133 1133
1134 EXPECT_EQ(0, bucket->emptyPagesHead); 1134 EXPECT_EQ(0, bucket->emptyPagesHead);
1135 EXPECT_EQ(0, page->numAllocatedSlots); 1135 EXPECT_EQ(0, page->numAllocatedSlots);
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
1188 EXPECT_TRUE(SetAddressSpaceLimit()); 1188 EXPECT_TRUE(SetAddressSpaceLimit());
1189 1189
1190 // 512 kB x 12288 == 6 GB 1190 // 512 kB x 12288 == 6 GB
1191 const size_t blockSize = 512 * 1024; 1191 const size_t blockSize = 512 * 1024;
1192 const int numAllocations = 12288; 1192 const int numAllocations = 12288;
1193 1193
1194 void* ptrs[numAllocations]; 1194 void* ptrs[numAllocations];
1195 int i; 1195 int i;
1196 1196
1197 for (i = 0; i < numAllocations; ++i) { 1197 for (i = 0; i < numAllocations; ++i) {
1198 ptrs[i] = partitionAllocGenericFlags(genericAllocator.root(), WTF::Parti tionAllocReturnNull, blockSize); 1198 ptrs[i] = partitionAllocGenericFlags(genericAllocator.root(), PartitionA llocReturnNull, blockSize);
1199 if (!ptrs[i]) { 1199 if (!ptrs[i]) {
1200 ptrs[i] = partitionAllocGenericFlags(genericAllocator.root(), WTF::P artitionAllocReturnNull, blockSize); 1200 ptrs[i] = partitionAllocGenericFlags(genericAllocator.root(), Partit ionAllocReturnNull, blockSize);
1201 EXPECT_FALSE(ptrs[i]); 1201 EXPECT_FALSE(ptrs[i]);
1202 break; 1202 break;
1203 } 1203 }
1204 } 1204 }
1205 1205
1206 // We shouldn't succeed in allocating all 6 GB of memory. If we do, then 1206 // We shouldn't succeed in allocating all 6 GB of memory. If we do, then
1207 // we're not actually testing anything here. 1207 // we're not actually testing anything here.
1208 EXPECT_LT(i, numAllocations); 1208 EXPECT_LT(i, numAllocations);
1209 1209
1210 // Free, reallocate and free again each block we allocated. We do this to 1210 // Free, reallocate and free again each block we allocated. We do this to
1211 // check that freeing memory also works correctly after a failed allocation. 1211 // check that freeing memory also works correctly after a failed allocation.
1212 for (--i; i >= 0; --i) { 1212 for (--i; i >= 0; --i) {
1213 partitionFreeGeneric(genericAllocator.root(), ptrs[i]); 1213 partitionFreeGeneric(genericAllocator.root(), ptrs[i]);
1214 ptrs[i] = partitionAllocGenericFlags(genericAllocator.root(), WTF::Parti tionAllocReturnNull, blockSize); 1214 ptrs[i] = partitionAllocGenericFlags(genericAllocator.root(), PartitionA llocReturnNull, blockSize);
1215 EXPECT_TRUE(ptrs[i]); 1215 EXPECT_TRUE(ptrs[i]);
1216 partitionFreeGeneric(genericAllocator.root(), ptrs[i]); 1216 partitionFreeGeneric(genericAllocator.root(), ptrs[i]);
1217 } 1217 }
1218 1218
1219 EXPECT_TRUE(ClearAddressSpaceLimit()); 1219 EXPECT_TRUE(ClearAddressSpaceLimit());
1220 1220
1221 TestShutdown(); 1221 TestShutdown();
1222 } 1222 }
1223 1223
1224 #endif // !CPU(64BIT) || OS(POSIX) 1224 #endif // !CPU(64BIT) || OS(POSIX)
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
1272 TestShutdown(); 1272 TestShutdown();
1273 } 1273 }
1274 1274
1275 // Check that guard pages are present where expected. 1275 // Check that guard pages are present where expected.
1276 TEST(PartitionAllocDeathTest, GuardPages) 1276 TEST(PartitionAllocDeathTest, GuardPages)
1277 { 1277 {
1278 TestSetup(); 1278 TestSetup();
1279 1279
1280 // This large size will result in a direct mapped allocation with guard 1280 // This large size will result in a direct mapped allocation with guard
1281 // pages at either end. 1281 // pages at either end.
1282 size_t size = (WTF::kGenericMaxBucketed + WTF::kSystemPageSize) - kExtraAllo cSize; 1282 size_t size = (kGenericMaxBucketed + kSystemPageSize) - kExtraAllocSize;
1283 void* ptr = partitionAllocGeneric(genericAllocator.root(), size); 1283 void* ptr = partitionAllocGeneric(genericAllocator.root(), size);
1284 EXPECT_TRUE(ptr); 1284 EXPECT_TRUE(ptr);
1285 char* charPtr = reinterpret_cast<char*>(ptr) - kPointerOffset; 1285 char* charPtr = reinterpret_cast<char*>(ptr) - kPointerOffset;
1286 1286
1287 EXPECT_DEATH(*(charPtr - 1) = 'A', ""); 1287 EXPECT_DEATH(*(charPtr - 1) = 'A', "");
1288 EXPECT_DEATH(*(charPtr + size + kExtraAllocSize) = 'A', ""); 1288 EXPECT_DEATH(*(charPtr + size + kExtraAllocSize) = 'A', "");
1289 1289
1290 partitionFreeGeneric(genericAllocator.root(), ptr); 1290 partitionFreeGeneric(genericAllocator.root(), ptr);
1291 1291
1292 TestShutdown(); 1292 TestShutdown();
1293 } 1293 }
1294 1294
1295 // Check that a bad free() is caught where the free() refers to an unused 1295 // Check that a bad free() is caught where the free() refers to an unused
1296 // partition page of a large allocation. 1296 // partition page of a large allocation.
1297 TEST(PartitionAllocDeathTest, FreeWrongPartitionPage) 1297 TEST(PartitionAllocDeathTest, FreeWrongPartitionPage)
1298 { 1298 {
1299 TestSetup(); 1299 TestSetup();
1300 1300
1301 // This large size will result in a direct mapped allocation with guard 1301 // This large size will result in a direct mapped allocation with guard
1302 // pages at either end. 1302 // pages at either end.
1303 void* ptr = partitionAllocGeneric(genericAllocator.root(), WTF::kPartitionPa geSize * 2); 1303 void* ptr = partitionAllocGeneric(genericAllocator.root(), kPartitionPageSiz e * 2);
1304 EXPECT_TRUE(ptr); 1304 EXPECT_TRUE(ptr);
1305 char* badPtr = reinterpret_cast<char*>(ptr) + WTF::kPartitionPageSize; 1305 char* badPtr = reinterpret_cast<char*>(ptr) + kPartitionPageSize;
1306 1306
1307 EXPECT_DEATH(partitionFreeGeneric(genericAllocator.root(), badPtr), ""); 1307 EXPECT_DEATH(partitionFreeGeneric(genericAllocator.root(), badPtr), "");
1308 1308
1309 partitionFreeGeneric(genericAllocator.root(), ptr); 1309 partitionFreeGeneric(genericAllocator.root(), ptr);
1310 1310
1311 TestShutdown(); 1311 TestShutdown();
1312 } 1312 }
1313 1313
1314 #endif // !OS(ANDROID) 1314 #endif // !OS(ANDROID)
1315 1315
(...skipping 12 matching lines...) Expand all
1328 } 1328 }
1329 1329
1330 // This series of tests checks the active -> empty -> decommitted states. 1330 // This series of tests checks the active -> empty -> decommitted states.
1331 { 1331 {
1332 void* genericPtr = partitionAllocGeneric(genericAllocator.root(), 2048 - kExtraAllocSize); 1332 void* genericPtr = partitionAllocGeneric(genericAllocator.root(), 2048 - kExtraAllocSize);
1333 { 1333 {
1334 MockPartitionStatsDumper mockStatsDumperGeneric; 1334 MockPartitionStatsDumper mockStatsDumperGeneric;
1335 partitionDumpStatsGeneric(genericAllocator.root(), "mock_generic_all ocator", &mockStatsDumperGeneric); 1335 partitionDumpStatsGeneric(genericAllocator.root(), "mock_generic_all ocator", &mockStatsDumperGeneric);
1336 EXPECT_TRUE(mockStatsDumperGeneric.IsMemoryAllocationRecorded()); 1336 EXPECT_TRUE(mockStatsDumperGeneric.IsMemoryAllocationRecorded());
1337 1337
1338 const WTF::PartitionBucketMemoryStats* stats = mockStatsDumperGeneri c.GetBucketStats(2048); 1338 const PartitionBucketMemoryStats* stats = mockStatsDumperGeneric.Get BucketStats(2048);
1339 EXPECT_TRUE(stats); 1339 EXPECT_TRUE(stats);
1340 EXPECT_TRUE(stats->isValid); 1340 EXPECT_TRUE(stats->isValid);
1341 EXPECT_EQ(2048u, stats->bucketSlotSize); 1341 EXPECT_EQ(2048u, stats->bucketSlotSize);
1342 EXPECT_EQ(2048u, stats->activeBytes); 1342 EXPECT_EQ(2048u, stats->activeBytes);
1343 EXPECT_EQ(WTF::kSystemPageSize, stats->residentBytes); 1343 EXPECT_EQ(kSystemPageSize, stats->residentBytes);
1344 EXPECT_EQ(0u, stats->freeableBytes); 1344 EXPECT_EQ(0u, stats->freeableBytes);
1345 EXPECT_EQ(0u, stats->numFullPages); 1345 EXPECT_EQ(0u, stats->numFullPages);
1346 EXPECT_EQ(1u, stats->numActivePages); 1346 EXPECT_EQ(1u, stats->numActivePages);
1347 EXPECT_EQ(0u, stats->numEmptyPages); 1347 EXPECT_EQ(0u, stats->numEmptyPages);
1348 EXPECT_EQ(0u, stats->numDecommittedPages); 1348 EXPECT_EQ(0u, stats->numDecommittedPages);
1349 } 1349 }
1350 1350
1351 partitionFreeGeneric(genericAllocator.root(), genericPtr); 1351 partitionFreeGeneric(genericAllocator.root(), genericPtr);
1352 1352
1353 { 1353 {
1354 MockPartitionStatsDumper mockStatsDumperGeneric; 1354 MockPartitionStatsDumper mockStatsDumperGeneric;
1355 partitionDumpStatsGeneric(genericAllocator.root(), "mock_generic_all ocator", &mockStatsDumperGeneric); 1355 partitionDumpStatsGeneric(genericAllocator.root(), "mock_generic_all ocator", &mockStatsDumperGeneric);
1356 EXPECT_FALSE(mockStatsDumperGeneric.IsMemoryAllocationRecorded()); 1356 EXPECT_FALSE(mockStatsDumperGeneric.IsMemoryAllocationRecorded());
1357 1357
1358 const WTF::PartitionBucketMemoryStats* stats = mockStatsDumperGeneri c.GetBucketStats(2048); 1358 const PartitionBucketMemoryStats* stats = mockStatsDumperGeneric.Get BucketStats(2048);
1359 EXPECT_TRUE(stats); 1359 EXPECT_TRUE(stats);
1360 EXPECT_TRUE(stats->isValid); 1360 EXPECT_TRUE(stats->isValid);
1361 EXPECT_EQ(2048u, stats->bucketSlotSize); 1361 EXPECT_EQ(2048u, stats->bucketSlotSize);
1362 EXPECT_EQ(0u, stats->activeBytes); 1362 EXPECT_EQ(0u, stats->activeBytes);
1363 EXPECT_EQ(WTF::kSystemPageSize, stats->residentBytes); 1363 EXPECT_EQ(kSystemPageSize, stats->residentBytes);
1364 EXPECT_EQ(WTF::kSystemPageSize, stats->freeableBytes); 1364 EXPECT_EQ(kSystemPageSize, stats->freeableBytes);
1365 EXPECT_EQ(0u, stats->numFullPages); 1365 EXPECT_EQ(0u, stats->numFullPages);
1366 EXPECT_EQ(0u, stats->numActivePages); 1366 EXPECT_EQ(0u, stats->numActivePages);
1367 EXPECT_EQ(1u, stats->numEmptyPages); 1367 EXPECT_EQ(1u, stats->numEmptyPages);
1368 EXPECT_EQ(0u, stats->numDecommittedPages); 1368 EXPECT_EQ(0u, stats->numDecommittedPages);
1369 } 1369 }
1370 1370
1371 CycleGenericFreeCache(kTestAllocSize); 1371 CycleGenericFreeCache(kTestAllocSize);
1372 1372
1373 { 1373 {
1374 MockPartitionStatsDumper mockStatsDumperGeneric; 1374 MockPartitionStatsDumper mockStatsDumperGeneric;
1375 partitionDumpStatsGeneric(genericAllocator.root(), "mock_generic_all ocator", &mockStatsDumperGeneric); 1375 partitionDumpStatsGeneric(genericAllocator.root(), "mock_generic_all ocator", &mockStatsDumperGeneric);
1376 EXPECT_FALSE(mockStatsDumperGeneric.IsMemoryAllocationRecorded()); 1376 EXPECT_FALSE(mockStatsDumperGeneric.IsMemoryAllocationRecorded());
1377 1377
1378 const WTF::PartitionBucketMemoryStats* stats = mockStatsDumperGeneri c.GetBucketStats(2048); 1378 const PartitionBucketMemoryStats* stats = mockStatsDumperGeneric.Get BucketStats(2048);
1379 EXPECT_TRUE(stats); 1379 EXPECT_TRUE(stats);
1380 EXPECT_TRUE(stats->isValid); 1380 EXPECT_TRUE(stats->isValid);
1381 EXPECT_EQ(2048u, stats->bucketSlotSize); 1381 EXPECT_EQ(2048u, stats->bucketSlotSize);
1382 EXPECT_EQ(0u, stats->activeBytes); 1382 EXPECT_EQ(0u, stats->activeBytes);
1383 EXPECT_EQ(0u, stats->residentBytes); 1383 EXPECT_EQ(0u, stats->residentBytes);
1384 EXPECT_EQ(0u, stats->freeableBytes); 1384 EXPECT_EQ(0u, stats->freeableBytes);
1385 EXPECT_EQ(0u, stats->numFullPages); 1385 EXPECT_EQ(0u, stats->numFullPages);
1386 EXPECT_EQ(0u, stats->numActivePages); 1386 EXPECT_EQ(0u, stats->numActivePages);
1387 EXPECT_EQ(0u, stats->numEmptyPages); 1387 EXPECT_EQ(0u, stats->numEmptyPages);
1388 EXPECT_EQ(1u, stats->numDecommittedPages); 1388 EXPECT_EQ(1u, stats->numDecommittedPages);
1389 } 1389 }
1390 } 1390 }
1391 1391
1392 // This test checks for correct empty page list accounting. 1392 // This test checks for correct empty page list accounting.
1393 { 1393 {
1394 size_t size = WTF::kPartitionPageSize - kExtraAllocSize; 1394 size_t size = kPartitionPageSize - kExtraAllocSize;
1395 void* ptr1 = partitionAllocGeneric(genericAllocator.root(), size); 1395 void* ptr1 = partitionAllocGeneric(genericAllocator.root(), size);
1396 void* ptr2 = partitionAllocGeneric(genericAllocator.root(), size); 1396 void* ptr2 = partitionAllocGeneric(genericAllocator.root(), size);
1397 partitionFreeGeneric(genericAllocator.root(), ptr1); 1397 partitionFreeGeneric(genericAllocator.root(), ptr1);
1398 partitionFreeGeneric(genericAllocator.root(), ptr2); 1398 partitionFreeGeneric(genericAllocator.root(), ptr2);
1399 1399
1400 CycleGenericFreeCache(kTestAllocSize); 1400 CycleGenericFreeCache(kTestAllocSize);
1401 1401
1402 ptr1 = partitionAllocGeneric(genericAllocator.root(), size); 1402 ptr1 = partitionAllocGeneric(genericAllocator.root(), size);
1403 1403
1404 { 1404 {
1405 MockPartitionStatsDumper mockStatsDumperGeneric; 1405 MockPartitionStatsDumper mockStatsDumperGeneric;
1406 partitionDumpStatsGeneric(genericAllocator.root(), "mock_generic_all ocator", &mockStatsDumperGeneric); 1406 partitionDumpStatsGeneric(genericAllocator.root(), "mock_generic_all ocator", &mockStatsDumperGeneric);
1407 EXPECT_TRUE(mockStatsDumperGeneric.IsMemoryAllocationRecorded()); 1407 EXPECT_TRUE(mockStatsDumperGeneric.IsMemoryAllocationRecorded());
1408 1408
1409 const WTF::PartitionBucketMemoryStats* stats = mockStatsDumperGeneri c.GetBucketStats(WTF::kPartitionPageSize); 1409 const PartitionBucketMemoryStats* stats = mockStatsDumperGeneric.Get BucketStats(kPartitionPageSize);
1410 EXPECT_TRUE(stats); 1410 EXPECT_TRUE(stats);
1411 EXPECT_TRUE(stats->isValid); 1411 EXPECT_TRUE(stats->isValid);
1412 EXPECT_EQ(WTF::kPartitionPageSize, stats->bucketSlotSize); 1412 EXPECT_EQ(kPartitionPageSize, stats->bucketSlotSize);
1413 EXPECT_EQ(WTF::kPartitionPageSize, stats->activeBytes); 1413 EXPECT_EQ(kPartitionPageSize, stats->activeBytes);
1414 EXPECT_EQ(WTF::kPartitionPageSize, stats->residentBytes); 1414 EXPECT_EQ(kPartitionPageSize, stats->residentBytes);
1415 EXPECT_EQ(0u, stats->freeableBytes); 1415 EXPECT_EQ(0u, stats->freeableBytes);
1416 EXPECT_EQ(1u, stats->numFullPages); 1416 EXPECT_EQ(1u, stats->numFullPages);
1417 EXPECT_EQ(0u, stats->numActivePages); 1417 EXPECT_EQ(0u, stats->numActivePages);
1418 EXPECT_EQ(0u, stats->numEmptyPages); 1418 EXPECT_EQ(0u, stats->numEmptyPages);
1419 EXPECT_EQ(1u, stats->numDecommittedPages); 1419 EXPECT_EQ(1u, stats->numDecommittedPages);
1420 } 1420 }
1421 partitionFreeGeneric(genericAllocator.root(), ptr1); 1421 partitionFreeGeneric(genericAllocator.root(), ptr1);
1422 } 1422 }
1423 1423
1424 // This test checks for correct direct mapped accounting. 1424 // This test checks for correct direct mapped accounting.
1425 { 1425 {
1426 size_t sizeSmaller = WTF::kGenericMaxBucketed + 1; 1426 size_t sizeSmaller = kGenericMaxBucketed + 1;
1427 size_t sizeBigger = (WTF::kGenericMaxBucketed * 2) + 1; 1427 size_t sizeBigger = (kGenericMaxBucketed * 2) + 1;
1428 size_t realSizeSmaller = (sizeSmaller + WTF::kSystemPageOffsetMask) & WT F::kSystemPageBaseMask; 1428 size_t realSizeSmaller = (sizeSmaller + kSystemPageOffsetMask) & kSystem PageBaseMask;
1429 size_t realSizeBigger = (sizeBigger + WTF::kSystemPageOffsetMask) & WTF: :kSystemPageBaseMask; 1429 size_t realSizeBigger = (sizeBigger + kSystemPageOffsetMask) & kSystemPa geBaseMask;
1430 void* ptr = partitionAllocGeneric(genericAllocator.root(), sizeSmaller); 1430 void* ptr = partitionAllocGeneric(genericAllocator.root(), sizeSmaller);
1431 void* ptr2 = partitionAllocGeneric(genericAllocator.root(), sizeBigger); 1431 void* ptr2 = partitionAllocGeneric(genericAllocator.root(), sizeBigger);
1432 1432
1433 { 1433 {
1434 MockPartitionStatsDumper mockStatsDumperGeneric; 1434 MockPartitionStatsDumper mockStatsDumperGeneric;
1435 partitionDumpStatsGeneric(genericAllocator.root(), "mock_generic_all ocator", &mockStatsDumperGeneric); 1435 partitionDumpStatsGeneric(genericAllocator.root(), "mock_generic_all ocator", &mockStatsDumperGeneric);
1436 EXPECT_TRUE(mockStatsDumperGeneric.IsMemoryAllocationRecorded()); 1436 EXPECT_TRUE(mockStatsDumperGeneric.IsMemoryAllocationRecorded());
1437 1437
1438 const WTF::PartitionBucketMemoryStats* stats = mockStatsDumperGeneri c.GetBucketStats(realSizeSmaller); 1438 const PartitionBucketMemoryStats* stats = mockStatsDumperGeneric.Get BucketStats(realSizeSmaller);
1439 EXPECT_TRUE(stats); 1439 EXPECT_TRUE(stats);
1440 EXPECT_TRUE(stats->isValid); 1440 EXPECT_TRUE(stats->isValid);
1441 EXPECT_TRUE(stats->isDirectMap); 1441 EXPECT_TRUE(stats->isDirectMap);
1442 EXPECT_EQ(realSizeSmaller, stats->bucketSlotSize); 1442 EXPECT_EQ(realSizeSmaller, stats->bucketSlotSize);
1443 EXPECT_EQ(realSizeSmaller, stats->activeBytes); 1443 EXPECT_EQ(realSizeSmaller, stats->activeBytes);
1444 EXPECT_EQ(realSizeSmaller, stats->residentBytes); 1444 EXPECT_EQ(realSizeSmaller, stats->residentBytes);
1445 EXPECT_EQ(0u, stats->freeableBytes); 1445 EXPECT_EQ(0u, stats->freeableBytes);
1446 EXPECT_EQ(1u, stats->numFullPages); 1446 EXPECT_EQ(1u, stats->numFullPages);
1447 EXPECT_EQ(0u, stats->numActivePages); 1447 EXPECT_EQ(0u, stats->numActivePages);
1448 EXPECT_EQ(0u, stats->numEmptyPages); 1448 EXPECT_EQ(0u, stats->numEmptyPages);
(...skipping 26 matching lines...) Expand all
1475 1475
1476 // This test checks large-but-not-quite-direct allocations. 1476 // This test checks large-but-not-quite-direct allocations.
1477 { 1477 {
1478 void* ptr = partitionAllocGeneric(genericAllocator.root(), 65537); 1478 void* ptr = partitionAllocGeneric(genericAllocator.root(), 65537);
1479 1479
1480 { 1480 {
1481 MockPartitionStatsDumper mockStatsDumperGeneric; 1481 MockPartitionStatsDumper mockStatsDumperGeneric;
1482 partitionDumpStatsGeneric(genericAllocator.root(), "mock_generic_all ocator", &mockStatsDumperGeneric); 1482 partitionDumpStatsGeneric(genericAllocator.root(), "mock_generic_all ocator", &mockStatsDumperGeneric);
1483 EXPECT_TRUE(mockStatsDumperGeneric.IsMemoryAllocationRecorded()); 1483 EXPECT_TRUE(mockStatsDumperGeneric.IsMemoryAllocationRecorded());
1484 1484
1485 size_t slotSize = 65536 + (65536 / WTF::kGenericNumBucketsPerOrder); 1485 size_t slotSize = 65536 + (65536 / kGenericNumBucketsPerOrder);
1486 const WTF::PartitionBucketMemoryStats* stats = mockStatsDumperGeneri c.GetBucketStats(slotSize); 1486 const PartitionBucketMemoryStats* stats = mockStatsDumperGeneric.Get BucketStats(slotSize);
1487 EXPECT_TRUE(stats); 1487 EXPECT_TRUE(stats);
1488 EXPECT_TRUE(stats->isValid); 1488 EXPECT_TRUE(stats->isValid);
1489 EXPECT_FALSE(stats->isDirectMap); 1489 EXPECT_FALSE(stats->isDirectMap);
1490 EXPECT_EQ(slotSize, stats->bucketSlotSize); 1490 EXPECT_EQ(slotSize, stats->bucketSlotSize);
1491 EXPECT_EQ(65536 + WTF::kSystemPageSize, stats->activeBytes); 1491 EXPECT_EQ(65536 + kSystemPageSize, stats->activeBytes);
1492 EXPECT_EQ(slotSize, stats->residentBytes); 1492 EXPECT_EQ(slotSize, stats->residentBytes);
1493 EXPECT_EQ(0u, stats->freeableBytes); 1493 EXPECT_EQ(0u, stats->freeableBytes);
1494 EXPECT_EQ(1u, stats->numFullPages); 1494 EXPECT_EQ(1u, stats->numFullPages);
1495 EXPECT_EQ(0u, stats->numActivePages); 1495 EXPECT_EQ(0u, stats->numActivePages);
1496 EXPECT_EQ(0u, stats->numEmptyPages); 1496 EXPECT_EQ(0u, stats->numEmptyPages);
1497 EXPECT_EQ(0u, stats->numDecommittedPages); 1497 EXPECT_EQ(0u, stats->numDecommittedPages);
1498 } 1498 }
1499 1499
1500 partitionFreeGeneric(genericAllocator.root(), ptr); 1500 partitionFreeGeneric(genericAllocator.root(), ptr);
1501 } 1501 }
1502 1502
1503 TestShutdown(); 1503 TestShutdown();
1504 } 1504 }
1505 1505
1506 // Tests the API to purge freeable memory. 1506 // Tests the API to purge freeable memory.
1507 TEST(PartitionAllocTest, Purge) 1507 TEST(PartitionAllocTest, Purge)
1508 { 1508 {
1509 TestSetup(); 1509 TestSetup();
1510 1510
1511 void* ptr = partitionAllocGeneric(genericAllocator.root(), 2048 - kExtraAllo cSize); 1511 void* ptr = partitionAllocGeneric(genericAllocator.root(), 2048 - kExtraAllo cSize);
1512 partitionFreeGeneric(genericAllocator.root(), ptr); 1512 partitionFreeGeneric(genericAllocator.root(), ptr);
1513 { 1513 {
1514 MockPartitionStatsDumper mockStatsDumperGeneric; 1514 MockPartitionStatsDumper mockStatsDumperGeneric;
1515 partitionDumpStatsGeneric(genericAllocator.root(), "mock_generic_allocat or", &mockStatsDumperGeneric); 1515 partitionDumpStatsGeneric(genericAllocator.root(), "mock_generic_allocat or", &mockStatsDumperGeneric);
1516 EXPECT_FALSE(mockStatsDumperGeneric.IsMemoryAllocationRecorded()); 1516 EXPECT_FALSE(mockStatsDumperGeneric.IsMemoryAllocationRecorded());
1517 1517
1518 const WTF::PartitionBucketMemoryStats* stats = mockStatsDumperGeneric.Ge tBucketStats(2048); 1518 const PartitionBucketMemoryStats* stats = mockStatsDumperGeneric.GetBuck etStats(2048);
1519 EXPECT_TRUE(stats); 1519 EXPECT_TRUE(stats);
1520 EXPECT_TRUE(stats->isValid); 1520 EXPECT_TRUE(stats->isValid);
1521 EXPECT_EQ(WTF::kSystemPageSize, stats->freeableBytes); 1521 EXPECT_EQ(kSystemPageSize, stats->freeableBytes);
1522 EXPECT_EQ(WTF::kSystemPageSize, stats->residentBytes); 1522 EXPECT_EQ(kSystemPageSize, stats->residentBytes);
1523 } 1523 }
1524 partitionPurgeMemoryGeneric(genericAllocator.root()); 1524 partitionPurgeMemoryGeneric(genericAllocator.root());
1525 { 1525 {
1526 MockPartitionStatsDumper mockStatsDumperGeneric; 1526 MockPartitionStatsDumper mockStatsDumperGeneric;
1527 partitionDumpStatsGeneric(genericAllocator.root(), "mock_generic_allocat or", &mockStatsDumperGeneric); 1527 partitionDumpStatsGeneric(genericAllocator.root(), "mock_generic_allocat or", &mockStatsDumperGeneric);
1528 EXPECT_FALSE(mockStatsDumperGeneric.IsMemoryAllocationRecorded()); 1528 EXPECT_FALSE(mockStatsDumperGeneric.IsMemoryAllocationRecorded());
1529 1529
1530 const WTF::PartitionBucketMemoryStats* stats = mockStatsDumperGeneric.Ge tBucketStats(2048); 1530 const PartitionBucketMemoryStats* stats = mockStatsDumperGeneric.GetBuck etStats(2048);
1531 EXPECT_TRUE(stats); 1531 EXPECT_TRUE(stats);
1532 EXPECT_TRUE(stats->isValid); 1532 EXPECT_TRUE(stats->isValid);
1533 EXPECT_EQ(0u, stats->freeableBytes); 1533 EXPECT_EQ(0u, stats->freeableBytes);
1534 EXPECT_EQ(0u, stats->residentBytes); 1534 EXPECT_EQ(0u, stats->residentBytes);
1535 } 1535 }
1536 // Calling purge again here is a good way of testing we didn't mess up the 1536 // Calling purge again here is a good way of testing we didn't mess up the
1537 // state of the free cache ring. 1537 // state of the free cache ring.
1538 partitionPurgeMemoryGeneric(genericAllocator.root()); 1538 partitionPurgeMemoryGeneric(genericAllocator.root());
1539 TestShutdown(); 1539 TestShutdown();
1540 } 1540 }
1541 1541
1542 // Tests that the countLeadingZeros() functions work to our satisfaction. 1542 // Tests that the countLeadingZeros() functions work to our satisfaction.
1543 // It doesn't seem worth the overhead of a whole new file for these tests, so 1543 // It doesn't seem worth the overhead of a whole new file for these tests, so
1544 // we'll put them here since partitionAllocGeneric will depend heavily on these 1544 // we'll put them here since partitionAllocGeneric will depend heavily on these
1545 // functions working correctly. 1545 // functions working correctly.
1546 TEST(PartitionAllocTest, CLZWorks) 1546 TEST(PartitionAllocTest, CLZWorks)
1547 { 1547 {
1548 EXPECT_EQ(32u, WTF::countLeadingZeros32(0u)); 1548 EXPECT_EQ(32u, countLeadingZeros32(0u));
1549 EXPECT_EQ(31u, WTF::countLeadingZeros32(1u)); 1549 EXPECT_EQ(31u, countLeadingZeros32(1u));
1550 EXPECT_EQ(1u, WTF::countLeadingZeros32(1u << 30)); 1550 EXPECT_EQ(1u, countLeadingZeros32(1u << 30));
1551 EXPECT_EQ(0u, WTF::countLeadingZeros32(1u << 31)); 1551 EXPECT_EQ(0u, countLeadingZeros32(1u << 31));
1552 1552
1553 #if CPU(64BIT) 1553 #if CPU(64BIT)
1554 EXPECT_EQ(64u, WTF::countLeadingZerosSizet(0ull)); 1554 EXPECT_EQ(64u, countLeadingZerosSizet(0ull));
1555 EXPECT_EQ(63u, WTF::countLeadingZerosSizet(1ull)); 1555 EXPECT_EQ(63u, countLeadingZerosSizet(1ull));
1556 EXPECT_EQ(32u, WTF::countLeadingZerosSizet(1ull << 31)); 1556 EXPECT_EQ(32u, countLeadingZerosSizet(1ull << 31));
1557 EXPECT_EQ(1u, WTF::countLeadingZerosSizet(1ull << 62)); 1557 EXPECT_EQ(1u, countLeadingZerosSizet(1ull << 62));
1558 EXPECT_EQ(0u, WTF::countLeadingZerosSizet(1ull << 63)); 1558 EXPECT_EQ(0u, countLeadingZerosSizet(1ull << 63));
1559 #else 1559 #else
1560 EXPECT_EQ(32u, WTF::countLeadingZerosSizet(0u)); 1560 EXPECT_EQ(32u, countLeadingZerosSizet(0u));
1561 EXPECT_EQ(31u, WTF::countLeadingZerosSizet(1u)); 1561 EXPECT_EQ(31u, countLeadingZerosSizet(1u));
1562 EXPECT_EQ(1u, WTF::countLeadingZerosSizet(1u << 30)); 1562 EXPECT_EQ(1u, countLeadingZerosSizet(1u << 30));
1563 EXPECT_EQ(0u, WTF::countLeadingZerosSizet(1u << 31)); 1563 EXPECT_EQ(0u, countLeadingZerosSizet(1u << 31));
1564 #endif 1564 #endif
1565 } 1565 }
1566 1566
1567 } // namespace 1567 } // namespace WTF
1568 1568
1569 #endif // !defined(MEMORY_TOOL_REPLACES_ALLOCATOR) 1569 #endif // !defined(MEMORY_TOOL_REPLACES_ALLOCATOR)
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698