Chromium Code Reviews| Index: Source/wtf/PartitionAlloc.cpp |
| diff --git a/Source/wtf/PartitionAlloc.cpp b/Source/wtf/PartitionAlloc.cpp |
| index 50987147696f2ecfd8977d2b70b4fa33d0e54cf7..4cd439ad03ca1e20691b7eb559d1ecbe8272ff2b 100644 |
| --- a/Source/wtf/PartitionAlloc.cpp |
| +++ b/Source/wtf/PartitionAlloc.cpp |
| @@ -114,6 +114,7 @@ static void parititonAllocBaseInit(PartitionRootBase* root) |
| root->initialized = true; |
| root->totalSizeOfCommittedPages = 0; |
| root->totalSizeOfSuperPages = 0; |
| + root->totalSizeOfDirectMappedPages = 0; |
| root->nextSuperPage = 0; |
| root->nextPartitionPage = 0; |
| root->nextPartitionPageEnd = 0; |
| @@ -296,15 +297,41 @@ bool partitionAllocGenericShutdown(PartitionRootGeneric* root) |
| return noLeaks; |
| } |
| -static NEVER_INLINE void partitionOutOfMemory() |
| +#if CPU(32BIT) |
| +static NEVER_INLINE void partitionOutOfMemoryWithLotsOfUncommitedPages() |
| { |
| +#if OS(WIN) |
| + // Crash at a special address (0x9b) |
| + // to be easily distinguished on crash reports. |
| + // This is because crash stack traces are inaccurate on Windows and |
| + // partitionOutOfMemoryWithLotsOfUncommitedPages might be not included |
| + // in the stack traces. |
| + ((void(*)())0x9b)(); |
|
Chris Evans
2014/11/12 23:01:30
Nit: should probably use reinterpret_cast to compl
hiroshige
2014/11/13 06:26:31
Done.
|
| +#endif |
| + |
| + // On non-Windows environment, IMMEDIATE_CRASH is sufficient |
| + // because partitionOutOfMemoryWithLotsOfUncommitedPages will appear |
| + // in crash stack traces. |
| + IMMEDIATE_CRASH(); |
| +} |
| +#endif |
| + |
| +static NEVER_INLINE void partitionOutOfMemory(const PartitionRootBase* root) |
| +{ |
| +#if CPU(32BIT) |
| + // Check whether this OOM is due to a lot of super pages that are allocated |
| + // but not committed, probably due to http://crbug.com/421387. |
| + if (root->totalSizeOfSuperPages + root->totalSizeOfDirectMappedPages - root->totalSizeOfCommittedPages > kReasonableSizeOfUnusedPages) { |
| + partitionOutOfMemoryWithLotsOfUncommitedPages(); |
| + } |
| +#endif |
| IMMEDIATE_CRASH(); |
| } |
| static ALWAYS_INLINE void partitionDecommitSystemPages(PartitionRootBase* root, void* addr, size_t len) |
| { |
| decommitSystemPages(addr, len); |
| - ASSERT(root->totalSizeOfCommittedPages > len); |
| + ASSERT(root->totalSizeOfCommittedPages >= len); |
| root->totalSizeOfCommittedPages -= len; |
| } |
| @@ -312,6 +339,7 @@ static ALWAYS_INLINE void partitionRecommitSystemPages(PartitionRootBase* root, |
| { |
| recommitSystemPages(addr, len); |
| root->totalSizeOfCommittedPages += len; |
| + ASSERT(root->totalSizeOfCommittedPages <= root->totalSizeOfSuperPages + root->totalSizeOfDirectMappedPages); |
| } |
| static ALWAYS_INLINE void* partitionAllocPartitionPages(PartitionRootBase* root, int flags, uint16_t numPartitionPages) |
| @@ -327,6 +355,7 @@ static ALWAYS_INLINE void* partitionAllocPartitionPages(PartitionRootBase* root, |
| char* ret = root->nextPartitionPage; |
| root->nextPartitionPage += totalSize; |
| root->totalSizeOfCommittedPages += totalSize; |
| + ASSERT(root->totalSizeOfCommittedPages <= root->totalSizeOfSuperPages + root->totalSizeOfDirectMappedPages); |
| return ret; |
| } |
| @@ -338,6 +367,7 @@ static ALWAYS_INLINE void* partitionAllocPartitionPages(PartitionRootBase* root, |
| root->totalSizeOfSuperPages += kSuperPageSize; |
| root->totalSizeOfCommittedPages += totalSize; |
| + ASSERT(root->totalSizeOfCommittedPages <= root->totalSizeOfSuperPages + root->totalSizeOfDirectMappedPages); |
| root->nextSuperPage = superPage + kSuperPageSize; |
| char* ret = superPage + kPartitionPageSize; |
| @@ -568,7 +598,10 @@ static ALWAYS_INLINE void* partitionDirectMap(PartitionRootBase* root, int flags |
| mapSize += kPageAllocationGranularityOffsetMask; |
| mapSize &= kPageAllocationGranularityBaseMask; |
| - root->totalSizeOfCommittedPages += size + kSystemPageSize; |
| + size_t committedPageSize = size + kSystemPageSize; |
| + root->totalSizeOfCommittedPages += committedPageSize; |
| + root->totalSizeOfDirectMappedPages += committedPageSize; |
| + ASSERT(root->totalSizeOfCommittedPages <= root->totalSizeOfSuperPages + root->totalSizeOfDirectMappedPages); |
| // TODO: we may want to let the operating system place these allocations |
| // where it pleases. On 32-bit, this might limit address space |
| @@ -624,7 +657,11 @@ static ALWAYS_INLINE void partitionDirectUnmap(PartitionPage* page) |
| unmapSize += kPartitionPageSize + kSystemPageSize; |
| PartitionRootBase* root = partitionPageToRoot(page); |
| - root->totalSizeOfCommittedPages -= page->bucket->slotSize + kSystemPageSize; |
| + size_t uncommittedPageSize = page->bucket->slotSize + kSystemPageSize; |
| + ASSERT(root->totalSizeOfCommittedPages >= uncommittedPageSize); |
| + root->totalSizeOfCommittedPages -= uncommittedPageSize; |
| + ASSERT(root->totalSizeOfDirectMappedPages >= uncommittedPageSize); |
| + root->totalSizeOfDirectMappedPages -= uncommittedPageSize; |
| ASSERT(!(unmapSize & kPageAllocationGranularityOffsetMask)); |
| @@ -709,7 +746,7 @@ partitionAllocSlowPathFailed: |
| bucket->activePagesHead = &PartitionRootGeneric::gSeedPage; |
| return nullptr; |
| } |
| - partitionOutOfMemory(); |
| + partitionOutOfMemory(root); |
| return nullptr; |
| } |