| Index: Source/wtf/PartitionAlloc.cpp
|
| diff --git a/Source/wtf/PartitionAlloc.cpp b/Source/wtf/PartitionAlloc.cpp
|
| index a63a684c51980189aed9ab281b326c9f54d06ac4..15c8286edef49b243c0d9d5658b9c32767d577ba 100644
|
| --- a/Source/wtf/PartitionAlloc.cpp
|
| +++ b/Source/wtf/PartitionAlloc.cpp
|
| @@ -112,6 +112,7 @@ static void parititonAllocBaseInit(PartitionRootBase* root)
|
| spinLockUnlock(&PartitionRootBase::gInitializedLock);
|
|
|
| root->initialized = true;
|
| + root->totalSizeOfCommittedPages = 0;
|
| root->totalSizeOfSuperPages = 0;
|
| root->nextSuperPage = 0;
|
| root->nextPartitionPage = 0;
|
| @@ -308,12 +309,26 @@ static NEVER_INLINE void partitionFull()
|
| IMMEDIATE_CRASH();
|
| }
|
|
|
| +static ALWAYS_INLINE void partitionDecommitSystemPages(PartitionRootBase* root, void* addr, size_t len)
|
| +{
|
| + decommitSystemPages(addr, len);
|
| + ASSERT(root->totalSizeOfCommittedPages > len);
|
| + root->totalSizeOfCommittedPages -= len;
|
| +}
|
| +
|
| +static ALWAYS_INLINE void partitionRecommitSystemPages(PartitionRootBase* root, void* addr, size_t len)
|
| +{
|
| + recommitSystemPages(addr, len);
|
| + root->totalSizeOfCommittedPages += len;
|
| +}
|
| +
|
| static ALWAYS_INLINE void* partitionAllocPartitionPages(PartitionRootBase* root, int flags, size_t numPartitionPages)
|
| {
|
| ASSERT(!(reinterpret_cast<uintptr_t>(root->nextPartitionPage) % kPartitionPageSize));
|
| ASSERT(!(reinterpret_cast<uintptr_t>(root->nextPartitionPageEnd) % kPartitionPageSize));
|
| RELEASE_ASSERT(numPartitionPages <= kNumPartitionPagesPerSuperPage);
|
| size_t totalSize = kPartitionPageSize * numPartitionPages;
|
| + root->totalSizeOfCommittedPages += totalSize;
|
| size_t numPartitionPagesLeft = (root->nextPartitionPageEnd - root->nextPartitionPage) >> kPartitionPageShift;
|
| if (LIKELY(numPartitionPagesLeft >= numPartitionPages)) {
|
| // In this case, we can still hand out pages from the current super page
|
| @@ -382,11 +397,11 @@ static ALWAYS_INLINE void* partitionAllocPartitionPages(PartitionRootBase* root,
|
| return ret;
|
| }
|
|
|
| -static ALWAYS_INLINE void partitionUnusePage(PartitionPage* page)
|
| +static ALWAYS_INLINE void partitionUnusePage(PartitionRootBase* root, PartitionPage* page)
|
| {
|
| ASSERT(page->bucket->numSystemPagesPerSlotSpan);
|
| void* addr = partitionPageToPointer(page);
|
| - decommitSystemPages(addr, page->bucket->numSystemPagesPerSlotSpan * kSystemPageSize);
|
| + partitionDecommitSystemPages(root, addr, page->bucket->numSystemPagesPerSlotSpan * kSystemPageSize);
|
| }
|
|
|
| static ALWAYS_INLINE size_t partitionBucketSlots(const PartitionBucket* bucket)
|
| @@ -675,7 +690,7 @@ void* partitionAllocSlowPath(PartitionRootBase* root, int flags, size_t size, Pa
|
| ASSERT(newPage->freeCacheIndex == -1);
|
| bucket->freePagesHead = newPage->nextPage;
|
| void* addr = partitionPageToPointer(newPage);
|
| - recommitSystemPages(addr, newPage->bucket->numSystemPagesPerSlotSpan * kSystemPageSize);
|
| + partitionRecommitSystemPages(root, addr, newPage->bucket->numSystemPagesPerSlotSpan * kSystemPageSize);
|
| } else {
|
| // Third. If we get here, we need a brand new page.
|
| size_t numPartitionPages = partitionBucketPartitionPages(bucket);
|
| @@ -693,11 +708,11 @@ void* partitionAllocSlowPath(PartitionRootBase* root, int flags, size_t size, Pa
|
| return partitionPageAllocAndFillFreelist(newPage);
|
| }
|
|
|
| -static ALWAYS_INLINE void partitionFreePage(PartitionPage* page)
|
| +static ALWAYS_INLINE void partitionFreePage(PartitionRootBase* root, PartitionPage* page)
|
| {
|
| ASSERT(page->freelistHead);
|
| ASSERT(!page->numAllocatedSlots);
|
| - partitionUnusePage(page);
|
| + partitionUnusePage(root, page);
|
| // We actually leave the freed page in the active list. We'll sweep it on
|
| // to the free page list when we next walk the active page list. Pulling
|
| // this trick enables us to use a singly-linked page list for all cases,
|
| @@ -710,6 +725,7 @@ static ALWAYS_INLINE void partitionFreePage(PartitionPage* page)
|
| static ALWAYS_INLINE void partitionRegisterEmptyPage(PartitionPage* page)
|
| {
|
| PartitionRootBase* root = partitionPageToRoot(page);
|
| +
|
| // If the page is already registered as empty, give it another life.
|
| if (page->freeCacheIndex != -1) {
|
| ASSERT(page->freeCacheIndex >= 0);
|
| @@ -729,7 +745,7 @@ static ALWAYS_INLINE void partitionRegisterEmptyPage(PartitionPage* page)
|
| ASSERT(pageToFree == root->globalEmptyPageRing[pageToFree->freeCacheIndex]);
|
| if (!pageToFree->numAllocatedSlots && pageToFree->freelistHead) {
|
| // The page is still empty, and not freed, so _really_ free it.
|
| - partitionFreePage(pageToFree);
|
| + partitionFreePage(root, pageToFree);
|
| }
|
| pageToFree->freeCacheIndex = -1;
|
| }
|
| @@ -757,7 +773,7 @@ void partitionFreeSlowPath(PartitionPage* page)
|
| partitionDirectUnmap(page);
|
| return;
|
| }
|
| - // If it's the current page, attempt to change it. We'd prefer to leave
|
| + // If it's the current active page, attempt to change it. We'd prefer to leave
|
| // the page empty as a gentle force towards defragmentation.
|
| if (LIKELY(page == bucket->activePagesHead) && page->nextPage) {
|
| if (partitionSetNewActivePage(page->nextPage)) {
|
| @@ -827,14 +843,14 @@ bool partitionReallocDirectMappedInPlace(PartitionRootGeneric* root, PartitionPa
|
|
|
| // Shrink by decommitting unneeded pages and making them inaccessible.
|
| size_t decommitSize = currentSize - newSize;
|
| - decommitSystemPages(charPtr + newSize, decommitSize);
|
| + partitionDecommitSystemPages(root, charPtr + newSize, decommitSize);
|
| setSystemPagesInaccessible(charPtr + newSize, decommitSize);
|
| } else if (newSize <= partitionPageToDirectMapExtent(page)->mapSize) {
|
| // Grow within the actually allocated memory. Just need to make the
|
| // pages accessible again.
|
| size_t recommitSize = newSize - currentSize;
|
| setSystemPagesAccessible(charPtr + currentSize, recommitSize);
|
| - recommitSystemPages(charPtr + currentSize, recommitSize);
|
| + partitionRecommitSystemPages(root, charPtr + currentSize, recommitSize);
|
|
|
| #ifndef NDEBUG
|
| memset(charPtr + currentSize, kUninitializedByte, recommitSize);
|
|
|