diff --git a/common.gypi b/common.gypi index c58aa7fd89305d..e487df802ed108 100644 --- a/common.gypi +++ b/common.gypi @@ -38,7 +38,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.13', + 'v8_embedder_string': '-node.14', ##### V8 defaults for Node.js ##### diff --git a/deps/v8/AUTHORS b/deps/v8/AUTHORS index 96d5b843d2badf..c261e03d2ea4cc 100644 --- a/deps/v8/AUTHORS +++ b/deps/v8/AUTHORS @@ -155,6 +155,7 @@ Huáng Jùnliàng HyeockJin Kim Iain Ireland Ilya Gavrilin +Ilyas Shabi Ingvar Stepanyan Ioseb Dzmanashvili Isiah Meadows diff --git a/deps/v8/include/v8-profiler.h b/deps/v8/include/v8-profiler.h index 61f427ea47c691..53b2a77e5226cc 100644 --- a/deps/v8/include/v8-profiler.h +++ b/deps/v8/include/v8-profiler.h @@ -811,6 +811,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; }; /** diff --git a/deps/v8/src/profiler/sampling-heap-profiler.cc b/deps/v8/src/profiler/sampling-heap-profiler.cc index 8133dec033b9fb..68bf4c11fb171a 100644 --- a/deps/v8/src/profiler/sampling-heap-profiler.cc +++ b/deps/v8/src/profiler/sampling-heap-profiler.cc @@ -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; } diff --git a/deps/v8/test/cctest/test-heap-profiler.cc b/deps/v8/test/cctest/test-heap-profiler.cc index 4dbb3fc7604344..926ed1f6a1abf2 100644 --- a/deps/v8/test/cctest/test-heap-profiler.cc +++ b/deps/v8/test/cctest/test-heap-profiler.cc @@ -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 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::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 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());