| Index: base/allocator/partition_allocator/partition_alloc.cc
|
| diff --git a/base/allocator/partition_allocator/partition_alloc.cc b/base/allocator/partition_allocator/partition_alloc.cc
|
| index eb4c6390a15f018251dafcda0857421e1f40b7fe..cdf8577929a64a7dd3f8cb12565f2c5a3f6a889a 100644
|
| --- a/base/allocator/partition_allocator/partition_alloc.cc
|
| +++ b/base/allocator/partition_allocator/partition_alloc.cc
|
| @@ -1310,11 +1310,23 @@ void PartitionDumpStatsGeneric(PartitionRootGeneric* partition,
|
| const char* partition_name,
|
| bool is_light_dump,
|
| PartitionStatsDumper* dumper) {
|
| - PartitionBucketMemoryStats bucket_stats[kGenericNumBuckets];
|
| + PartitionMemoryStats stats = {0};
|
| + stats.total_mmapped_bytes = partition->total_size_of_super_pages +
|
| + partition->total_size_of_direct_mapped_pages;
|
| + stats.total_committed_bytes = partition->total_size_of_committed_pages;
|
| +
|
| + size_t direct_mapped_allocations_total_size = 0;
|
| +
|
| static const size_t kMaxReportableDirectMaps = 4096;
|
| - uint32_t direct_map_lengths[kMaxReportableDirectMaps];
|
| - size_t num_direct_mapped_allocations = 0;
|
|
|
| + // A heap allocation rather than on the stack to avoid stack overflows
|
| + // skirmishes (on Windows, in particular.)
|
| + uint32_t* direct_map_lengths = nullptr;
|
| + if (!is_light_dump)
|
| + direct_map_lengths = new uint32_t[kMaxReportableDirectMaps];
|
| +
|
| + PartitionBucketMemoryStats bucket_stats[kGenericNumBuckets];
|
| + size_t num_direct_mapped_allocations = 0;
|
| {
|
| subtle::SpinLock::Guard guard(partition->lock);
|
|
|
| @@ -1327,55 +1339,53 @@ void PartitionDumpStatsGeneric(PartitionRootGeneric* partition,
|
| bucket_stats[i].is_valid = false;
|
| else
|
| PartitionDumpBucketStats(&bucket_stats[i], bucket);
|
| + if (bucket_stats[i].is_valid) {
|
| + stats.total_resident_bytes += bucket_stats[i].resident_bytes;
|
| + stats.total_active_bytes += bucket_stats[i].active_bytes;
|
| + stats.total_decommittable_bytes += bucket_stats[i].decommittable_bytes;
|
| + stats.total_discardable_bytes += bucket_stats[i].discardable_bytes;
|
| + }
|
| }
|
|
|
| - for (PartitionDirectMapExtent* extent = partition->direct_map_list; extent;
|
| - extent = extent->next_extent) {
|
| + for (PartitionDirectMapExtent *extent = partition->direct_map_list;
|
| + extent && num_direct_mapped_allocations < kMaxReportableDirectMaps;
|
| + extent = extent->next_extent, ++num_direct_mapped_allocations) {
|
| DCHECK(!extent->next_extent ||
|
| extent->next_extent->prev_extent == extent);
|
| - direct_map_lengths[num_direct_mapped_allocations] =
|
| - extent->bucket->slot_size;
|
| - ++num_direct_mapped_allocations;
|
| - if (num_direct_mapped_allocations == kMaxReportableDirectMaps)
|
| - break;
|
| + size_t slot_size = extent->bucket->slot_size;
|
| + direct_mapped_allocations_total_size += slot_size;
|
| + if (is_light_dump)
|
| + continue;
|
| + direct_map_lengths[num_direct_mapped_allocations] = slot_size;
|
| }
|
| }
|
|
|
| - // Call |PartitionsDumpBucketStats| after collecting stats because it can try
|
| - // to allocate using |PartitionAllocGeneric| and it can't obtain the lock.
|
| - PartitionMemoryStats stats = {0};
|
| - stats.total_mmapped_bytes = partition->total_size_of_super_pages +
|
| - partition->total_size_of_direct_mapped_pages;
|
| - stats.total_committed_bytes = partition->total_size_of_committed_pages;
|
| - for (size_t i = 0; i < kGenericNumBuckets; ++i) {
|
| - if (bucket_stats[i].is_valid) {
|
| - stats.total_resident_bytes += bucket_stats[i].resident_bytes;
|
| - stats.total_active_bytes += bucket_stats[i].active_bytes;
|
| - stats.total_decommittable_bytes += bucket_stats[i].decommittable_bytes;
|
| - stats.total_discardable_bytes += bucket_stats[i].discardable_bytes;
|
| - if (!is_light_dump)
|
| + if (!is_light_dump) {
|
| + // Call |PartitionsDumpBucketStats| after collecting stats because it can
|
| + // try to allocate using |PartitionAllocGeneric| and it can't obtain the
|
| + // lock.
|
| + for (size_t i = 0; i < kGenericNumBuckets; ++i) {
|
| + if (bucket_stats[i].is_valid)
|
| dumper->PartitionsDumpBucketStats(partition_name, &bucket_stats[i]);
|
| }
|
| - }
|
| -
|
| - size_t direct_mapped_allocations_total_size = 0;
|
| - for (size_t i = 0; i < num_direct_mapped_allocations; ++i) {
|
| - uint32_t size = direct_map_lengths[i];
|
| - direct_mapped_allocations_total_size += size;
|
| - if (is_light_dump)
|
| - continue;
|
|
|
| - PartitionBucketMemoryStats stats;
|
| - memset(&stats, '\0', sizeof(stats));
|
| - stats.is_valid = true;
|
| - stats.is_direct_map = true;
|
| - stats.num_full_pages = 1;
|
| - stats.allocated_page_size = size;
|
| - stats.bucket_slot_size = size;
|
| - stats.active_bytes = size;
|
| - stats.resident_bytes = size;
|
| - dumper->PartitionsDumpBucketStats(partition_name, &stats);
|
| + for (size_t i = 0; i < num_direct_mapped_allocations; ++i) {
|
| + uint32_t size = direct_map_lengths[i];
|
| +
|
| + PartitionBucketMemoryStats stats;
|
| + memset(&stats, '\0', sizeof(stats));
|
| + stats.is_valid = true;
|
| + stats.is_direct_map = true;
|
| + stats.num_full_pages = 1;
|
| + stats.allocated_page_size = size;
|
| + stats.bucket_slot_size = size;
|
| + stats.active_bytes = size;
|
| + stats.resident_bytes = size;
|
| + dumper->PartitionsDumpBucketStats(partition_name, &stats);
|
| + }
|
| + delete[] direct_map_lengths;
|
| }
|
| +
|
| stats.total_resident_bytes += direct_mapped_allocations_total_size;
|
| stats.total_active_bytes += direct_mapped_allocations_total_size;
|
| dumper->PartitionDumpTotals(partition_name, &stats);
|
|
|