Skip to content

Commit 81d5d59

Browse files
committed
deps: V8: cherry-pick 2444c109f4f8
Original commit message: [heap] Treat zero allocation throughput as a low allocation rate Since https://crrev.com/c/5935313 allocation throughput is tracked with SmoothedBytesAndDuration, which has no lower bound. A sampled throughput of exactly 0 -- nothing was allocated, or the smoothed value decayed to 0 after a long idle period -- made ComputeMutatorUtilizationImpl() return a mutator utilization of 0 ("maximal allocation"). For an isolate that never allocates on the CppHeap, HasLowAllocationRate() is then never true and the MemoryReducer cannot start a GC through its low-allocation condition; only the 100s watchdog can. Node.js hits this for any process that does not use node:vm. Remove the special case. A mutator speed of 0 now yields a mutator utilization of 1, i.e. the lowest possible allocation rate. gc_speed is either the conservative default or at least 1 byte/ms, so the formula stays well defined. Bug: 570738027 Change-Id: I84cd51607df3c31c2f1e02bb2fe258e5506131ce Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/8521518 Reviewed-by: Dominik Inführ <dinfuehr@chromium.org> Commit-Queue: Dominik Inführ <dinfuehr@chromium.org> Reviewed-by: Omer Katz <omerkatz@chromium.org> Commit-Queue: Omer Katz <omerkatz@chromium.org> Cr-Commit-Position: refs/heads/main@{#110599} Refs: v8/v8@2444c10 Fixes: #66564
1 parent a7a96c2 commit 81d5d59

6 files changed

Lines changed: 44 additions & 4 deletions

File tree

‎common.gypi‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@
4444

4545
# Reset this number to 0 on major V8 upgrades.
4646
# Increment by one for each non-official patch applied to deps/v8.
47-
'v8_embedder_string': '-node.15',
47+
'v8_embedder_string': '-node.16',
4848

4949
##### V8 defaults for Node.js #####
5050

‎deps/v8/AUTHORS‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ Artem Kobzar <artem.kobzar@jetbrains.com>
7979
Arthur Islamov <arthur@islamov.ai>
8080
Asuka Shikina <shikina.asuka@gmail.com>
8181
Aurèle Barrière <aurele.barriere@gmail.com>
82+
Austin Burdine <austin@ghost.org>
8283
Aviv Keller <me@aviv.sh>
8384
Ayako Hayasaka <a.iwasaki0128@gmail.com>
8485
Bala Avulapati <bavulapati@gmail.com>

