| 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 |