Skip to content

Commit 0f024d4

Browse files
IlyasShabiV8 LUCI CQ
authored andcommitted
[heap profiler] Add is_live field to AllocationProfile::Sample
When using kSamplingIncludeObjectsCollectedByMajorGC/MinorGC flag, samples for collected objects are retained but callers had no way to distinguish live from dead objects. Add is_live to expose this information. Change-Id: I2e930644348ff942caa4b192a127c5baa05bbfef Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/7603535 Reviewed-by: Dominik Inführ <[email protected]> Commit-Queue: Dominik Inführ <[email protected]> Reviewed-by: Michael Lippautz <[email protected]> Cr-Commit-Position: refs/heads/main@{#105698}
1 parent 26fe633 commit 0f024d4

4 files changed

Lines changed: 85 additions & 1 deletion

File tree

AUTHORS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,7 @@ Huáng Jùnliàng <[email protected]>
156156
HyeockJin Kim <[email protected]>
157157
Iain Ireland <[email protected]>
158158
Ilya Gavrilin <[email protected]>
159+
Ilyas Shabi <[email protected]>
159160
Ingvar Stepanyan <[email protected]>
160161
Ioseb Dzmanashvili <[email protected]>
161162
Isiah Meadows <[email protected]>

include/v8-profiler.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -830,6 +830,12 @@ class V8_EXPORT AllocationProfile {
830830
* what samples were added or removed between two snapshots.
831831
*/
832832
uint64_t sample_id;
833+
834+
/**
835+
* Indicates whether the sampled allocation is still live or has already
836+
* been collected by GC.
837+
*/
838+
bool is_live;
833839
};
834840

835841
/**

src/profiler/sampling-heap-profiler.cc

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -312,9 +312,10 @@ SamplingHeapProfiler::BuildSamples() const {
312312
samples.reserve(samples_.size());
313313
for (const auto& it : samples_) {
314314
const Sample* sample = it.second.get();
315+
const bool is_live = !sample->global.IsEmpty();
315316
samples.emplace_back(v8::AllocationProfile::Sample{
316317
sample->owner->id_, sample->size, ScaleSample(sample->size, 1).count,
317-
sample->sample_id});
318+
sample->sample_id, is_live});
318319
}
319320
return samples;
320321
}

test/cctest/test-heap-profiler.cc

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4324,6 +4324,82 @@ TEST(SamplingHeapProfilerLargeInterval) {
43244324
heap_profiler->StopSamplingHeapProfiler();
43254325
}
43264326

4327+
TEST(SamplingHeapProfilerSampleWithoutGCFlags) {
4328+
v8::HandleScope scope(CcTest::isolate());
4329+
LocalContext env;
4330+
v8::HeapProfiler* heap_profiler = env.isolate()->GetHeapProfiler();
4331+
4332+
// Suppress randomness to avoid flakiness in tests.
4333+
i::v8_flags.sampling_heap_profiler_suppress_randomness = true;
4334+
4335+
heap_profiler->StartSamplingHeapProfiler(1024);
4336+
4337+
// Allocate objects that will be retained
4338+
CompileRun(
4339+
"var retained = [];\n"
4340+
"for (var i = 0; i < 500; i++) retained.push(new Array(10));\n");
4341+
4342+
CompileRun("for (var i = 0; i < 500; i++) new Array(10);\n");
4343+
4344+
std::unique_ptr<v8::AllocationProfile> profile(
4345+
heap_profiler->GetAllocationProfile());
4346+
CHECK(profile);
4347+
4348+
const auto& samples = profile->GetSamples();
4349+
CHECK(!samples.empty());
4350+
4351+
for (const auto& sample : samples) {
4352+
CHECK(sample.is_live);
4353+
}
4354+
4355+
heap_profiler->StopSamplingHeapProfiler();
4356+
}
4357+
4358+
TEST(SamplingHeapProfilerSampleIsLive) {
4359+
v8::HandleScope scope(CcTest::isolate());
4360+
LocalContext env;
4361+
v8::HeapProfiler* heap_profiler = env.isolate()->GetHeapProfiler();
4362+
4363+
// Suppress randomness to avoid flakiness in tests.
4364+
i::v8_flags.sampling_heap_profiler_suppress_randomness = true;
4365+
4366+
heap_profiler->StartSamplingHeapProfiler(
4367+
64, 16,
4368+
static_cast<v8::HeapProfiler::SamplingFlags>(
4369+
v8::HeapProfiler::kSamplingForceGC |
4370+
v8::HeapProfiler::kSamplingIncludeObjectsCollectedByMajorGC));
4371+
4372+
// Allocate objects that will be retained
4373+
CompileRun(
4374+
"var retained = [];\n"
4375+
"for (var i = 0; i < 500; i++) retained.push(new Array(10));\n");
4376+
4377+
CompileRun("for (var i = 0; i < 500; i++) new Array(10);\n");
4378+
4379+
std::unique_ptr<v8::AllocationProfile> profile(
4380+
heap_profiler->GetAllocationProfile());
4381+
CHECK(profile);
4382+
4383+
const auto& samples = profile->GetSamples();
4384+
CHECK(!samples.empty());
4385+
4386+
int live_samples = 0;
4387+
int dead_samples = 0;
4388+
for (const auto& sample : samples) {
4389+
if (sample.is_live) {
4390+
++live_samples;
4391+
} else {
4392+
++dead_samples;
4393+
}
4394+
}
4395+
4396+
// We expect both retained and collected allocations in this profile.
4397+
CHECK_GT(live_samples, 0);
4398+
CHECK_GT(dead_samples, 0);
4399+
4400+
heap_profiler->StopSamplingHeapProfiler();
4401+
}
4402+
43274403
TEST(HeapSnapshotPrototypeNotJSReceiver) {
43284404
LocalContext env;
43294405
v8::HandleScope scope(env.isolate());

0 commit comments

Comments
 (0)