From 091638dc9528b86a2d9b7ea173afba32a0374f80 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ralph=20K=C3=BCpper?= Date: Sun, 13 Sep 2026 15:27:37 +0200 Subject: [PATCH 1/2] fix(json): route the traversal-feedback counters through the hot thread-local cache The thread-local policy ratchet allows no raw thread_local! in the runtime; #10150 declared json/traversal_feedback.rs's two counters with one. Both now use crate::perry_thread_local!, with unchanged call sites. --- crates/perry-runtime/src/json/traversal_feedback.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/crates/perry-runtime/src/json/traversal_feedback.rs b/crates/perry-runtime/src/json/traversal_feedback.rs index f3017b0305..55f3ea2d2f 100644 --- a/crates/perry-runtime/src/json/traversal_feedback.rs +++ b/crates/perry-runtime/src/json/traversal_feedback.rs @@ -40,9 +40,8 @@ const SCORE_MAX: u8 = 8; /// the evidence keeps being refreshed. const RESAMPLE_EVERY: u8 = 16; -// Two byte counters read once per parse: plain `thread_local!`, not the hot-TLS -// macro, and no heap pointer can live in either. -thread_local! { +// Two byte counters read once per parse. No heap pointer can live in either. +crate::perry_thread_local! { static SCORE: Cell = const { Cell::new(0) }; static EAGER_RUN: Cell = const { Cell::new(0) }; } From 388e83a74227be8ec58ae34c23b67c5168f261a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ralph=20K=C3=BCpper?= Date: Sun, 13 Sep 2026 15:27:43 +0200 Subject: [PATCH 2/2] docs(changelog): fragment for #10203 --- changelog.d/10203-traversal-feedback-hot-tls.md | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 changelog.d/10203-traversal-feedback-hot-tls.md diff --git a/changelog.d/10203-traversal-feedback-hot-tls.md b/changelog.d/10203-traversal-feedback-hot-tls.md new file mode 100644 index 0000000000..a0a93a3d17 --- /dev/null +++ b/changelog.d/10203-traversal-feedback-hot-tls.md @@ -0,0 +1,3 @@ +### fix(json): route the traversal-feedback counters through the hot thread-local cache + +`json/traversal_feedback.rs` declared its two per-thread counters with a raw `thread_local!`, which the thread-local policy ratchet (`scripts/check_thread_locals.py`) rejects; they now use `crate::perry_thread_local!` like every other runtime declaration, so the per-parse read lands in the hot TLS cache instead of a `_tlv_get_addr` call.