| Index: Source/wtf/PartitionAlloc.cpp | 
| diff --git a/Source/wtf/PartitionAlloc.cpp b/Source/wtf/PartitionAlloc.cpp | 
| index e1376d31d15f73e398eda6597064477621cbaf70..cb5dc0a85a4f984a9e5ae3df27e4fd4afe4dcf53 100644 | 
| --- a/Source/wtf/PartitionAlloc.cpp | 
| +++ b/Source/wtf/PartitionAlloc.cpp | 
| @@ -31,7 +31,6 @@ | 
| #include "config.h" | 
| #include "wtf/PartitionAlloc.h" | 
|  | 
| -#include "wtf/PageAllocator.h" | 
| #include <string.h> | 
|  | 
| #ifndef NDEBUG | 
| @@ -285,16 +284,16 @@ static ALWAYS_INLINE void partitionUnlinkPage(PartitionPageHeader* page) | 
| page->prev->next = page->next; | 
| } | 
|  | 
| -static ALWAYS_INLINE void partitionLinkPage(PartitionPageHeader* newPage, PartitionPageHeader* prevPage) | 
| +static ALWAYS_INLINE void partitionLinkPageBefore(PartitionPageHeader* newPage, PartitionPageHeader* nextPage) | 
| { | 
| -    ASSERT(prevPage->prev->next == prevPage); | 
| -    ASSERT(prevPage->next->prev == prevPage); | 
| +    ASSERT(nextPage->prev->next == nextPage); | 
| +    ASSERT(nextPage->next->prev == nextPage); | 
|  | 
| -    newPage->prev = prevPage; | 
| -    newPage->next = prevPage->next; | 
| +    newPage->next = nextPage; | 
| +    newPage->prev = nextPage->prev; | 
|  | 
| -    prevPage->next->prev = newPage; | 
| -    prevPage->next = newPage; | 
| +    nextPage->prev->next = newPage; | 
| +    nextPage->prev = newPage; | 
| } | 
|  | 
| void* partitionAllocSlowPath(PartitionBucket* bucket) | 
| @@ -304,8 +303,8 @@ void* partitionAllocSlowPath(PartitionBucket* bucket) | 
| PartitionPageHeader* next = page->next; | 
| ASSERT(page == &bucket->root->seedPage || (page->bucket == bucket && next->bucket == bucket)); | 
|  | 
| -    // First, see if the partition page still has capacity and if so, fill out | 
| -    // the freelist a little more. | 
| +    // First, see if the current partition page still has capacity and if so, | 
| +    // fill out the freelist a little more. | 
| if (LIKELY(page->numUnprovisionedSlots)) | 
| return partitionPageAllocAndFillFreelist(page); | 
|  | 
| @@ -322,6 +321,10 @@ void* partitionAllocSlowPath(PartitionBucket* bucket) | 
| next->numAllocatedSlots++; | 
| return ret; | 
| } | 
| +        if (LIKELY(next->numUnprovisionedSlots)) { | 
| +            bucket->currPage = next; | 
| +            return partitionPageAllocAndFillFreelist(next); | 
| +        } | 
| // Pull this page out of the non-full page list, since it has no free | 
| // slots. | 
| // This tags the page as full so that free'ing can tell, and move | 
| @@ -334,7 +337,18 @@ void* partitionAllocSlowPath(PartitionBucket* bucket) | 
| next = next->next; | 
| } | 
|  | 
| -    // Second, look in our list of freed but reserved pages. | 
| +    // After we've considered and rejected every partition page in the list, | 
| +    // we should by definition have a single self-linked page left. We will | 
| +    // replace this single page with the new page we choose. | 
| +    ASSERT(page == page->next); | 
| +    ASSERT(page == page->prev); | 
| +    ASSERT(page == &bucket->root->seedPage || page->numAllocatedSlots == partitionBucketSlots(bucket)); | 
| +    if (LIKELY(page != &bucket->root->seedPage)) { | 
| +        page->numAllocatedSlots = -page->numAllocatedSlots; | 
| +        ++bucket->numFullPages; | 
| +    } | 
| + | 
| +    // Third, look in our list of freed but reserved pages. | 
| PartitionPageHeader* newPage; | 
| PartitionFreepagelistEntry* pagelist = bucket->freePages; | 
| if (LIKELY(pagelist != 0)) { | 
| @@ -342,21 +356,13 @@ void* partitionAllocSlowPath(PartitionBucket* bucket) | 
| bucket->freePages = pagelist->next; | 
| partitionFree(pagelist); | 
| ASSERT(page != &bucket->root->seedPage); | 
| -        partitionLinkPage(newPage, page); | 
| } else { | 
| -        // Third. If we get here, we need a brand new page. | 
| +        // Fourth. If we get here, we need a brand new page. | 
| newPage = partitionAllocPage(bucket->root); | 
| -        if (UNLIKELY(page == &bucket->root->seedPage)) { | 
| -            // If this is the first page allocation to this bucket, then | 
| -            // fully replace the seed page. This avoids pointlessly iterating | 
| -            // over it. | 
| -            newPage->prev = newPage; | 
| -            newPage->next = newPage; | 
| -        } else { | 
| -            partitionLinkPage(newPage, page); | 
| -        } | 
| } | 
|  | 
| +    newPage->prev = newPage; | 
| +    newPage->next = newPage; | 
| bucket->currPage = newPage; | 
| partitionPageReset(newPage, bucket); | 
| return partitionPageAllocAndFillFreelist(newPage); | 
| @@ -367,10 +373,14 @@ void partitionFreeSlowPath(PartitionPageHeader* page) | 
| PartitionBucket* bucket = page->bucket; | 
| if (LIKELY(page->numAllocatedSlots == 0)) { | 
| // Page became fully unused. | 
| -        // If it's the current page, leave it be so that we don't bounce a page | 
| -        // onto the free page list and immediately back out again. | 
| -        if (LIKELY(page == bucket->currPage)) | 
| -            return; | 
| +        // If it's the current page, change it! | 
| +        if (LIKELY(page == bucket->currPage)) { | 
| +            if (UNLIKELY(page->next == page)) { | 
| +                // For now, we do not free the last partition page in a bucket. | 
| +                return; | 
| +            } | 
| +            bucket->currPage = page->next; | 
| +        } | 
|  | 
| partitionUnlinkPage(page); | 
| partitionUnusePage(page); | 
| @@ -380,8 +390,11 @@ void partitionFreeSlowPath(PartitionPageHeader* page) | 
| bucket->freePages = entry; | 
| } else { | 
| // Fully used page became partially used. It must be put back on the | 
| -        // non-full page list. | 
| -        partitionLinkPage(page, bucket->currPage); | 
| +        // non-full page list. Also make it the current page to increase the | 
| +        // chances of it being filled up again. The old current page will be | 
| +        // the next page. | 
| +        partitionLinkPageBefore(page, bucket->currPage); | 
| +        bucket->currPage = page; | 
| page->numAllocatedSlots = -page->numAllocatedSlots - 2; | 
| ASSERT(page->numAllocatedSlots == partitionBucketSlots(bucket) - 1); | 
| --bucket->numFullPages; | 
|  |