diff --git a/Misc/NEWS.d/next/Library/2026-10-10-13-35-08.gh-issue-149584.Yq2bF7.rst b/Misc/NEWS.d/next/Library/2026-10-10-13-35-08.gh-issue-149584.Yq2bF7.rst new file mode 100644 index 000000000000000..7f92a1b19877cd4 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2026-10-10-13-35-08.gh-issue-149584.Yq2bF7.rst @@ -0,0 +1,2 @@ +Improve the performance of the Tachyon profiler by avoiding unnecessary remote +reads of the base frame sentinel. Patch by Maurycy Pawłowski-Wieroński. diff --git a/Modules/_remote_debugging/frame_cache.c b/Modules/_remote_debugging/frame_cache.c index 1b2d9a60f408b91..63d1331015a548d 100644 --- a/Modules/_remote_debugging/frame_cache.c +++ b/Modules/_remote_debugging/frame_cache.c @@ -318,9 +318,8 @@ frame_cache_store( // Validate we have a complete stack before caching. // Only cache if last_frame_visited matches base_frame_addr (the sentinel // at the bottom of the stack). Note: we use last_frame_visited rather than - // addrs[num_addrs-1] because the base frame is visited but not added to the - // addrs array (it returns frame==NULL from is_frame_valid due to - // owner==FRAME_OWNED_BY_INTERPRETER). + // addrs[num_addrs-1] because the base frame's address is not added to the + // addrs array. if (base_frame_addr != 0 && last_frame_visited != base_frame_addr) { // Incomplete stack - don't cache (graceful degradation) return 0; diff --git a/Modules/_remote_debugging/frames.c b/Modules/_remote_debugging/frames.c index f5b9ed72f1f98e9..268939b6f77a20c 100644 --- a/Modules/_remote_debugging/frames.c +++ b/Modules/_remote_debugging/frames.c @@ -326,6 +326,14 @@ process_frame_chain( } assert(frame_count <= MAX_FRAME_CHAIN_DEPTH); + // The base frame is a sentinel with previous == NULL: reaching it is + // enough, no need to read it. Still read it when it is the GC frame + // so the marker gets emitted. + if (frame_addr == ctx->base_frame_addr + && !(unwinder->gc && frame_addr == ctx->gc_frame)) { + break; + } + if (ctx->chunks && ctx->chunks->count > 0) { parse_result = parse_frame_from_chunks( unwinder, &frame, frame_addr, &next_frame_addr, &stackpointer, ctx->chunks);