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

Unified Diff: Source/wtf/PartitionAllocTest.cpp

Issue 133863006: PartitionAlloc: wait just a little while before actually freeing empty pages. (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Created 6 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« Source/wtf/PartitionAlloc.cpp ('K') | « Source/wtf/PartitionAlloc.cpp ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: Source/wtf/PartitionAllocTest.cpp
diff --git a/Source/wtf/PartitionAllocTest.cpp b/Source/wtf/PartitionAllocTest.cpp
index a9b29c7f1cbd617a776c5cd706507f0191db738b..07da35038811a8871fe0ce23844a30400ec89ca6 100644
--- a/Source/wtf/PartitionAllocTest.cpp
+++ b/Source/wtf/PartitionAllocTest.cpp
@@ -119,6 +119,22 @@ static void FreeFullPage(WTF::PartitionPage* page)
}
}
+static void CycleFreeCache(size_t size)
+{
+ size_t realSize = size + kExtraAllocSize;
+ size_t bucketIdx = realSize >> WTF::kBucketShift;
+ WTF::PartitionBucket* bucket = &allocator.root()->buckets()[bucketIdx];
+ ASSERT(!bucket->activePagesHead->numAllocatedSlots);
+
+ for (size_t i = 0; i < WTF::kMaxFreeableSpans; ++i) {
+ void* ptr = partitionAlloc(allocator.root(), size);
+ EXPECT_EQ(1, bucket->activePagesHead->numAllocatedSlots);
+ partitionFree(ptr);
+ EXPECT_EQ(0, bucket->activePagesHead->numAllocatedSlots);
+ EXPECT_TRUE(bucket->activePagesHead->freeCacheIndex);
+ }
+}
+
// Check that the most basic of allocate / free pairs work.
TEST(WTF_PartitionAlloc, Basic)
{
@@ -228,7 +244,7 @@ TEST(WTF_PartitionAlloc, MultiPages)
EXPECT_EQ(0, page->numAllocatedSlots);
EXPECT_EQ(0, page2->numAllocatedSlots);
EXPECT_EQ(0, page2->numUnprovisionedSlots);
- EXPECT_EQ(0, page2->freelistHead);
+ EXPECT_TRUE(page2->freeCacheIndex);
TestShutdown();
}
@@ -313,7 +329,7 @@ TEST(WTF_PartitionAlloc, FreePageListPageTransitions)
for (i = 0; i < numToFillFreeListPage; ++i)
FreeFullPage(pages[i]);
EXPECT_EQ(0, bucket->activePagesHead->numAllocatedSlots);
- EXPECT_EQ(0, bucket->activePagesHead->nextPage->freelistHead);
+ EXPECT_TRUE(bucket->activePagesHead->nextPage->freeCacheIndex);
EXPECT_EQ(0, bucket->activePagesHead->nextPage->numAllocatedSlots);
EXPECT_EQ(0, bucket->activePagesHead->nextPage->numUnprovisionedSlots);
@@ -343,7 +359,7 @@ TEST(WTF_PartitionAlloc, FreePageListPageTransitions)
for (i = 0; i < numToFillFreeListPage; ++i)
FreeFullPage(pages[i]);
EXPECT_EQ(0, bucket->activePagesHead->numAllocatedSlots);
- EXPECT_EQ(0, bucket->activePagesHead->nextPage->freelistHead);
+ EXPECT_TRUE(bucket->activePagesHead->nextPage->freeCacheIndex);
EXPECT_EQ(0, bucket->activePagesHead->nextPage->numAllocatedSlots);
EXPECT_EQ(0, bucket->activePagesHead->nextPage->numUnprovisionedSlots);
@@ -491,11 +507,9 @@ TEST(WTF_PartitionAlloc, GenericAllocSizes)
void* ptr2 = partitionAllocGeneric(genericAllocator.root(), size);
EXPECT_TRUE(ptr2);
partitionFreeGeneric(genericAllocator.root(), ptr);
- // Should have freelisted at this point.
+ // Should be freeable at this point.
WTF::PartitionPage* page = WTF::partitionPointerToPage(WTF::partitionCookieFreePointerAdjust(ptr));
-#if 0 // Temporarily disabled, see crbug.com/332282
- EXPECT_TRUE(page->bucket->freePagesHead);
-#endif
+ EXPECT_TRUE(page->freeCacheIndex);
partitionFreeGeneric(genericAllocator.root(), ptr2);
size = WTF::kGenericMaxBucketed - kExtraAllocSize;
@@ -516,14 +530,14 @@ TEST(WTF_PartitionAlloc, GenericAllocSizes)
partitionFreeGeneric(genericAllocator.root(), ptr);
partitionFreeGeneric(genericAllocator.root(), ptr3);
partitionFreeGeneric(genericAllocator.root(), ptr2);
- // Should have been freed at this point.
- EXPECT_FALSE(page->freelistHead);
+ // Should be freeable at this point.
+ EXPECT_TRUE(page->freeCacheIndex);
EXPECT_EQ(0, page->numAllocatedSlots);
EXPECT_EQ(0, page->numUnprovisionedSlots);
void* newPtr = partitionAllocGeneric(genericAllocator.root(), size);
EXPECT_EQ(ptr3, newPtr);
newPtr = partitionAllocGeneric(genericAllocator.root(), size);
- EXPECT_EQ(ptr, newPtr);
+ EXPECT_EQ(ptr2, newPtr);
#if OS(LINUX) && defined(NDEBUG)
// On Linux, we have a guarantee that freelisting a page should cause its
// contents to be nulled out. We check for null here to detect an bug we
@@ -599,8 +613,8 @@ TEST(WTF_PartitionAlloc, PartialPageFreelists)
partitionFree(ptr4);
partitionFree(ptr5);
partitionFree(ptr6);
- EXPECT_TRUE(bucket->freePagesHead);
- EXPECT_EQ(page, bucket->freePagesHead);
+ EXPECT_TRUE(page->freeCacheIndex);
+ EXPECT_TRUE(page2->freeCacheIndex);
EXPECT_TRUE(page2->freelistHead);
EXPECT_EQ(0, page2->numAllocatedSlots);
@@ -803,6 +817,50 @@ TEST(WTF_PartitionAlloc, MappingCollision)
TestShutdown();
}
+// Tests that pages in the free page cache do get freed as appropriate.
+TEST(WTF_PartitionAlloc, FreeCache)
+{
+ TestSetup();
+
+ size_t bigSize = allocator.root()->maxAllocation - kExtraAllocSize;
+ size_t bucketIdx = (bigSize + kExtraAllocSize) >> WTF::kBucketShift;
+ WTF::PartitionBucket* bucket = &allocator.root()->buckets()[bucketIdx];
+
+ void* ptr = partitionAlloc(allocator.root(), bigSize);
+ EXPECT_TRUE(ptr);
+ WTF::PartitionPage* page = WTF::partitionPointerToPage(WTF::partitionCookieFreePointerAdjust(ptr));
+ EXPECT_EQ(0, bucket->freePagesHead);
+ EXPECT_EQ(1, page->numAllocatedSlots);
+ partitionFree(ptr);
+ EXPECT_EQ(0, page->numAllocatedSlots);
+ EXPECT_TRUE(page->freeCacheIndex);
+ EXPECT_TRUE(page->freelistHead);
+
+ CycleFreeCache(kTestAllocSize);
+
+ // Flushing the cache should have really freed the unused page.
+ EXPECT_FALSE(page->freelistHead);
+ EXPECT_FALSE(page->freeCacheIndex);
+ EXPECT_EQ(0, page->numAllocatedSlots);
+
+ // Check that an allocation works ok whilst in this state (a free'd page
+ // as the active pages head).
+ ptr = partitionAlloc(allocator.root(), bigSize);
+ EXPECT_FALSE(bucket->freePagesHead);
+ partitionFree(ptr);
+
+ // Also check that a page that is bouncing immediately between empty and
+ // used does not get freed.
+ for (size_t i = 0; i < WTF::kMaxFreeableSpans * 2; ++i) {
+ ptr = partitionAlloc(allocator.root(), bigSize);
+ EXPECT_TRUE(page->freelistHead);
+ partitionFree(ptr);
+ EXPECT_TRUE(page->freelistHead);
+ }
+
+ TestShutdown();
+}
+
// Make sure that malloc(-1) dies.
// In the past, we had an integer overflow that would alias malloc(-1) to
// malloc(0), which is not good.
« Source/wtf/PartitionAlloc.cpp ('K') | « Source/wtf/PartitionAlloc.cpp ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698