‎deps/v8/src/heap/gc-tracer.h‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -692,6 +692,7 @@ class V8_EXPORT_PRIVATE GCTracer {
692692
FRIEND_TEST(GCTracerTest, BackgroundMajorMCScope);
693693
FRIEND_TEST(GCTracerTest, CyclePriorities);
694694
FRIEND_TEST(GCTracerTest, EmbedderAllocationThroughput);
695+
FRIEND_TEST(GCTracerTest, HighAllocationRateWithEmbedderAllocation);
695696
FRIEND_TEST(GCTracerTest, MultithreadedBackgroundScope);
696697
FRIEND_TEST(GCTracerTest, NewSpaceAllocationThroughput);
697698
FRIEND_TEST(GCTracerTest, PerGenerationAllocationThroughput);
@@ -700,6 +701,7 @@ class V8_EXPORT_PRIVATE GCTracer {
700701
FRIEND_TEST(GCTracerTest, IncrementalMarkingDetails);
701702
FRIEND_TEST(GCTracerTest, IncrementalScope);
702703
FRIEND_TEST(GCTracerTest, IncrementalMarkingSpeed);
704+
FRIEND_TEST(GCTracerTest, LowAllocationRateWithZeroEmbedderAllocation);
703705
FRIEND_TEST(GCTracerTest, MutatorUtilization);
704706
FRIEND_TEST(GCTracerTest, RecordMarkCompactHistograms);
705707
FRIEND_TEST(GCTracerTest, RecordScavengerHistograms);

‎deps/v8/src/heap/heap.cc‎

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3492,9 +3492,7 @@ namespace {
34923492

34933493
double ComputeMutatorUtilizationImpl(double mutator_speed,
34943494
std::optional<double> gc_speed) {
3495-
constexpr double kMinMutatorUtilization = 0.0;
34963495
constexpr double kConservativeGcSpeedInBytesPerMillisecond = 200000;
3497-
if (mutator_speed == 0) return kMinMutatorUtilization;
34983496
if (!gc_speed) gc_speed = kConservativeGcSpeedInBytesPerMillisecond;
34993497
// Derivation:
35003498
// mutator_utilization = mutator_time / (mutator_time + gc_time)

‎deps/v8/src/heap/heap.h‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -687,7 +687,7 @@ class Heap final {
687687
// null.
688688
V8_INLINE bool CanSafepoint() const { return deserialization_complete(); }
689689

690-
bool HasLowAllocationRate();
690+
V8_EXPORT_PRIVATE bool HasLowAllocationRate();
691691
bool HasHighFragmentation();
692692

693693
void ActivateMemoryReducerIfNeeded();

‎deps/v8/test/unittests/heap/gc-tracer-unittest.cc‎

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,45 @@ TEST_F(GCTracerTest, PerGenerationAllocationThroughput) {
180180
tracer->ExternalAllocationThroughputInBytesPerMillisecond()));
181181
}
182182

183+
TEST_F(GCTracerTest, LowAllocationRateWithZeroEmbedderAllocation) {
184+
if (v8_flags.stress_incremental_marking) return;
185+
Heap* heap = i_isolate()->heap();
186+
GCTracer* tracer = heap->tracer();
187+
tracer->ResetForTesting();
188+
tracer->allocation_time_ = base::TimeTicks();
189+
190+
// Two samples 100 ms apart. Young and old generation allocate a little;
191+
// the embedder (CppHeap) and external memory allocate nothing at all, as
192+
// in an embedder that never uses cppgc (e.g. Node.js without node:vm).
193+
tracer->SampleAllocation(base::TimeTicks::FromMsTicksForTesting(0), 0, 0, 0,
194+
0);
195+
tracer->SampleAllocation(base::TimeTicks::FromMsTicksForTesting(100), 100,
196+
100, 0, 0);
197+
198+
EXPECT_DOUBLE_EQ(0.0,
199+
tracer->EmbedderAllocationThroughputInBytesPerMillisecond());
200+
EXPECT_TRUE(heap->HasLowAllocationRate());
201+
}
202+
203+
TEST_F(GCTracerTest, HighAllocationRateWithEmbedderAllocation) {
204+
if (v8_flags.stress_incremental_marking) return;
205+
Heap* heap = i_isolate()->heap();
206+
GCTracer* tracer = heap->tracer();
207+
tracer->ResetForTesting();
208+
tracer->allocation_time_ = base::TimeTicks();
209+
210+
// Same as above, but the embedder allocates heavily: 1 GB over 100 ms is
211+
// ~10^7 B/ms, so the embedder term must still report a high allocation
212+
// rate (mu = 200000 / (10^7 + 200000) < 0.993).
213+
tracer->SampleAllocation(base::TimeTicks::FromMsTicksForTesting(0), 0, 0, 0,
214+
0);
215+
tracer->SampleAllocation(base::TimeTicks::FromMsTicksForTesting(100), 100,
216+
100, size_t{1} << 30, 0);
217+
218+
EXPECT_GT(tracer->EmbedderAllocationThroughputInBytesPerMillisecond(), 0.0);
219+
EXPECT_FALSE(heap->HasLowAllocationRate());
220+
}
221+
183222
TEST_F(GCTracerTest, RegularScope) {
184223
if (v8_flags.stress_incremental_marking) return;
185224
GCTracer* tracer = i_isolate()->heap()->tracer();

0 commit comments

Comments
 (0)