Upstream version 5.34.104.0
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / Source / wtf / PartitionAllocTest.cpp
index 6edd669..5b5ea1d 100644 (file)
@@ -54,13 +54,13 @@ static const size_t kTestMaxAllocation = 4096;
 static SizeSpecificPartitionAllocator<kTestMaxAllocation> allocator;
 static PartitionAllocatorGeneric genericAllocator;
 
-static const size_t kTestAllocSize = sizeof(void*);
+static const size_t kTestAllocSize = 16;
 #ifdef NDEBUG
 static const size_t kPointerOffset = 0;
 static const size_t kExtraAllocSize = 0;
 #else
-static const size_t kPointerOffset = sizeof(uintptr_t);
-static const size_t kExtraAllocSize = sizeof(uintptr_t) * 2;
+static const size_t kPointerOffset = WTF::kCookieSize;
+static const size_t kExtraAllocSize = WTF::kCookieSize * 2;
 #endif
 static const size_t kRealAllocSize = kTestAllocSize + kExtraAllocSize;
 static const size_t kTestBucketIndex = kRealAllocSize >> WTF::kBucketShift;
@@ -135,6 +135,19 @@ static void CycleFreeCache(size_t size)
     }
 }
 
+static void CycleGenericFreeCache(size_t size)
+{
+    for (size_t i = 0; i < WTF::kMaxFreeableSpans; ++i) {
+        void* ptr = partitionAllocGeneric(genericAllocator.root(), size);
+        WTF::PartitionPage* page = WTF::partitionPointerToPage(WTF::partitionCookieFreePointerAdjust(ptr));
+        WTF::PartitionBucket* bucket = page->bucket;
+        EXPECT_EQ(1, bucket->activePagesHead->numAllocatedSlots);
+        partitionFreeGeneric(genericAllocator.root(), ptr);
+        EXPECT_EQ(0, bucket->activePagesHead->numAllocatedSlots);
+        EXPECT_NE(-1, bucket->activePagesHead->freeCacheIndex);
+    }
+}
+
 // Check that the most basic of allocate / free pairs work.
 TEST(WTF_PartitionAlloc, Basic)
 {
@@ -689,7 +702,7 @@ TEST(WTF_PartitionAlloc, PartialPageFreelists)
     EXPECT_TRUE(page->freelistHead);
     EXPECT_EQ(0, page->numAllocatedSlots);
 
-    size_t verySmallSize = (WTF::kAllocationGranularity * 2) - kExtraAllocSize;
+    size_t verySmallSize = 32 - kExtraAllocSize;
     bucketIdx = (verySmallSize + kExtraAllocSize) >> WTF::kBucketShift;
     bucket = &allocator.root()->buckets()[bucketIdx];
     EXPECT_EQ(0, bucket->freePagesHead);
@@ -898,6 +911,68 @@ TEST(WTF_PartitionAlloc, FreeCache)
     TestShutdown();
 }
 
+// Tests for a bug we had with losing references to free pages.
+TEST(WTF_PartitionAlloc, LostFreePagesBug)
+{
+    TestSetup();
+
+    size_t size = WTF::kPartitionPageSize - kExtraAllocSize;
+
+    void* ptr = partitionAllocGeneric(genericAllocator.root(), size);
+    EXPECT_TRUE(ptr);
+    void* ptr2 = partitionAllocGeneric(genericAllocator.root(), size);
+    EXPECT_TRUE(ptr2);
+
+    WTF::PartitionPage* page = WTF::partitionPointerToPage(WTF::partitionCookieFreePointerAdjust(ptr));
+    WTF::PartitionPage* page2 = WTF::partitionPointerToPage(WTF::partitionCookieFreePointerAdjust(ptr2));
+    WTF::PartitionBucket* bucket = page->bucket;
+
+    EXPECT_EQ(0, bucket->freePagesHead);
+    EXPECT_EQ(-1, page->numAllocatedSlots);
+    EXPECT_EQ(1, page2->numAllocatedSlots);
+
+    partitionFreeGeneric(genericAllocator.root(), ptr);
+    partitionFreeGeneric(genericAllocator.root(), ptr2);
+
+    EXPECT_EQ(0, bucket->freePagesHead);
+    EXPECT_EQ(0, page->numAllocatedSlots);
+    EXPECT_EQ(0, page2->numAllocatedSlots);
+    EXPECT_TRUE(page->freelistHead);
+    EXPECT_TRUE(page2->freelistHead);
+
+    CycleGenericFreeCache(kTestAllocSize);
+
+    EXPECT_FALSE(page->freelistHead);
+    EXPECT_FALSE(page2->freelistHead);
+
+    EXPECT_FALSE(bucket->freePagesHead);
+    EXPECT_TRUE(bucket->activePagesHead);
+    EXPECT_TRUE(bucket->activePagesHead->nextPage);
+
+    // At this moment, we have two freed pages, on the freelist.
+
+    ptr = partitionAllocGeneric(genericAllocator.root(), size);
+    EXPECT_TRUE(ptr);
+    partitionFreeGeneric(genericAllocator.root(), ptr);
+
+    EXPECT_TRUE(bucket->activePagesHead);
+    EXPECT_TRUE(bucket->freePagesHead);
+
+    CycleGenericFreeCache(kTestAllocSize);
+
+    // We're now set up to trigger the bug by scanning over the active pages
+    // list, where the current active page is freed, and there exists at least
+    // one freed page in the free pages list.
+    ptr = partitionAllocGeneric(genericAllocator.root(), size);
+    EXPECT_TRUE(ptr);
+    partitionFreeGeneric(genericAllocator.root(), ptr);
+
+    EXPECT_TRUE(bucket->activePagesHead);
+    EXPECT_TRUE(bucket->freePagesHead);
+
+    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.