From c688a0b2db1504a1da63678b35881438ad908f9a Mon Sep 17 00:00:00 2001 From: Chris Kennelly Date: Thu, 10 Sep 2026 12:30:02 -0700 Subject: [PATCH] Eliminate an unnecessary clock check for unsampled trackers. Last allocation time is only used for sampled page trackers. We also augment the existing test to cover a sampled get/put sequence. PiperOrigin-RevId: 979331505 --- tcmalloc/huge_page_filler.h | 4 ++-- tcmalloc/huge_page_filler_test.cc | 39 ++++++++++++++++++++++++++++++- 2 files changed, 40 insertions(+), 3 deletions(-) diff --git a/tcmalloc/huge_page_filler.h b/tcmalloc/huge_page_filler.h index b79ab51f2..329206b0d 100644 --- a/tcmalloc/huge_page_filler.h +++ b/tcmalloc/huge_page_filler.h @@ -1233,11 +1233,11 @@ HugePageFiller::TryGet(Length n, SpanAllocInfo span_alloc_info) { TC_ASSERT(type == AccessDensityPrediction::kSparse || pt->HasDenseSpans()); // Log previous features before modifying the page tracker. - const auto now = clock_.now(); if (pt->GetTagState().sampled_for_tagging) { + const auto now = clock_.now(); pt->RecordFeatures(); + pt->SetLastAllocationTime(now); } - pt->SetLastAllocationTime(now); const auto page_allocation = pt->Get(n, span_alloc_info); AddToFillerList(pt); pages_allocated_[type] += n; diff --git a/tcmalloc/huge_page_filler_test.cc b/tcmalloc/huge_page_filler_test.cc index 02b2bb924..986c5e9f4 100644 --- a/tcmalloc/huge_page_filler_test.cc +++ b/tcmalloc/huge_page_filler_test.cc @@ -714,7 +714,7 @@ TEST_F(FillerTest, ClockCalls) { page2 = res.page; } EXPECT_EQ(alloc_pt, pt); - EXPECT_EQ(FakeClock::now_calls(), 2); + EXPECT_EQ(FakeClock::now_calls(), 1); EXPECT_EQ(FakeClock::freq_calls(), 0); // 3. Put (partially freed hugepage). @@ -741,6 +741,43 @@ TEST_F(FillerTest, ClockCalls) { EXPECT_EQ(FakeClock::now_calls(), 2); EXPECT_EQ(FakeClock::freq_calls(), 1); + // 5. Contribute and wait for pt to be sampled. + while (true) { + PageHeapSpinLockHolder l; + page1 = pt->Get(Length(1), info).page; + filler_.Contribute(pt, /*donated=*/false, info); + if (pt->GetTagState().sampled_for_tagging) { + break; + } + filler_.Put(pt, Range(page1, Length(1)), info); + } + + FakeClock::ResetCalls(); + + { + PageHeapSpinLockHolder l; + auto res = filler_.TryGet(Length(1), info); + alloc_pt = res.pt; + page2 = res.page; + } + + EXPECT_EQ(alloc_pt, pt); + EXPECT_EQ(FakeClock::now_calls(), 2); + EXPECT_EQ(FakeClock::freq_calls(), 0); + + FakeClock::ResetCalls(); + + { + PageHeapSpinLockHolder l; + put_res1 = filler_.Put(alloc_pt, Range(page2, Length(1)), info); + put_res2 = filler_.Put(pt, Range(page1, Length(1)), info); + } + + EXPECT_EQ(put_res1, nullptr); + EXPECT_EQ(put_res2, pt); + EXPECT_EQ(FakeClock::now_calls(), 3); + EXPECT_EQ(FakeClock::freq_calls(), 1); + delete pt; }