OLD | NEW |
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "base/allocator/partition_allocator/partition_alloc.h" | 5 #include "base/allocator/partition_allocator/partition_alloc.h" |
6 | 6 |
7 #include <string.h> | 7 #include <string.h> |
8 | 8 |
9 #include "base/allocator/partition_allocator/oom.h" | 9 #include "base/allocator/partition_allocator/oom.h" |
10 #include "base/allocator/partition_allocator/spin_lock.h" | 10 #include "base/allocator/partition_allocator/spin_lock.h" |
(...skipping 1292 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1303 DCHECK(page != &PartitionRootGeneric::gSeedPage); | 1303 DCHECK(page != &PartitionRootGeneric::gSeedPage); |
1304 PartitionDumpPageStats(stats_out, page); | 1304 PartitionDumpPageStats(stats_out, page); |
1305 } | 1305 } |
1306 } | 1306 } |
1307 } | 1307 } |
1308 | 1308 |
1309 void PartitionDumpStatsGeneric(PartitionRootGeneric* partition, | 1309 void PartitionDumpStatsGeneric(PartitionRootGeneric* partition, |
1310 const char* partition_name, | 1310 const char* partition_name, |
1311 bool is_light_dump, | 1311 bool is_light_dump, |
1312 PartitionStatsDumper* dumper) { | 1312 PartitionStatsDumper* dumper) { |
| 1313 PartitionMemoryStats stats = {0}; |
| 1314 stats.total_mmapped_bytes = partition->total_size_of_super_pages + |
| 1315 partition->total_size_of_direct_mapped_pages; |
| 1316 stats.total_committed_bytes = partition->total_size_of_committed_pages; |
| 1317 |
| 1318 size_t direct_mapped_allocations_total_size = 0; |
| 1319 |
| 1320 static const size_t kMaxReportableDirectMaps = 4096; |
| 1321 |
| 1322 // A heap allocation rather than on the stack to avoid stack overflows |
| 1323 // skirmishes (on Windows, in particular.) |
| 1324 uint32_t* direct_map_lengths = nullptr; |
| 1325 if (!is_light_dump) |
| 1326 direct_map_lengths = new uint32_t[kMaxReportableDirectMaps]; |
| 1327 |
1313 PartitionBucketMemoryStats bucket_stats[kGenericNumBuckets]; | 1328 PartitionBucketMemoryStats bucket_stats[kGenericNumBuckets]; |
1314 static const size_t kMaxReportableDirectMaps = 4096; | |
1315 uint32_t direct_map_lengths[kMaxReportableDirectMaps]; | |
1316 size_t num_direct_mapped_allocations = 0; | 1329 size_t num_direct_mapped_allocations = 0; |
1317 | |
1318 { | 1330 { |
1319 subtle::SpinLock::Guard guard(partition->lock); | 1331 subtle::SpinLock::Guard guard(partition->lock); |
1320 | 1332 |
1321 for (size_t i = 0; i < kGenericNumBuckets; ++i) { | 1333 for (size_t i = 0; i < kGenericNumBuckets; ++i) { |
1322 const PartitionBucket* bucket = &partition->buckets[i]; | 1334 const PartitionBucket* bucket = &partition->buckets[i]; |
1323 // Don't report the pseudo buckets that the generic allocator sets up in | 1335 // Don't report the pseudo buckets that the generic allocator sets up in |
1324 // order to preserve a fast size->bucket map (see | 1336 // order to preserve a fast size->bucket map (see |
1325 // PartitionAllocGenericInit for details). | 1337 // PartitionAllocGenericInit for details). |
1326 if (!bucket->active_pages_head) | 1338 if (!bucket->active_pages_head) |
1327 bucket_stats[i].is_valid = false; | 1339 bucket_stats[i].is_valid = false; |
1328 else | 1340 else |
1329 PartitionDumpBucketStats(&bucket_stats[i], bucket); | 1341 PartitionDumpBucketStats(&bucket_stats[i], bucket); |
| 1342 if (bucket_stats[i].is_valid) { |
| 1343 stats.total_resident_bytes += bucket_stats[i].resident_bytes; |
| 1344 stats.total_active_bytes += bucket_stats[i].active_bytes; |
| 1345 stats.total_decommittable_bytes += bucket_stats[i].decommittable_bytes; |
| 1346 stats.total_discardable_bytes += bucket_stats[i].discardable_bytes; |
| 1347 } |
1330 } | 1348 } |
1331 | 1349 |
1332 for (PartitionDirectMapExtent* extent = partition->direct_map_list; extent; | 1350 for (PartitionDirectMapExtent *extent = partition->direct_map_list; |
1333 extent = extent->next_extent) { | 1351 extent && num_direct_mapped_allocations < kMaxReportableDirectMaps; |
| 1352 extent = extent->next_extent, ++num_direct_mapped_allocations) { |
1334 DCHECK(!extent->next_extent || | 1353 DCHECK(!extent->next_extent || |
1335 extent->next_extent->prev_extent == extent); | 1354 extent->next_extent->prev_extent == extent); |
1336 direct_map_lengths[num_direct_mapped_allocations] = | 1355 size_t slot_size = extent->bucket->slot_size; |
1337 extent->bucket->slot_size; | 1356 direct_mapped_allocations_total_size += slot_size; |
1338 ++num_direct_mapped_allocations; | 1357 if (is_light_dump) |
1339 if (num_direct_mapped_allocations == kMaxReportableDirectMaps) | 1358 continue; |
1340 break; | 1359 direct_map_lengths[num_direct_mapped_allocations] = slot_size; |
1341 } | 1360 } |
1342 } | 1361 } |
1343 | 1362 |
1344 // Call |PartitionsDumpBucketStats| after collecting stats because it can try | 1363 if (!is_light_dump) { |
1345 // to allocate using |PartitionAllocGeneric| and it can't obtain the lock. | 1364 // Call |PartitionsDumpBucketStats| after collecting stats because it can |
1346 PartitionMemoryStats stats = {0}; | 1365 // try to allocate using |PartitionAllocGeneric| and it can't obtain the |
1347 stats.total_mmapped_bytes = partition->total_size_of_super_pages + | 1366 // lock. |
1348 partition->total_size_of_direct_mapped_pages; | 1367 for (size_t i = 0; i < kGenericNumBuckets; ++i) { |
1349 stats.total_committed_bytes = partition->total_size_of_committed_pages; | 1368 if (bucket_stats[i].is_valid) |
1350 for (size_t i = 0; i < kGenericNumBuckets; ++i) { | |
1351 if (bucket_stats[i].is_valid) { | |
1352 stats.total_resident_bytes += bucket_stats[i].resident_bytes; | |
1353 stats.total_active_bytes += bucket_stats[i].active_bytes; | |
1354 stats.total_decommittable_bytes += bucket_stats[i].decommittable_bytes; | |
1355 stats.total_discardable_bytes += bucket_stats[i].discardable_bytes; | |
1356 if (!is_light_dump) | |
1357 dumper->PartitionsDumpBucketStats(partition_name, &bucket_stats[i]); | 1369 dumper->PartitionsDumpBucketStats(partition_name, &bucket_stats[i]); |
1358 } | 1370 } |
| 1371 |
| 1372 for (size_t i = 0; i < num_direct_mapped_allocations; ++i) { |
| 1373 uint32_t size = direct_map_lengths[i]; |
| 1374 |
| 1375 PartitionBucketMemoryStats stats; |
| 1376 memset(&stats, '\0', sizeof(stats)); |
| 1377 stats.is_valid = true; |
| 1378 stats.is_direct_map = true; |
| 1379 stats.num_full_pages = 1; |
| 1380 stats.allocated_page_size = size; |
| 1381 stats.bucket_slot_size = size; |
| 1382 stats.active_bytes = size; |
| 1383 stats.resident_bytes = size; |
| 1384 dumper->PartitionsDumpBucketStats(partition_name, &stats); |
| 1385 } |
| 1386 delete[] direct_map_lengths; |
1359 } | 1387 } |
1360 | 1388 |
1361 size_t direct_mapped_allocations_total_size = 0; | |
1362 for (size_t i = 0; i < num_direct_mapped_allocations; ++i) { | |
1363 uint32_t size = direct_map_lengths[i]; | |
1364 direct_mapped_allocations_total_size += size; | |
1365 if (is_light_dump) | |
1366 continue; | |
1367 | |
1368 PartitionBucketMemoryStats stats; | |
1369 memset(&stats, '\0', sizeof(stats)); | |
1370 stats.is_valid = true; | |
1371 stats.is_direct_map = true; | |
1372 stats.num_full_pages = 1; | |
1373 stats.allocated_page_size = size; | |
1374 stats.bucket_slot_size = size; | |
1375 stats.active_bytes = size; | |
1376 stats.resident_bytes = size; | |
1377 dumper->PartitionsDumpBucketStats(partition_name, &stats); | |
1378 } | |
1379 stats.total_resident_bytes += direct_mapped_allocations_total_size; | 1389 stats.total_resident_bytes += direct_mapped_allocations_total_size; |
1380 stats.total_active_bytes += direct_mapped_allocations_total_size; | 1390 stats.total_active_bytes += direct_mapped_allocations_total_size; |
1381 dumper->PartitionDumpTotals(partition_name, &stats); | 1391 dumper->PartitionDumpTotals(partition_name, &stats); |
1382 } | 1392 } |
1383 | 1393 |
1384 void PartitionDumpStats(PartitionRoot* partition, | 1394 void PartitionDumpStats(PartitionRoot* partition, |
1385 const char* partition_name, | 1395 const char* partition_name, |
1386 bool is_light_dump, | 1396 bool is_light_dump, |
1387 PartitionStatsDumper* dumper) { | 1397 PartitionStatsDumper* dumper) { |
1388 static const size_t kMaxReportableBuckets = 4096 / sizeof(void*); | 1398 static const size_t kMaxReportableBuckets = 4096 / sizeof(void*); |
(...skipping 17 matching lines...) Expand all Loading... |
1406 stats.total_decommittable_bytes += memory_stats[i].decommittable_bytes; | 1416 stats.total_decommittable_bytes += memory_stats[i].decommittable_bytes; |
1407 stats.total_discardable_bytes += memory_stats[i].discardable_bytes; | 1417 stats.total_discardable_bytes += memory_stats[i].discardable_bytes; |
1408 if (!is_light_dump) | 1418 if (!is_light_dump) |
1409 dumper->PartitionsDumpBucketStats(partition_name, &memory_stats[i]); | 1419 dumper->PartitionsDumpBucketStats(partition_name, &memory_stats[i]); |
1410 } | 1420 } |
1411 } | 1421 } |
1412 dumper->PartitionDumpTotals(partition_name, &stats); | 1422 dumper->PartitionDumpTotals(partition_name, &stats); |
1413 } | 1423 } |
1414 | 1424 |
1415 } // namespace base | 1425 } // namespace base |
OLD | NEW |