Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(334)

Side by Side Diff: Source/wtf/PartitionAlloc.cpp

Issue 1315113006: Add partitionsOutOfMemoryUsingXXX to know Blink memory usage from OOM crash reports (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Created 5 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2013 Google Inc. All rights reserved. 2 * Copyright (C) 2013 Google Inc. All rights reserved.
3 * 3 *
4 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are 5 * modification, are permitted provided that the following conditions are
6 * met: 6 * met:
7 * 7 *
8 * * Redistributions of source code must retain the above copyright 8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer. 9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above 10 * * Redistributions in binary form must reproduce the above
(...skipping 13 matching lines...) Expand all
24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */ 29 */
30 30
31 #include "config.h" 31 #include "config.h"
32 #include "wtf/PartitionAlloc.h" 32 #include "wtf/PartitionAlloc.h"
33 33
34 #include "wtf/Alias.h"
35 #include "wtf/Partitions.h"
36
34 #include <string.h> 37 #include <string.h>
35 38
36 #ifndef NDEBUG 39 #ifndef NDEBUG
37 #include <stdio.h> 40 #include <stdio.h>
38 #endif 41 #endif
39 42
40 // Two partition pages are used as guard / metadata page so make sure the super 43 // Two partition pages are used as guard / metadata page so make sure the super
41 // page size is bigger. 44 // page size is bigger.
42 static_assert(WTF::kPartitionPageSize * 4 <= WTF::kSuperPageSize, "ok super page size"); 45 static_assert(WTF::kPartitionPageSize * 4 <= WTF::kSuperPageSize, "ok super page size");
43 static_assert(!(WTF::kSuperPageSize % WTF::kPartitionPageSize), "ok super page m ultiple"); 46 static_assert(!(WTF::kSuperPageSize % WTF::kPartitionPageSize), "ok super page m ultiple");
44 // Four system pages gives us room to hack out a still-guard-paged piece 47 // Four system pages gives us room to hack out a still-guard-paged piece
45 // of metadata in the middle of a guard partition page. 48 // of metadata in the middle of a guard partition page.
46 static_assert(WTF::kSystemPageSize * 4 <= WTF::kPartitionPageSize, "ok partition page size"); 49 static_assert(WTF::kSystemPageSize * 4 <= WTF::kPartitionPageSize, "ok partition page size");
47 static_assert(!(WTF::kPartitionPageSize % WTF::kSystemPageSize), "ok partition p age multiple"); 50 static_assert(!(WTF::kPartitionPageSize % WTF::kSystemPageSize), "ok partition p age multiple");
48 static_assert(sizeof(WTF::PartitionPage) <= WTF::kPageMetadataSize, "PartitionPa ge should not be too big"); 51 static_assert(sizeof(WTF::PartitionPage) <= WTF::kPageMetadataSize, "PartitionPa ge should not be too big");
49 static_assert(sizeof(WTF::PartitionBucket) <= WTF::kPageMetadataSize, "Partition Bucket should not be too big"); 52 static_assert(sizeof(WTF::PartitionBucket) <= WTF::kPageMetadataSize, "Partition Bucket should not be too big");
50 static_assert(sizeof(WTF::PartitionSuperPageExtentEntry) <= WTF::kPageMetadataSi ze, "PartitionSuperPageExtentEntry should not be too big"); 53 static_assert(sizeof(WTF::PartitionSuperPageExtentEntry) <= WTF::kPageMetadataSi ze, "PartitionSuperPageExtentEntry should not be too big");
51 static_assert(WTF::kPageMetadataSize * WTF::kNumPartitionPagesPerSuperPage <= WT F::kSystemPageSize, "page metadata fits in hole"); 54 static_assert(WTF::kPageMetadataSize * WTF::kNumPartitionPagesPerSuperPage <= WT F::kSystemPageSize, "page metadata fits in hole");
52 // Check that some of our zanier calculations worked out as expected. 55 // Check that some of our zanier calculations worked out as expected.
53 static_assert(WTF::kGenericSmallestBucket == 8, "generic smallest bucket"); 56 static_assert(WTF::kGenericSmallestBucket == 8, "generic smallest bucket");
54 static_assert(WTF::kGenericMaxBucketed == 983040, "generic max bucketed"); 57 static_assert(WTF::kGenericMaxBucketed == 983040, "generic max bucketed");
55 58
56 namespace WTF { 59 namespace WTF {
57 60
58 int PartitionRootBase::gInitializedLock = 0; 61 int PartitionRootBase::gInitializedLock = 0;
59 bool PartitionRootBase::gInitialized = false; 62 bool PartitionRootBase::gInitialized = false;
60 PartitionPage PartitionRootBase::gSeedPage; 63 PartitionPage PartitionRootBase::gSeedPage;
61 PartitionBucket PartitionRootBase::gPagedBucket; 64 PartitionBucket PartitionRootBase::gPagedBucket;
65 size_t (*PartitionRootBase::gMemoryUsageReportFunction)() = nullptr;
62 66
63 static uint16_t partitionBucketNumSystemPages(size_t size) 67 static uint16_t partitionBucketNumSystemPages(size_t size)
64 { 68 {
65 // This works out reasonably for the current bucket sizes of the generic 69 // This works out reasonably for the current bucket sizes of the generic
66 // allocator, and the current values of partition page size and constants. 70 // allocator, and the current values of partition page size and constants.
67 // Specifically, we have enough room to always pack the slots perfectly into 71 // Specifically, we have enough room to always pack the slots perfectly into
68 // some number of system pages. The only waste is the waste associated with 72 // some number of system pages. The only waste is the waste associated with
69 // unfaulted pages (i.e. wasted address space). 73 // unfaulted pages (i.e. wasted address space).
70 // TODO: we end up using a lot of system pages for very small sizes. For 74 // TODO: we end up using a lot of system pages for very small sizes. For
71 // example, we'll use 12 system pages for slot size 24. The slot size is 75 // example, we'll use 12 system pages for slot size 24. The slot size is
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
131 135
132 static void partitionBucketInitBase(PartitionBucket* bucket, PartitionRootBase* root) 136 static void partitionBucketInitBase(PartitionBucket* bucket, PartitionRootBase* root)
133 { 137 {
134 bucket->activePagesHead = &PartitionRootGeneric::gSeedPage; 138 bucket->activePagesHead = &PartitionRootGeneric::gSeedPage;
135 bucket->emptyPagesHead = 0; 139 bucket->emptyPagesHead = 0;
136 bucket->decommittedPagesHead = 0; 140 bucket->decommittedPagesHead = 0;
137 bucket->numFullPages = 0; 141 bucket->numFullPages = 0;
138 bucket->numSystemPagesPerSlotSpan = partitionBucketNumSystemPages(bucket->sl otSize); 142 bucket->numSystemPagesPerSlotSpan = partitionBucketNumSystemPages(bucket->sl otSize);
139 } 143 }
140 144
145 void partitionAllocGlobalInit(size_t (*memoryUsageReportFunc)())
146 {
147 PartitionRootBase::gMemoryUsageReportFunction = memoryUsageReportFunc;
148 }
149
141 void partitionAllocInit(PartitionRoot* root, size_t numBuckets, size_t maxAlloca tion) 150 void partitionAllocInit(PartitionRoot* root, size_t numBuckets, size_t maxAlloca tion)
142 { 151 {
143 partitionAllocBaseInit(root); 152 partitionAllocBaseInit(root);
144 153
145 root->numBuckets = numBuckets; 154 root->numBuckets = numBuckets;
146 root->maxAllocation = maxAllocation; 155 root->maxAllocation = maxAllocation;
147 size_t i; 156 size_t i;
148 for (i = 0; i < root->numBuckets; ++i) { 157 for (i = 0; i < root->numBuckets; ++i) {
149 PartitionBucket* bucket = &root->buckets()[i]; 158 PartitionBucket* bucket = &root->buckets()[i];
150 if (!i) 159 if (!i)
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after
292 return !foundLeak; 301 return !foundLeak;
293 } 302 }
294 303
295 #if !CPU(64BIT) 304 #if !CPU(64BIT)
296 static NEVER_INLINE void partitionOutOfMemoryWithLotsOfUncommitedPages() 305 static NEVER_INLINE void partitionOutOfMemoryWithLotsOfUncommitedPages()
297 { 306 {
298 IMMEDIATE_CRASH(); 307 IMMEDIATE_CRASH();
299 } 308 }
300 #endif 309 #endif
301 310
302 static NEVER_INLINE void partitionOutOfMemory(const PartitionRootBase* root) 311 static NEVER_INLINE void partitionOutOfMemoryUsing2G()
312 {
313 const void* signature = (void*)&partitionOutOfMemoryUsing2G;
314 alias(signature);
315 IMMEDIATE_CRASH();
316 }
317
318 static NEVER_INLINE void partitionOutOfMemoryUsing1G()
319 {
320 const void* signature = (void*)&partitionOutOfMemoryUsing1G;
321 alias(signature);
322 IMMEDIATE_CRASH();
323 }
324
325 static NEVER_INLINE void partitionOutOfMemoryUsing512M()
326 {
327 const void* signature = (void*)&partitionOutOfMemoryUsing512M;
328 alias(signature);
329 IMMEDIATE_CRASH();
330 }
331
332 static NEVER_INLINE void partitionOutOfMemoryUsing256M()
333 {
334 const void* signature = (void*)&partitionOutOfMemoryUsing256M;
335 alias(signature);
336 IMMEDIATE_CRASH();
337 }
338
339 static NEVER_INLINE void partitionOutOfMemoryUsing128M()
340 {
341 const void* signature = (void*)&partitionOutOfMemoryUsing128M;
342 alias(signature);
343 IMMEDIATE_CRASH();
344 }
345
346 static NEVER_INLINE void partitionOutOfMemoryUsing64M()
347 {
348 const void* signature = (void*)&partitionOutOfMemoryUsing64M;
349 alias(signature);
350 IMMEDIATE_CRASH();
351 }
352
353 static NEVER_INLINE void partitionOutOfMemoryUsing32M()
354 {
355 const void* signature = (void*)&partitionOutOfMemoryUsing32M;
356 alias(signature);
357 IMMEDIATE_CRASH();
358 }
359
360 static NEVER_INLINE void partitionOutOfMemoryUsing16M()
361 {
362 const void* signature = (void*)&partitionOutOfMemoryUsing16M;
363 alias(signature);
364 IMMEDIATE_CRASH();
365 }
366
367 static NEVER_INLINE void partitionOutOfMemoryUsingLessThan16M()
368 {
369 const void* signature = (void*)&partitionOutOfMemoryUsingLessThan16M;
370 alias(signature);
371 IMMEDIATE_CRASH();
372 }
373
374 static void partitionOutOfMemory(const PartitionRootBase* root)
303 { 375 {
304 #if !CPU(64BIT) 376 #if !CPU(64BIT)
305 // Check whether this OOM is due to a lot of super pages that are allocated 377 // Check whether this OOM is due to a lot of super pages that are allocated
306 // but not committed, probably due to http://crbug.com/421387. 378 // but not committed, probably due to http://crbug.com/421387.
307 if (root->totalSizeOfSuperPages + root->totalSizeOfDirectMappedPages - root- >totalSizeOfCommittedPages > kReasonableSizeOfUnusedPages) { 379 if (root->totalSizeOfSuperPages + root->totalSizeOfDirectMappedPages - root- >totalSizeOfCommittedPages > kReasonableSizeOfUnusedPages) {
308 partitionOutOfMemoryWithLotsOfUncommitedPages(); 380 partitionOutOfMemoryWithLotsOfUncommitedPages();
309 } 381 }
310 #endif 382 #endif
311 IMMEDIATE_CRASH(); 383 volatile size_t totalUsage = (*PartitionRootBase::gMemoryUsageReportFunction )();
384 if (totalUsage >= 2UL * 1024 * 1024 * 1024)
385 partitionOutOfMemoryUsing2G();
386 if (totalUsage >= 1UL * 1024 * 1024 * 1024)
387 partitionOutOfMemoryUsing1G();
388 if (totalUsage >= 512 * 1024 * 1024)
389 partitionOutOfMemoryUsing512M();
390 if (totalUsage >= 256 * 1024 * 1024)
391 partitionOutOfMemoryUsing256M();
392 if (totalUsage >= 128 * 1024 * 1024)
393 partitionOutOfMemoryUsing128M();
394 if (totalUsage >= 64 * 1024 * 1024)
395 partitionOutOfMemoryUsing64M();
396 if (totalUsage >= 32 * 1024 * 1024)
397 partitionOutOfMemoryUsing32M();
398 if (totalUsage >= 16 * 1024 * 1024)
399 partitionOutOfMemoryUsing16M();
400 partitionOutOfMemoryUsingLessThan16M();
312 } 401 }
313 402
314 static NEVER_INLINE void partitionExcessiveAllocationSize() 403 static NEVER_INLINE void partitionExcessiveAllocationSize()
315 { 404 {
316 IMMEDIATE_CRASH(); 405 IMMEDIATE_CRASH();
317 } 406 }
318 407
319 static NEVER_INLINE void partitionBucketFull() 408 static NEVER_INLINE void partitionBucketFull()
320 { 409 {
321 IMMEDIATE_CRASH(); 410 IMMEDIATE_CRASH();
(...skipping 1074 matching lines...) Expand 10 before | Expand all | Expand 10 after
1396 partitionStats.totalDiscardableBytes += memoryStats[i].discardableBy tes; 1485 partitionStats.totalDiscardableBytes += memoryStats[i].discardableBy tes;
1397 if (!isLightDump) 1486 if (!isLightDump)
1398 partitionStatsDumper->partitionsDumpBucketStats(partitionName, & memoryStats[i]); 1487 partitionStatsDumper->partitionsDumpBucketStats(partitionName, & memoryStats[i]);
1399 } 1488 }
1400 } 1489 }
1401 partitionStatsDumper->partitionDumpTotals(partitionName, &partitionStats); 1490 partitionStatsDumper->partitionDumpTotals(partitionName, &partitionStats);
1402 } 1491 }
1403 1492
1404 } // namespace WTF 1493 } // namespace WTF
1405 1494
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698