1 // Copyright 2020 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #ifndef BASE_ALLOCATOR_PARTITION_ALLOCATOR_SRC_PARTITION_ALLOC_PARTITION_STATS_H_
6 #define BASE_ALLOCATOR_PARTITION_ALLOCATOR_SRC_PARTITION_ALLOC_PARTITION_STATS_H_
7
8 #include <cstddef>
9 #include <cstdint>
10
11 #include "partition_alloc/partition_alloc_base/component_export.h"
12 #include "partition_alloc/partition_alloc_buildflags.h"
13 #include "partition_alloc/partition_alloc_config.h"
14 #include "partition_alloc/partition_alloc_constants.h"
15
16 namespace partition_alloc {
17
18 // Most of these are not populated if PA_THREAD_CACHE_ENABLE_STATISTICS is not
19 // defined.
20 struct ThreadCacheStats {
21 uint64_t alloc_count; // Total allocation requests.
22 uint64_t alloc_hits; // Thread cache hits.
23 uint64_t alloc_misses; // Thread cache misses.
24
25 // Allocation failure details:
26 uint64_t alloc_miss_empty;
27 uint64_t alloc_miss_too_large;
28
29 // Cache fill details:
30 uint64_t cache_fill_count;
31 uint64_t cache_fill_hits;
32 uint64_t cache_fill_misses; // Object too large.
33
34 uint64_t batch_fill_count; // Number of central allocator requests.
35
36 // Memory cost:
37 uint32_t bucket_total_memory;
38 uint32_t metadata_overhead;
39
40 #if PA_CONFIG(THREAD_CACHE_ALLOC_STATS)
41 uint64_t allocs_per_bucket_[internal::kNumBuckets + 1];
42 #endif // PA_CONFIG(THREAD_CACHE_ALLOC_STATS)
43 };
44
45 // Per-thread allocation statistics. Only covers allocations made through the
46 // partition linked to the thread cache. As the allocator doesn't record
47 // requested sizes in most cases, the data there will be an overestimate of the
48 // actually requested sizes. It is also not expected to sum up to anything
49 // meaningful across threads, due to the lack of synchronization. Figures there
50 // are cumulative, not net. Since the data below is per-thread, note a thread
51 // can deallocate more than it allocated.
52 struct ThreadAllocStats {
53 uint64_t alloc_count;
54 uint64_t alloc_total_size;
55 uint64_t dealloc_count;
56 uint64_t dealloc_total_size;
57 };
58
59 struct LightweightQuarantineStats {
60 size_t size_in_bytes;
61 size_t count;
62 size_t cumulative_size_in_bytes;
63 size_t cumulative_count;
64 size_t quarantine_miss_count; // Object too large.
65 };
66
67 // Struct used to retrieve total memory usage of a partition. Used by
68 // PartitionStatsDumper implementation.
69 struct PartitionMemoryStats {
70 size_t total_mmapped_bytes; // Total bytes mmap()-ed from the system.
71 size_t total_committed_bytes; // Total size of committed pages.
72 size_t max_committed_bytes; // Max size of committed pages.
73 size_t total_allocated_bytes; // Total size of allcoations.
74 size_t max_allocated_bytes; // Max size of allocations.
75 size_t total_resident_bytes; // Total bytes provisioned by the partition.
76 size_t total_active_bytes; // Total active bytes in the partition.
77 size_t total_active_count; // Total count of active objects in the partition.
78 size_t total_decommittable_bytes; // Total bytes that could be decommitted.
79 size_t total_discardable_bytes; // Total bytes that could be discarded.
80 #if BUILDFLAG(ENABLE_BACKUP_REF_PTR_SUPPORT)
81 size_t
82 total_brp_quarantined_bytes; // Total bytes that are quarantined by BRP.
83 size_t total_brp_quarantined_count; // Total number of slots that are
84 // quarantined by BRP.
85 size_t cumulative_brp_quarantined_bytes; // Cumulative bytes that are
86 // quarantined by BRP.
87 size_t cumulative_brp_quarantined_count; // Cumulative number of slots that
88 // are quarantined by BRP.
89 #endif
90
91 bool has_thread_cache;
92 ThreadCacheStats current_thread_cache_stats;
93 ThreadCacheStats all_thread_caches_stats;
94
95 // Count and total duration of system calls made since process start. May not
96 // be reported on all platforms.
97 uint64_t syscall_count;
98 uint64_t syscall_total_time_ns;
99 };
100
101 // Struct used to retrieve memory statistics about a partition bucket. Used by
102 // PartitionStatsDumper implementation.
103 struct PartitionBucketMemoryStats {
104 bool is_valid; // Used to check if the stats is valid.
105 bool is_direct_map; // True if this is a direct mapping; size will not be
106 // unique.
107 uint32_t bucket_slot_size; // The size of the slot in bytes.
108 uint32_t allocated_slot_span_size; // Total size the slot span allocated
109 // from the system (committed pages).
110 uint32_t active_bytes; // Total active bytes used in the bucket.
111 uint32_t active_count; // Total active objects allocated in the bucket.
112 uint32_t resident_bytes; // Total bytes provisioned in the bucket.
113 uint32_t decommittable_bytes; // Total bytes that could be decommitted.
114 uint32_t discardable_bytes; // Total bytes that could be discarded.
115 uint32_t num_full_slot_spans; // Number of slot spans with all slots
116 // allocated.
117 uint32_t num_active_slot_spans; // Number of slot spans that have at least
118 // one provisioned slot.
119 uint32_t num_empty_slot_spans; // Number of slot spans that are empty
120 // but not decommitted.
121 uint32_t num_decommitted_slot_spans; // Number of slot spans that are empty
122 // and decommitted.
123 };
124
125 // Interface that is passed to PartitionDumpStats and
126 // PartitionDumpStats for using the memory statistics.
PA_COMPONENT_EXPORT(PARTITION_ALLOC)127 class PA_COMPONENT_EXPORT(PARTITION_ALLOC) PartitionStatsDumper {
128 public:
129 virtual ~PartitionStatsDumper() = default;
130
131 // Called to dump total memory used by partition, once per partition.
132 virtual void PartitionDumpTotals(const char* partition_name,
133 const PartitionMemoryStats*) = 0;
134
135 // Called to dump stats about buckets, for each bucket.
136 virtual void PartitionsDumpBucketStats(const char* partition_name,
137 const PartitionBucketMemoryStats*) = 0;
138 };
139
140 // Simple version of PartitionStatsDumper, storing the returned stats in stats_.
141 // Does not handle per-bucket stats.
PA_COMPONENT_EXPORT(PARTITION_ALLOC)142 class PA_COMPONENT_EXPORT(PARTITION_ALLOC) SimplePartitionStatsDumper
143 : public PartitionStatsDumper {
144 public:
145 SimplePartitionStatsDumper();
146 ~SimplePartitionStatsDumper() override = default;
147
148 void PartitionDumpTotals(const char* partition_name,
149 const PartitionMemoryStats* memory_stats) override;
150
151 void PartitionsDumpBucketStats(const char* partition_name,
152 const PartitionBucketMemoryStats*) override {}
153
154 const PartitionMemoryStats& stats() const { return stats_; }
155
156 private:
157 PartitionMemoryStats stats_;
158 };
159
160 } // namespace partition_alloc
161
162 #endif // BASE_ALLOCATOR_PARTITION_ALLOCATOR_SRC_PARTITION_ALLOC_PARTITION_STATS_H_
163