diff --git a/common.gypi b/common.gypi index 9fc77e9445cb..b1bae4999b26 100644 --- a/common.gypi +++ b/common.gypi @@ -44,7 +44,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.15', + 'v8_embedder_string': '-node.16', ##### V8 defaults for Node.js ##### diff --git a/deps/v8/AUTHORS b/deps/v8/AUTHORS index ee6d6af3a38d..182bc5358591 100644 --- a/deps/v8/AUTHORS +++ b/deps/v8/AUTHORS @@ -79,6 +79,7 @@ Artem Kobzar Arthur Islamov Asuka Shikina Aurèle Barrière +Austin Burdine Aviv Keller Ayako Hayasaka Bala Avulapati diff --git a/deps/v8/src/heap/gc-tracer.h b/deps/v8/src/heap/gc-tracer.h index 453ab94e4b14..ffa5d7d0e68e 100644 --- a/deps/v8/src/heap/gc-tracer.h +++ b/deps/v8/src/heap/gc-tracer.h @@ -692,6 +692,7 @@ class V8_EXPORT_PRIVATE GCTracer { FRIEND_TEST(GCTracerTest, BackgroundMajorMCScope); FRIEND_TEST(GCTracerTest, CyclePriorities); FRIEND_TEST(GCTracerTest, EmbedderAllocationThroughput); + FRIEND_TEST(GCTracerTest, HighAllocationRateWithEmbedderAllocation); FRIEND_TEST(GCTracerTest, MultithreadedBackgroundScope); FRIEND_TEST(GCTracerTest, NewSpaceAllocationThroughput); FRIEND_TEST(GCTracerTest, PerGenerationAllocationThroughput); @@ -700,6 +701,7 @@ class V8_EXPORT_PRIVATE GCTracer { FRIEND_TEST(GCTracerTest, IncrementalMarkingDetails); FRIEND_TEST(GCTracerTest, IncrementalScope); FRIEND_TEST(GCTracerTest, IncrementalMarkingSpeed); + FRIEND_TEST(GCTracerTest, LowAllocationRateWithZeroEmbedderAllocation); FRIEND_TEST(GCTracerTest, MutatorUtilization); FRIEND_TEST(GCTracerTest, RecordMarkCompactHistograms); FRIEND_TEST(GCTracerTest, RecordScavengerHistograms); diff --git a/deps/v8/src/heap/heap.cc b/deps/v8/src/heap/heap.cc index d67b6933c72a..c3e69804cf75 100644 --- a/deps/v8/src/heap/heap.cc +++ b/deps/v8/src/heap/heap.cc @@ -3492,9 +3492,7 @@ namespace { double ComputeMutatorUtilizationImpl(double mutator_speed, std::optional gc_speed) { - constexpr double kMinMutatorUtilization = 0.0; constexpr double kConservativeGcSpeedInBytesPerMillisecond = 200000; - if (mutator_speed == 0) return kMinMutatorUtilization; if (!gc_speed) gc_speed = kConservativeGcSpeedInBytesPerMillisecond; // Derivation: // mutator_utilization = mutator_time / (mutator_time + gc_time) diff --git a/deps/v8/src/heap/heap.h b/deps/v8/src/heap/heap.h index 810449851fec..9d7aeed3f215 100644 --- a/deps/v8/src/heap/heap.h +++ b/deps/v8/src/heap/heap.h @@ -687,7 +687,7 @@ class Heap final { // null. V8_INLINE bool CanSafepoint() const { return deserialization_complete(); } - bool HasLowAllocationRate(); + V8_EXPORT_PRIVATE bool HasLowAllocationRate(); bool HasHighFragmentation(); void ActivateMemoryReducerIfNeeded(); diff --git a/deps/v8/test/unittests/heap/gc-tracer-unittest.cc b/deps/v8/test/unittests/heap/gc-tracer-unittest.cc index bcde0440e28f..563ad1de160a 100644 --- a/deps/v8/test/unittests/heap/gc-tracer-unittest.cc +++ b/deps/v8/test/unittests/heap/gc-tracer-unittest.cc @@ -180,6 +180,45 @@ TEST_F(GCTracerTest, PerGenerationAllocationThroughput) { tracer->ExternalAllocationThroughputInBytesPerMillisecond())); } +TEST_F(GCTracerTest, LowAllocationRateWithZeroEmbedderAllocation) { + if (v8_flags.stress_incremental_marking) return; + Heap* heap = i_isolate()->heap(); + GCTracer* tracer = heap->tracer(); + tracer->ResetForTesting(); + tracer->allocation_time_ = base::TimeTicks(); + + // Two samples 100 ms apart. Young and old generation allocate a little; + // the embedder (CppHeap) and external memory allocate nothing at all, as + // in an embedder that never uses cppgc (e.g. Node.js without node:vm). + tracer->SampleAllocation(base::TimeTicks::FromMsTicksForTesting(0), 0, 0, 0, + 0); + tracer->SampleAllocation(base::TimeTicks::FromMsTicksForTesting(100), 100, + 100, 0, 0); + + EXPECT_DOUBLE_EQ(0.0, + tracer->EmbedderAllocationThroughputInBytesPerMillisecond()); + EXPECT_TRUE(heap->HasLowAllocationRate()); +} + +TEST_F(GCTracerTest, HighAllocationRateWithEmbedderAllocation) { + if (v8_flags.stress_incremental_marking) return; + Heap* heap = i_isolate()->heap(); + GCTracer* tracer = heap->tracer(); + tracer->ResetForTesting(); + tracer->allocation_time_ = base::TimeTicks(); + + // Same as above, but the embedder allocates heavily: 1 GB over 100 ms is + // ~10^7 B/ms, so the embedder term must still report a high allocation + // rate (mu = 200000 / (10^7 + 200000) < 0.993). + tracer->SampleAllocation(base::TimeTicks::FromMsTicksForTesting(0), 0, 0, 0, + 0); + tracer->SampleAllocation(base::TimeTicks::FromMsTicksForTesting(100), 100, + 100, size_t{1} << 30, 0); + + EXPECT_GT(tracer->EmbedderAllocationThroughputInBytesPerMillisecond(), 0.0); + EXPECT_FALSE(heap->HasLowAllocationRate()); +} + TEST_F(GCTracerTest, RegularScope) { if (v8_flags.stress_incremental_marking) return; GCTracer* tracer = i_isolate()->heap()->tracer();