| OLD | NEW |
| 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 30 matching lines...) Expand all Loading... |
| 41 | 41 |
| 42 int Partitions::s_initializationLock = 0; | 42 int Partitions::s_initializationLock = 0; |
| 43 bool Partitions::s_initialized = false; | 43 bool Partitions::s_initialized = false; |
| 44 | 44 |
| 45 PartitionAllocatorGeneric Partitions::m_fastMallocAllocator; | 45 PartitionAllocatorGeneric Partitions::m_fastMallocAllocator; |
| 46 PartitionAllocatorGeneric Partitions::m_bufferAllocator; | 46 PartitionAllocatorGeneric Partitions::m_bufferAllocator; |
| 47 SizeSpecificPartitionAllocator<3328> Partitions::m_nodeAllocator; | 47 SizeSpecificPartitionAllocator<3328> Partitions::m_nodeAllocator; |
| 48 SizeSpecificPartitionAllocator<1024> Partitions::m_layoutAllocator; | 48 SizeSpecificPartitionAllocator<1024> Partitions::m_layoutAllocator; |
| 49 HistogramEnumerationFunction Partitions::m_histogramEnumeration = nullptr; | 49 HistogramEnumerationFunction Partitions::m_histogramEnumeration = nullptr; |
| 50 | 50 |
| 51 void Partitions::initialize(HistogramEnumerationFunction histogramEnumeration) | 51 void Partitions::initialize(HistogramEnumerationFunction histogramEnumeration) { |
| 52 { | 52 spinLockLock(&s_initializationLock); |
| 53 spinLockLock(&s_initializationLock); | |
| 54 | 53 |
| 55 if (!s_initialized) { | 54 if (!s_initialized) { |
| 56 partitionAllocGlobalInit(&Partitions::handleOutOfMemory); | 55 partitionAllocGlobalInit(&Partitions::handleOutOfMemory); |
| 57 m_fastMallocAllocator.init(); | 56 m_fastMallocAllocator.init(); |
| 58 m_bufferAllocator.init(); | 57 m_bufferAllocator.init(); |
| 59 m_nodeAllocator.init(); | 58 m_nodeAllocator.init(); |
| 60 m_layoutAllocator.init(); | 59 m_layoutAllocator.init(); |
| 61 m_histogramEnumeration = histogramEnumeration; | 60 m_histogramEnumeration = histogramEnumeration; |
| 62 s_initialized = true; | 61 s_initialized = true; |
| 63 } | 62 } |
| 64 | 63 |
| 65 spinLockUnlock(&s_initializationLock); | 64 spinLockUnlock(&s_initializationLock); |
| 66 } | 65 } |
| 67 | 66 |
| 68 void Partitions::shutdown() | 67 void Partitions::shutdown() { |
| 69 { | 68 // We could ASSERT here for a memory leak within the partition, but it leads |
| 70 // We could ASSERT here for a memory leak within the partition, but it leads | 69 // to very hard to diagnose ASSERTs, so it's best to leave leak checking for |
| 71 // to very hard to diagnose ASSERTs, so it's best to leave leak checking for | 70 // the valgrind and heapcheck bots, which run without partitions. |
| 72 // the valgrind and heapcheck bots, which run without partitions. | 71 (void)m_layoutAllocator.shutdown(); |
| 73 (void) m_layoutAllocator.shutdown(); | 72 (void)m_nodeAllocator.shutdown(); |
| 74 (void) m_nodeAllocator.shutdown(); | 73 (void)m_bufferAllocator.shutdown(); |
| 75 (void) m_bufferAllocator.shutdown(); | 74 (void)m_fastMallocAllocator.shutdown(); |
| 76 (void) m_fastMallocAllocator.shutdown(); | |
| 77 } | 75 } |
| 78 | 76 |
| 79 void Partitions::decommitFreeableMemory() | 77 void Partitions::decommitFreeableMemory() { |
| 80 { | 78 ASSERT(isMainThread()); |
| 81 ASSERT(isMainThread()); | |
| 82 | 79 |
| 83 partitionPurgeMemoryGeneric(bufferPartition(), PartitionPurgeDecommitEmptyPa
ges); | 80 partitionPurgeMemoryGeneric(bufferPartition(), PartitionPurgeDecommitEmptyPage
s); |
| 84 partitionPurgeMemoryGeneric(fastMallocPartition(), PartitionPurgeDecommitEmp
tyPages); | 81 partitionPurgeMemoryGeneric(fastMallocPartition(), PartitionPurgeDecommitEmpty
Pages); |
| 85 partitionPurgeMemory(nodePartition(), PartitionPurgeDecommitEmptyPages); | 82 partitionPurgeMemory(nodePartition(), PartitionPurgeDecommitEmptyPages); |
| 86 partitionPurgeMemory(layoutPartition(), PartitionPurgeDecommitEmptyPages); | 83 partitionPurgeMemory(layoutPartition(), PartitionPurgeDecommitEmptyPages); |
| 87 } | 84 } |
| 88 | 85 |
| 89 void Partitions::reportMemoryUsageHistogram() | 86 void Partitions::reportMemoryUsageHistogram() { |
| 90 { | 87 static size_t supportedMaxSizeInMB = 4 * 1024; |
| 91 static size_t supportedMaxSizeInMB = 4 * 1024; | 88 static size_t observedMaxSizeInMB = 0; |
| 92 static size_t observedMaxSizeInMB = 0; | |
| 93 | 89 |
| 94 if (!m_histogramEnumeration) | 90 if (!m_histogramEnumeration) |
| 95 return; | 91 return; |
| 96 // We only report the memory in the main thread. | 92 // We only report the memory in the main thread. |
| 97 if (!isMainThread()) | 93 if (!isMainThread()) |
| 98 return; | 94 return; |
| 99 // +1 is for rounding up the sizeInMB. | 95 // +1 is for rounding up the sizeInMB. |
| 100 size_t sizeInMB = Partitions::totalSizeOfCommittedPages() / 1024 / 1024 + 1; | 96 size_t sizeInMB = Partitions::totalSizeOfCommittedPages() / 1024 / 1024 + 1; |
| 101 if (sizeInMB >= supportedMaxSizeInMB) | 97 if (sizeInMB >= supportedMaxSizeInMB) |
| 102 sizeInMB = supportedMaxSizeInMB - 1; | 98 sizeInMB = supportedMaxSizeInMB - 1; |
| 103 if (sizeInMB > observedMaxSizeInMB) { | 99 if (sizeInMB > observedMaxSizeInMB) { |
| 104 // Send a UseCounter only when we see the highest memory usage | 100 // Send a UseCounter only when we see the highest memory usage |
| 105 // we've ever seen. | 101 // we've ever seen. |
| 106 m_histogramEnumeration("PartitionAlloc.CommittedSize", sizeInMB, support
edMaxSizeInMB); | 102 m_histogramEnumeration("PartitionAlloc.CommittedSize", sizeInMB, supportedMa
xSizeInMB); |
| 107 observedMaxSizeInMB = sizeInMB; | 103 observedMaxSizeInMB = sizeInMB; |
| 108 } | 104 } |
| 109 } | 105 } |
| 110 | 106 |
| 111 void Partitions::dumpMemoryStats(bool isLightDump, PartitionStatsDumper* partiti
onStatsDumper) | 107 void Partitions::dumpMemoryStats(bool isLightDump, PartitionStatsDumper* partiti
onStatsDumper) { |
| 112 { | 108 // Object model and rendering partitions are not thread safe and can be |
| 113 // Object model and rendering partitions are not thread safe and can be | 109 // accessed only on the main thread. |
| 114 // accessed only on the main thread. | 110 ASSERT(isMainThread()); |
| 115 ASSERT(isMainThread()); | |
| 116 | 111 |
| 117 decommitFreeableMemory(); | 112 decommitFreeableMemory(); |
| 118 partitionDumpStatsGeneric(fastMallocPartition(), "fast_malloc", isLightDump,
partitionStatsDumper); | 113 partitionDumpStatsGeneric(fastMallocPartition(), "fast_malloc", isLightDump, p
artitionStatsDumper); |
| 119 partitionDumpStatsGeneric(bufferPartition(), "buffer", isLightDump, partitio
nStatsDumper); | 114 partitionDumpStatsGeneric(bufferPartition(), "buffer", isLightDump, partitionS
tatsDumper); |
| 120 partitionDumpStats(nodePartition(), "node", isLightDump, partitionStatsDumpe
r); | 115 partitionDumpStats(nodePartition(), "node", isLightDump, partitionStatsDumper)
; |
| 121 partitionDumpStats(layoutPartition(), "layout", isLightDump, partitionStatsD
umper); | 116 partitionDumpStats(layoutPartition(), "layout", isLightDump, partitionStatsDum
per); |
| 122 } | 117 } |
| 123 | 118 |
| 124 static NEVER_INLINE void partitionsOutOfMemoryUsing2G() | 119 static NEVER_INLINE void partitionsOutOfMemoryUsing2G() { |
| 125 { | 120 size_t signature = 2UL * 1024 * 1024 * 1024; |
| 126 size_t signature = 2UL * 1024 * 1024 * 1024; | 121 alias(&signature); |
| 127 alias(&signature); | 122 IMMEDIATE_CRASH(); |
| 128 IMMEDIATE_CRASH(); | |
| 129 } | 123 } |
| 130 | 124 |
| 131 static NEVER_INLINE void partitionsOutOfMemoryUsing1G() | 125 static NEVER_INLINE void partitionsOutOfMemoryUsing1G() { |
| 132 { | 126 size_t signature = 1UL * 1024 * 1024 * 1024; |
| 133 size_t signature = 1UL * 1024 * 1024 * 1024; | 127 alias(&signature); |
| 134 alias(&signature); | 128 IMMEDIATE_CRASH(); |
| 135 IMMEDIATE_CRASH(); | |
| 136 } | 129 } |
| 137 | 130 |
| 138 static NEVER_INLINE void partitionsOutOfMemoryUsing512M() | 131 static NEVER_INLINE void partitionsOutOfMemoryUsing512M() { |
| 139 { | 132 size_t signature = 512 * 1024 * 1024; |
| 140 size_t signature = 512 * 1024 * 1024; | 133 alias(&signature); |
| 141 alias(&signature); | 134 IMMEDIATE_CRASH(); |
| 142 IMMEDIATE_CRASH(); | |
| 143 } | 135 } |
| 144 | 136 |
| 145 static NEVER_INLINE void partitionsOutOfMemoryUsing256M() | 137 static NEVER_INLINE void partitionsOutOfMemoryUsing256M() { |
| 146 { | 138 size_t signature = 256 * 1024 * 1024; |
| 147 size_t signature = 256 * 1024 * 1024; | 139 alias(&signature); |
| 148 alias(&signature); | 140 IMMEDIATE_CRASH(); |
| 149 IMMEDIATE_CRASH(); | |
| 150 } | 141 } |
| 151 | 142 |
| 152 static NEVER_INLINE void partitionsOutOfMemoryUsing128M() | 143 static NEVER_INLINE void partitionsOutOfMemoryUsing128M() { |
| 153 { | 144 size_t signature = 128 * 1024 * 1024; |
| 154 size_t signature = 128 * 1024 * 1024; | 145 alias(&signature); |
| 155 alias(&signature); | 146 IMMEDIATE_CRASH(); |
| 156 IMMEDIATE_CRASH(); | |
| 157 } | 147 } |
| 158 | 148 |
| 159 static NEVER_INLINE void partitionsOutOfMemoryUsing64M() | 149 static NEVER_INLINE void partitionsOutOfMemoryUsing64M() { |
| 160 { | 150 size_t signature = 64 * 1024 * 1024; |
| 161 size_t signature = 64 * 1024 * 1024; | 151 alias(&signature); |
| 162 alias(&signature); | 152 IMMEDIATE_CRASH(); |
| 163 IMMEDIATE_CRASH(); | |
| 164 } | 153 } |
| 165 | 154 |
| 166 static NEVER_INLINE void partitionsOutOfMemoryUsing32M() | 155 static NEVER_INLINE void partitionsOutOfMemoryUsing32M() { |
| 167 { | 156 size_t signature = 32 * 1024 * 1024; |
| 168 size_t signature = 32 * 1024 * 1024; | 157 alias(&signature); |
| 169 alias(&signature); | 158 IMMEDIATE_CRASH(); |
| 170 IMMEDIATE_CRASH(); | |
| 171 } | 159 } |
| 172 | 160 |
| 173 static NEVER_INLINE void partitionsOutOfMemoryUsing16M() | 161 static NEVER_INLINE void partitionsOutOfMemoryUsing16M() { |
| 174 { | 162 size_t signature = 16 * 1024 * 1024; |
| 175 size_t signature = 16 * 1024 * 1024; | 163 alias(&signature); |
| 176 alias(&signature); | 164 IMMEDIATE_CRASH(); |
| 177 IMMEDIATE_CRASH(); | |
| 178 } | 165 } |
| 179 | 166 |
| 180 static NEVER_INLINE void partitionsOutOfMemoryUsingLessThan16M() | 167 static NEVER_INLINE void partitionsOutOfMemoryUsingLessThan16M() { |
| 181 { | 168 size_t signature = 16 * 1024 * 1024 - 1; |
| 182 size_t signature = 16 * 1024 * 1024 - 1; | 169 alias(&signature); |
| 183 alias(&signature); | 170 IMMEDIATE_CRASH(); |
| 184 IMMEDIATE_CRASH(); | |
| 185 } | 171 } |
| 186 | 172 |
| 187 void Partitions::handleOutOfMemory() | 173 void Partitions::handleOutOfMemory() { |
| 188 { | 174 volatile size_t totalUsage = totalSizeOfCommittedPages(); |
| 189 volatile size_t totalUsage = totalSizeOfCommittedPages(); | |
| 190 | 175 |
| 191 if (totalUsage >= 2UL * 1024 * 1024 * 1024) | 176 if (totalUsage >= 2UL * 1024 * 1024 * 1024) |
| 192 partitionsOutOfMemoryUsing2G(); | 177 partitionsOutOfMemoryUsing2G(); |
| 193 if (totalUsage >= 1UL * 1024 * 1024 * 1024) | 178 if (totalUsage >= 1UL * 1024 * 1024 * 1024) |
| 194 partitionsOutOfMemoryUsing1G(); | 179 partitionsOutOfMemoryUsing1G(); |
| 195 if (totalUsage >= 512 * 1024 * 1024) | 180 if (totalUsage >= 512 * 1024 * 1024) |
| 196 partitionsOutOfMemoryUsing512M(); | 181 partitionsOutOfMemoryUsing512M(); |
| 197 if (totalUsage >= 256 * 1024 * 1024) | 182 if (totalUsage >= 256 * 1024 * 1024) |
| 198 partitionsOutOfMemoryUsing256M(); | 183 partitionsOutOfMemoryUsing256M(); |
| 199 if (totalUsage >= 128 * 1024 * 1024) | 184 if (totalUsage >= 128 * 1024 * 1024) |
| 200 partitionsOutOfMemoryUsing128M(); | 185 partitionsOutOfMemoryUsing128M(); |
| 201 if (totalUsage >= 64 * 1024 * 1024) | 186 if (totalUsage >= 64 * 1024 * 1024) |
| 202 partitionsOutOfMemoryUsing64M(); | 187 partitionsOutOfMemoryUsing64M(); |
| 203 if (totalUsage >= 32 * 1024 * 1024) | 188 if (totalUsage >= 32 * 1024 * 1024) |
| 204 partitionsOutOfMemoryUsing32M(); | 189 partitionsOutOfMemoryUsing32M(); |
| 205 if (totalUsage >= 16 * 1024 * 1024) | 190 if (totalUsage >= 16 * 1024 * 1024) |
| 206 partitionsOutOfMemoryUsing16M(); | 191 partitionsOutOfMemoryUsing16M(); |
| 207 partitionsOutOfMemoryUsingLessThan16M(); | 192 partitionsOutOfMemoryUsingLessThan16M(); |
| 208 } | 193 } |
| 209 | 194 |
| 210 } // namespace WTF | 195 } // namespace WTF |
| OLD | NEW |