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