Index: Source/wtf/PartitionAlloc.cpp |
diff --git a/Source/wtf/PartitionAlloc.cpp b/Source/wtf/PartitionAlloc.cpp |
index 50987147696f2ecfd8977d2b70b4fa33d0e54cf7..d5a56d14a47ce3459003614814d8d37d4e64fb09 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(64BIT) |
hiroshige
2014/11/13 06:26:31
Use CPU(64BIT) instead of CPU(32BIT), beause
https
|
+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. |
+ reinterpret_cast<void(*)()>(0x9b)(); |
+#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(64BIT) |
+ // 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; |
} |