deps: V8: cherry-pick 0f024d4e66e0

Original commit message:

    [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 <dinfuehr@chromium.org>
    Commit-Queue: Dominik Inführ <dinfuehr@chromium.org>
    Reviewed-by: Michael Lippautz <mlippautz@chromium.org>
    Cr-Commit-Position: refs/heads/main@{#105698}

Refs: https://github.com/v8/v8/commit/0f024d4e66e0edcb4a1370e47e2ba44686a28ac4
Signed-off-by: ishabi <ilyasshabi94@gmail.com>
PR-URL: https://github.com/nodejs/node/pull/62408
Reviewed-By: Stephen Belanger <admin@stephenbelanger.com>
Reviewed-By: Richard Lau <richard.lau@ibm.com>
Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de>
This commit is contained in:
ishabi authored and Bryan English committed 2026-04-28 10:15:47 -04:00
1 parent 746624951f
commit 8385efc013
5 files changed
+86 -2

No files matched your search

+1 -1
View File
@@ -40,7 +40,7 @@
# Reset this number to 0 on major V8 upgrades.
# Increment by one for each non-official patch applied to deps/v8.
'v8_embedder_string': '-node.18',
'v8_embedder_string': '-node.19',
##### V8 defaults for Node.js #####
+1
View File
@@ -155,6 +155,7 @@ Huáng Jùnliàng <jlhwung@gmail.com>
HyeockJin Kim <kherootz@gmail.com>
Iain Ireland <iireland@mozilla.com>
Ilya Gavrilin <ilya.gavrilin@syntacore.com>
Ilyas Shabi <ilyasshabi94@gmail.com>
Ingvar Stepanyan <me@rreverser.com>
Ioseb Dzmanashvili <ioseb.dzmanashvili@gmail.com>
Isiah Meadows <impinball@gmail.com>
+6
View File
@@ -830,6 +830,12 @@ class V8_EXPORT AllocationProfile {
* what samples were added or removed between two snapshots.
*/
uint64_t sample_id;
/**
* Indicates whether the sampled allocation is still live or has already
* been collected by GC.
*/
bool is_live;
};
/**
+2 -1
View File
@@ -312,9 +312,10 @@ SamplingHeapProfiler::BuildSamples() const {
samples.reserve(samples_.size());
for (const auto& it : samples_) {
const Sample* sample = it.second.get();
const bool is_live = !sample->global.IsEmpty();
samples.emplace_back(v8::AllocationProfile::Sample{
sample->owner->id_, sample->size, ScaleSample(sample->size, 1).count,
sample->sample_id});
sample->sample_id, is_live});
}
return samples;
}
+76
View File
@@ -4442,6 +4442,82 @@ TEST(SamplingHeapProfilerLargeInterval) {
heap_profiler->StopSamplingHeapProfiler();
}
TEST(SamplingHeapProfilerSampleWithoutGCFlags) {
v8::HandleScope scope(CcTest::isolate());
LocalContext env;
v8::HeapProfiler* heap_profiler = env.isolate()->GetHeapProfiler();
// Suppress randomness to avoid flakiness in tests.
i::v8_flags.sampling_heap_profiler_suppress_randomness = true;
heap_profiler->StartSamplingHeapProfiler(1024);
// Allocate objects that will be retained
CompileRun(
"var retained = [];\n"
"for (var i = 0; i < 500; i++) retained.push(new Array(10));\n");
CompileRun("for (var i = 0; i < 500; i++) new Array(10);\n");
std::unique_ptr<v8::AllocationProfile> profile(
heap_profiler->GetAllocationProfile());
CHECK(profile);
const auto& samples = profile->GetSamples();
CHECK(!samples.empty());
for (const auto& sample : samples) {
CHECK(sample.is_live);
}
heap_profiler->StopSamplingHeapProfiler();
}
TEST(SamplingHeapProfilerSampleIsLive) {
v8::HandleScope scope(CcTest::isolate());
LocalContext env;
v8::HeapProfiler* heap_profiler = env.isolate()->GetHeapProfiler();
// Suppress randomness to avoid flakiness in tests.
i::v8_flags.sampling_heap_profiler_suppress_randomness = true;
heap_profiler->StartSamplingHeapProfiler(
64, 16,
static_cast<v8::HeapProfiler::SamplingFlags>(
v8::HeapProfiler::kSamplingForceGC |
v8::HeapProfiler::kSamplingIncludeObjectsCollectedByMajorGC));
// Allocate objects that will be retained
CompileRun(
"var retained = [];\n"
"for (var i = 0; i < 500; i++) retained.push(new Array(10));\n");
CompileRun("for (var i = 0; i < 500; i++) new Array(10);\n");
std::unique_ptr<v8::AllocationProfile> profile(
heap_profiler->GetAllocationProfile());
CHECK(profile);
const auto& samples = profile->GetSamples();
CHECK(!samples.empty());
int live_samples = 0;
int dead_samples = 0;
for (const auto& sample : samples) {
if (sample.is_live) {
++live_samples;
} else {
++dead_samples;
}
}
// We expect both retained and collected allocations in this profile.
CHECK_GT(live_samples, 0);
CHECK_GT(dead_samples, 0);
heap_profiler->StopSamplingHeapProfiler();
}
TEST(HeapSnapshotPrototypeNotJSReceiver) {
LocalContext env;
v8::HandleScope scope(env.isolate());