diff options
author | Michaël Zasso <targos@protonmail.com> | 2022-10-11 09:04:31 +0200 |
---|---|---|
committer | Node.js GitHub Bot <github-bot@iojs.org> | 2022-10-13 06:49:33 +0000 |
commit | 690a837f4fb62f6b9dd52a48c80d3ceccfcc580b (patch) | |
tree | fd9ee046ac841c4e96b152533e8358fde6846c59 /deps/v8/src | |
parent | bab8b3aad68bc5e105bc803ed8546d5a13d37339 (diff) | |
download | node-new-690a837f4fb62f6b9dd52a48c80d3ceccfcc580b.tar.gz |
deps: V8: cherry-pick 3d59a3c2c164
Original commit message:
Add option to report discarded allocations in sampling heap profiler
A couple of customers have asked about using devtools to get information
about temporary allocations, with the goal of reducing GC time and/or
peak memory usage. Currently, the sampling heap profiler reports only
objects which are still alive at the end of the profiling session. In
this change, I propose adding configuration options when starting the
sampling heap profiler so that it can optionally include information
about objects which were discarded by the GC before the end of the
profiling session. A user could run the sampling heap profiler in
several different modes depending on their goals:
1. To find memory leaks or determine which functions contribute most to
steady-state memory consumption, the current default mode is best.
2. To find functions which cause large temporary memory spikes or large
GC pauses, the user can request data about both live objects and
those collected by major GC.
3. To tune for minimal GC activity in latency-sensitive applications
like real-time audio processing, the user can request data about
every allocation, including objects collected by major or minor GC.
4. I'm not sure why anybody would want data about objects collected by
minor GC and not objects collected by major GC, but it's also a valid
flags combination.
Change-Id: If55d5965a1de04fed3ae640a02ca369723f64fdf
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3868522
Reviewed-by: Michael Lippautz <mlippautz@chromium.org>
Reviewed-by: Camillo Bruni <cbruni@chromium.org>
Reviewed-by: Simon Zünd <szuend@chromium.org>
Commit-Queue: Seth Brenith <seth.brenith@microsoft.com>
Cr-Commit-Position: refs/heads/main@{#83202}
Refs: https://github.com/v8/v8/commit/3d59a3c2c16405eea59263300c5591c3283a2a0e
PR-URL: https://github.com/nodejs/node/pull/44958
Reviewed-By: Jiawen Geng <technicalcute@gmail.com>
Reviewed-By: Beth Griggs <bethanyngriggs@gmail.com>
Reviewed-By: Rafael Gonzaga <rafael.nunu@hotmail.com>
Reviewed-By: Richard Lau <rlau@redhat.com>
Diffstat (limited to 'deps/v8/src')
-rw-r--r-- | deps/v8/src/heap/heap.cc | 2 | ||||
-rw-r--r-- | deps/v8/src/heap/heap.h | 6 | ||||
-rw-r--r-- | deps/v8/src/inspector/v8-heap-profiler-agent-impl.cc | 26 | ||||
-rw-r--r-- | deps/v8/src/inspector/v8-heap-profiler-agent-impl.h | 4 | ||||
-rw-r--r-- | deps/v8/src/profiler/sampling-heap-profiler.cc | 13 |
5 files changed, 47 insertions, 4 deletions
diff --git a/deps/v8/src/heap/heap.cc b/deps/v8/src/heap/heap.cc index 5a307ff9e1..d966d979c8 100644 --- a/deps/v8/src/heap/heap.cc +++ b/deps/v8/src/heap/heap.cc @@ -1819,6 +1819,8 @@ bool Heap::CollectGarbage(AllocationSpace space, collector = SelectGarbageCollector(space, gc_reason, &collector_reason); + current_or_last_garbage_collector_ = collector; + if (collector == GarbageCollector::MARK_COMPACTOR && incremental_marking()->IsMinorMarking()) { CollectGarbage(NEW_SPACE, GarbageCollectionReason::kFinalizeMinorMC); diff --git a/deps/v8/src/heap/heap.h b/deps/v8/src/heap/heap.h index daca783901..6e270f246d 100644 --- a/deps/v8/src/heap/heap.h +++ b/deps/v8/src/heap/heap.h @@ -1455,6 +1455,10 @@ class Heap { bool is_current_gc_forced() const { return is_current_gc_forced_; } + GarbageCollector current_or_last_garbage_collector() const { + return current_or_last_garbage_collector_; + } + // Returns whether the currently in-progress GC should avoid increasing the // ages on any objects that live for a set number of collections. bool ShouldCurrentGCKeepAgesUnchanged() const { @@ -2389,6 +2393,8 @@ class Heap { bool is_current_gc_forced_ = false; bool is_current_gc_for_heap_profiler_ = false; + GarbageCollector current_or_last_garbage_collector_ = + GarbageCollector::SCAVENGER; ExternalStringTable external_string_table_; diff --git a/deps/v8/src/inspector/v8-heap-profiler-agent-impl.cc b/deps/v8/src/inspector/v8-heap-profiler-agent-impl.cc index 13dfd69bbe..4e8197fdec 100644 --- a/deps/v8/src/inspector/v8-heap-profiler-agent-impl.cc +++ b/deps/v8/src/inspector/v8-heap-profiler-agent-impl.cc @@ -29,6 +29,7 @@ static const char allocationTrackingEnabled[] = "allocationTrackingEnabled"; static const char samplingHeapProfilerEnabled[] = "samplingHeapProfilerEnabled"; static const char samplingHeapProfilerInterval[] = "samplingHeapProfilerInterval"; +static const char samplingHeapProfilerFlags[] = "samplingHeapProfilerFlags"; } // namespace HeapProfilerAgentState class HeapSnapshotProgress final : public v8::ActivityControl { @@ -208,7 +209,16 @@ void V8HeapProfilerAgentImpl::restore() { double samplingInterval = m_state->doubleProperty( HeapProfilerAgentState::samplingHeapProfilerInterval, -1); DCHECK_GE(samplingInterval, 0); - startSampling(Maybe<double>(samplingInterval)); + int flags = m_state->integerProperty( + HeapProfilerAgentState::samplingHeapProfilerFlags, 0); + startSampling( + Maybe<double>(samplingInterval), + Maybe<bool>( + flags & + v8::HeapProfiler::kSamplingIncludeObjectsCollectedByMajorGC), + Maybe<bool>( + flags & + v8::HeapProfiler::kSamplingIncludeObjectsCollectedByMinorGC)); } } @@ -387,7 +397,9 @@ void V8HeapProfilerAgentImpl::stopTrackingHeapObjectsInternal() { } Response V8HeapProfilerAgentImpl::startSampling( - Maybe<double> samplingInterval) { + Maybe<double> samplingInterval, + Maybe<bool> includeObjectsCollectedByMajorGC, + Maybe<bool> includeObjectsCollectedByMinorGC) { v8::HeapProfiler* profiler = m_isolate->GetHeapProfiler(); if (!profiler) return Response::ServerError("Cannot access v8 heap profiler"); const unsigned defaultSamplingInterval = 1 << 15; @@ -400,9 +412,17 @@ Response V8HeapProfilerAgentImpl::startSampling( samplingIntervalValue); m_state->setBoolean(HeapProfilerAgentState::samplingHeapProfilerEnabled, true); + int flags = v8::HeapProfiler::kSamplingForceGC; + if (includeObjectsCollectedByMajorGC.fromMaybe(false)) { + flags |= v8::HeapProfiler::kSamplingIncludeObjectsCollectedByMajorGC; + } + if (includeObjectsCollectedByMinorGC.fromMaybe(false)) { + flags |= v8::HeapProfiler::kSamplingIncludeObjectsCollectedByMinorGC; + } + m_state->setInteger(HeapProfilerAgentState::samplingHeapProfilerFlags, flags); profiler->StartSamplingHeapProfiler( static_cast<uint64_t>(samplingIntervalValue), 128, - v8::HeapProfiler::kSamplingForceGC); + static_cast<v8::HeapProfiler::SamplingFlags>(flags)); return Response::Success(); } diff --git a/deps/v8/src/inspector/v8-heap-profiler-agent-impl.h b/deps/v8/src/inspector/v8-heap-profiler-agent-impl.h index 0387a006b8..61c6b6af53 100644 --- a/deps/v8/src/inspector/v8-heap-profiler-agent-impl.h +++ b/deps/v8/src/inspector/v8-heap-profiler-agent-impl.h @@ -56,7 +56,9 @@ class V8HeapProfilerAgentImpl : public protocol::HeapProfiler::Backend { Response getHeapObjectId(const String16& objectId, String16* heapSnapshotObjectId) override; - Response startSampling(Maybe<double> samplingInterval) override; + Response startSampling(Maybe<double> samplingInterval, + Maybe<bool> includeObjectsCollectedByMajorGC, + Maybe<bool> includeObjectsCollectedByMinorGC) override; Response stopSampling( std::unique_ptr<protocol::HeapProfiler::SamplingHeapProfile>*) override; Response getSamplingProfile( diff --git a/deps/v8/src/profiler/sampling-heap-profiler.cc b/deps/v8/src/profiler/sampling-heap-profiler.cc index 45c72ec202..b38d235e98 100644 --- a/deps/v8/src/profiler/sampling-heap-profiler.cc +++ b/deps/v8/src/profiler/sampling-heap-profiler.cc @@ -95,6 +95,19 @@ void SamplingHeapProfiler::SampleObject(Address soon_object, size_t size) { void SamplingHeapProfiler::OnWeakCallback( const WeakCallbackInfo<Sample>& data) { Sample* sample = data.GetParameter(); + Heap* heap = reinterpret_cast<Isolate*>(data.GetIsolate())->heap(); + bool is_minor_gc = + heap->current_or_last_garbage_collector() == GarbageCollector::SCAVENGER; + bool should_keep_sample = + is_minor_gc + ? (sample->profiler->flags_ & + v8::HeapProfiler::kSamplingIncludeObjectsCollectedByMinorGC) + : (sample->profiler->flags_ & + v8::HeapProfiler::kSamplingIncludeObjectsCollectedByMajorGC); + if (should_keep_sample) { + sample->global.Reset(); + return; + } AllocationNode* node = sample->owner; DCHECK_GT(node->allocations_[sample->size], 0); node->allocations_[sample->size]--; |