Skip to content

Commit daaff7d

Browse files
omerktzCommit Bot
authored andcommitted
cppgc: Collect heap statistics
HeapBase::CollectStatistics returns a HeapStatistics struct that can be used by blink to populate a memory dump. Bug: chromium:1056170 Change-Id: Ic147a02ba6b4aa77bf92cfca067da70b7e1af55b Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2689181 Commit-Queue: Omer Katz <omerkatz@chromium.org> Reviewed-by: Michael Lippautz <mlippautz@chromium.org> Cr-Commit-Position: refs/heads/master@{#72660}
1 parent 1105d7b commit daaff7d

19 files changed

Lines changed: 512 additions & 8 deletions

BUILD.gn

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4666,6 +4666,7 @@ v8_source_set("cppgc_base") {
46664666
"include/cppgc/garbage-collected.h",
46674667
"include/cppgc/heap-consistency.h",
46684668
"include/cppgc/heap-state.h",
4669+
"include/cppgc/heap-statistics.h",
46694670
"include/cppgc/heap.h",
46704671
"include/cppgc/internal/api-constants.h",
46714672
"include/cppgc/internal/atomic-entry-flag.h",
@@ -4719,6 +4720,8 @@ v8_source_set("cppgc_base") {
47194720
"src/heap/cppgc/heap-space.cc",
47204721
"src/heap/cppgc/heap-space.h",
47214722
"src/heap/cppgc/heap-state.cc",
4723+
"src/heap/cppgc/heap-statistics-collector.cc",
4724+
"src/heap/cppgc/heap-statistics-collector.h",
47224725
"src/heap/cppgc/heap-visitor.h",
47234726
"src/heap/cppgc/heap.cc",
47244727
"src/heap/cppgc/heap.h",

include/DEPS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ include_rules = [
44
"+cppgc/common.h",
55
# Used by v8-cppgc.h to bridge to cppgc.
66
"+cppgc/custom-space.h",
7+
"+cppgc/heap-statistics.h",
78
"+cppgc/internal/process-heap.h",
89
"+cppgc/internal/write-barrier.h",
910
"+cppgc/visitor.h",

include/cppgc/heap-statistics.h

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
// Copyright 2021 the V8 project authors. All rights reserved.
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 INCLUDE_CPPGC_HEAP_STATISTICS_H_
6+
#define INCLUDE_CPPGC_HEAP_STATISTICS_H_
7+
8+
#include <memory>
9+
#include <string>
10+
#include <vector>
11+
12+
namespace cppgc {
13+
14+
/**
15+
* `HeapStatistics` contains memory consumption and utilization statistics for a
16+
* cppgc heap.
17+
*/
18+
struct HeapStatistics final {
19+
/**
20+
* Specifies the detail level of the heap statistics. Brief statistics contain
21+
* only the top-level allocated and used memory statistics for the entire
22+
* heap. Detailed statistics also contain a break down per space and page, as
23+
* well as freelist statistics and object type histograms. Note that used
24+
* memory reported by brief statistics and detailed statistics might differ
25+
* slightly.
26+
*/
27+
enum DetailLevel : uint8_t {
28+
kBrief,
29+
kDetailed,
30+
};
31+
32+
/**
33+
* Statistics of object types. For each type the statistics record its name,
34+
* how many objects of that type were allocated, and the overall size used by
35+
* these objects.
36+
*/
37+
struct ObjectStatistics {
38+
/** Number of distinct types in the heap. */
39+
size_t num_types = 0;
40+
/** Name of each type in the heap. */
41+
std::vector<std::string> type_name;
42+
/** Number of allocated objects per each type. */
43+
std::vector<size_t> type_count;
44+
/** Overall size of allocated objects per each type. */
45+
std::vector<size_t> type_bytes;
46+
};
47+
48+
/**
49+
* Page granularity statistics. For each page the statistics record the
50+
* allocated memory size and overall used memory size for the page.
51+
*/
52+
struct PageStatistics {
53+
/** Overall amount of memory allocated for the page. */
54+
size_t allocated_size_bytes = 0;
55+
/** Amount of memory actually used on the page. */
56+
size_t used_size_bytes = 0;
57+
};
58+
59+
/**
60+
* Stastistics of the freelist (used only in non-large object spaces). For
61+
* each bucket in the freelist the statistics record the bucket size, the
62+
* number of freelist entries in the bucket, and the overall allocated memory
63+
* consumed by these freelist entries.
64+
*/
65+
struct FreeListStatistics {
66+
/** bucket sizes in the freelist. */
67+
std::vector<size_t> bucket_size;
68+
/** number of freelist entries per bucket. */
69+
std::vector<size_t> free_count;
70+
/** memory size concumed by freelist entries per size. */
71+
std::vector<size_t> free_size;
72+
};
73+
74+
/**
75+
* Space granularity statistics. For each space the statistics record the
76+
* space name, the amount of allocated memory and overall used memory for the
77+
* space. The statistics also contain statistics for each of the space's
78+
* pages, its freelist and the objects allocated on the space.
79+
*/
80+
struct SpaceStatistics {
81+
/** The space name */
82+
std::string name;
83+
/** Overall amount of memory allocated for the space. */
84+
size_t allocated_size_bytes = 0;
85+
/** Amount of memory actually used on the space. */
86+
size_t used_size_bytes = 0;
87+
/** Statistics for each of the pages in the space. */
88+
std::vector<PageStatistics> page_stats;
89+
/** Statistics for the freelist of the space. */
90+
FreeListStatistics free_list_stats;
91+
/** Statistics for object allocated on the space. Filled only when
92+
* NameProvider::HideInternalNames() is false. */
93+
ObjectStatistics object_stats;
94+
};
95+
96+
/** Overall amount of memory allocated for the heap. */
97+
size_t allocated_size_bytes = 0;
98+
/** Amount of memory actually used on the heap. */
99+
size_t used_size_bytes = 0;
100+
/** Detail level of this HeapStatistics. */
101+
DetailLevel detail_level;
102+
103+
/** Statistics for each of the spaces in the heap. Filled only when
104+
* detail_level is kDetailed. */
105+
std::vector<SpaceStatistics> space_stats;
106+
};
107+
108+
} // namespace cppgc
109+
110+
#endif // INCLUDE_CPPGC_HEAP_STATISTICS_H_

include/v8-cppgc.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include <vector>
1111

1212
#include "cppgc/custom-space.h"
13+
#include "cppgc/heap-statistics.h"
1314
#include "cppgc/internal/process-heap.h"
1415
#include "cppgc/internal/write-barrier.h"
1516
#include "cppgc/visitor.h"
@@ -106,6 +107,15 @@ class V8_EXPORT CppHeap {
106107
*/
107108
void Terminate();
108109

110+
/**
111+
* \param detail_level specifies whether should return detailed
112+
* statistics or only brief summary statistics.
113+
* \returns current CppHeap statistics regarding memory consumption
114+
* and utilization.
115+
*/
116+
cppgc::HeapStatistics CollectStatistics(
117+
cppgc::HeapStatistics::DetailLevel detail_level);
118+
109119
private:
110120
CppHeap() = default;
111121

src/heap/cppgc-js/cpp-heap.cc

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,12 @@ cppgc::HeapHandle& CppHeap::GetHeapHandle() {
5858

5959
void CppHeap::Terminate() { internal::CppHeap::From(this)->Terminate(); }
6060

61+
cppgc::HeapStatistics CppHeap::CollectStatistics(
62+
cppgc::HeapStatistics::DetailLevel detail_level) {
63+
return internal::CppHeap::From(this)->AsBase().CollectStatistics(
64+
detail_level);
65+
}
66+
6167
void JSHeapConsistency::DijkstraMarkingBarrierSlow(
6268
cppgc::HeapHandle& heap_handle, const TracedReferenceBase& ref) {
6369
auto& heap_base = cppgc::internal::HeapBase::From(heap_handle);

src/heap/cppgc/free-list.cc

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,5 +191,26 @@ bool FreeList::IsConsistent(size_t index) const {
191191
!free_list_tails_[index]->Next());
192192
}
193193

194+
void FreeList::CollectStatistics(
195+
HeapStatistics::FreeListStatistics& free_list_stats) {
196+
std::vector<size_t>& bucket_size = free_list_stats.bucket_size;
197+
std::vector<size_t>& free_count = free_list_stats.free_count;
198+
std::vector<size_t>& free_size = free_list_stats.free_size;
199+
DCHECK(bucket_size.empty());
200+
DCHECK(free_count.empty());
201+
DCHECK(free_size.empty());
202+
for (size_t i = 0; i < kPageSizeLog2; ++i) {
203+
size_t entry_count = 0;
204+
size_t entry_size = 0;
205+
for (Entry* entry = free_list_heads_[i]; entry; entry = entry->Next()) {
206+
++entry_count;
207+
entry_size += entry->GetSize();
208+
}
209+
bucket_size.push_back(static_cast<size_t>(1) << i);
210+
free_count.push_back(entry_count);
211+
free_size.push_back(entry_size);
212+
}
213+
}
214+
194215
} // namespace internal
195216
} // namespace cppgc

src/heap/cppgc/free-list.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
#include <array>
99

10+
#include "include/cppgc/heap-statistics.h"
1011
#include "src/base/macros.h"
1112
#include "src/heap/cppgc/globals.h"
1213
#include "src/heap/cppgc/heap-object-header.h"
@@ -45,6 +46,8 @@ class V8_EXPORT_PRIVATE FreeList {
4546

4647
bool Contains(Block) const;
4748

49+
void CollectStatistics(HeapStatistics::FreeListStatistics&);
50+
4851
private:
4952
class Entry;
5053

src/heap/cppgc/gc-info-table.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,8 @@ class V8_EXPORT GCInfoTable final {
6363
return table_[index];
6464
}
6565

66-
GCInfoIndex NumberOfGCInfosForTesting() const { return current_index_; }
66+
GCInfoIndex NumberOfGCInfos() const { return current_index_; }
67+
6768
GCInfoIndex LimitForTesting() const { return limit_; }
6869
GCInfo& TableSlotForTesting(GCInfoIndex index) { return table_[index]; }
6970

src/heap/cppgc/heap-base.cc

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include "src/heap/cppgc/globals.h"
1111
#include "src/heap/cppgc/heap-object-header.h"
1212
#include "src/heap/cppgc/heap-page.h"
13+
#include "src/heap/cppgc/heap-statistics-collector.h"
1314
#include "src/heap/cppgc/heap-visitor.h"
1415
#include "src/heap/cppgc/marker.h"
1516
#include "src/heap/cppgc/marking-verifier.h"
@@ -133,5 +134,19 @@ void HeapBase::Terminate() {
133134
disallow_gc_scope_++;
134135
}
135136

137+
HeapStatistics HeapBase::CollectStatistics(
138+
HeapStatistics::DetailLevel detail_level) {
139+
if (detail_level == HeapStatistics::DetailLevel::kBrief) {
140+
return {stats_collector_->allocated_memory_size(),
141+
stats_collector_->allocated_object_size(),
142+
HeapStatistics::DetailLevel::kBrief,
143+
{}};
144+
}
145+
146+
sweeper_.FinishIfRunning();
147+
object_allocator_.ResetLinearAllocationBuffers();
148+
return HeapStatisticsCollector().CollectStatistics(this);
149+
}
150+
136151
} // namespace internal
137152
} // namespace cppgc

src/heap/cppgc/heap-base.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#include <memory>
99
#include <set>
1010

11+
#include "include/cppgc/heap-statistics.h"
1112
#include "include/cppgc/heap.h"
1213
#include "include/cppgc/internal/persistent-node.h"
1314
#include "include/cppgc/macros.h"
@@ -163,6 +164,8 @@ class V8_EXPORT_PRIVATE HeapBase : public cppgc::HeapHandle {
163164
void EnableTestingAPIsForTesting() { testing_enabled_ = true; }
164165
bool TestingEnabled() const { return testing_enabled_; }
165166

167+
HeapStatistics CollectStatistics(HeapStatistics::DetailLevel);
168+
166169
protected:
167170
virtual void FinalizeIncrementalGarbageCollectionIfNeeded(
168171
cppgc::Heap::StackState) = 0;

0 commit comments

Comments
 (0)