Skip to content

Commit d576d38

Browse files
committed
small cleanp
1 parent 2995187 commit d576d38

4 files changed

Lines changed: 25 additions & 20 deletions

File tree

Lib/profiling/sampling/sample.py

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -296,18 +296,14 @@ def _print_unwinder_stats(self):
296296
print(f" Hits: {code_hits:n} ({ANSIColors.GREEN}{fmt(code_hits_pct)}%{ANSIColors.RESET})")
297297
print(f" Misses: {code_misses:n} ({ANSIColors.RED}{fmt(code_misses_pct)}%{ANSIColors.RESET})")
298298

299-
# Batched remote read stats
300299
batched_attempts = stats.get('batched_read_attempts', 0)
301300
batched_successes = stats.get('batched_read_successes', 0)
302301
batched_misses = stats.get('batched_read_misses', 0)
303302
segments_requested = stats.get('batched_read_segments_requested', 0)
304303
segments_completed = stats.get('batched_read_segments_completed', 0)
305-
if batched_attempts > 0 or segments_requested > 0:
304+
if batched_attempts > 0:
306305
batched_success_rate = stats.get('batched_read_success_rate', 0.0)
307-
batched_miss_rate = (
308-
(batched_misses / batched_attempts * 100)
309-
if batched_attempts > 0 else 0
310-
)
306+
batched_miss_rate = 100.0 - batched_success_rate
311307
segment_completion_rate = stats.get(
312308
'batched_read_segment_completion_rate', 0.0
313309
)

Modules/_remote_debugging/_remote_debugging.h

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -244,6 +244,10 @@ typedef struct {
244244
uintptr_t thread_state_addr;
245245
} InterpreterThreadCacheEntry;
246246

247+
// Carries already-read thread state and/or frame buffers across helpers so the
248+
// downstream callee can skip a remote read. Address fields are caller-supplied
249+
// inputs; buffer pointers (tstate, frame) are NULL unless a prior batched read
250+
// successfully populated them.
247251
typedef struct {
248252
const char *tstate;
249253
uintptr_t tstate_addr;
@@ -350,8 +354,10 @@ typedef struct {
350354
int cache_frames;
351355
int collect_stats; // whether to collect statistics
352356
uint32_t stale_invalidation_counter; // counter for throttling frame_cache_invalidate_stale
353-
uintptr_t cached_tstate_interpreter_addr; // hot last-interpreter prediction
354-
uintptr_t cached_tstate_addr; // hot first-thread prediction
357+
// L1 single-entry shortcut over cached_tstates[]: most workloads sample one
358+
// interpreter, so check this pair before hashing into the table below.
359+
uintptr_t cached_tstate_interpreter_addr;
360+
uintptr_t cached_tstate_addr;
355361
RemoteDebuggingState *cached_state;
356362
FrameCacheEntry *frame_cache; // preallocated array of FRAME_CACHE_MAX_THREADS entries
357363
UnwinderStats stats; // statistics for performance analysis

Modules/_remote_debugging/module.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -477,7 +477,7 @@ _remote_debugging_RemoteUnwinder___init___impl(RemoteUnwinderObject *self,
477477
return 0;
478478
}
479479

480-
static size_t
480+
static inline size_t
481481
interpreter_thread_cache_index(uintptr_t interpreter_addr)
482482
{
483483
// Direct-mapped table indexed by the remote interpreter address. Each entry
@@ -487,7 +487,7 @@ interpreter_thread_cache_index(uintptr_t interpreter_addr)
487487
& (INTERPRETER_THREAD_CACHE_SIZE - 1);
488488
}
489489

490-
static uintptr_t
490+
static inline uintptr_t
491491
get_cached_tstate_for_interpreter(
492492
RemoteUnwinderObject *self,
493493
uintptr_t interpreter_addr)
@@ -510,7 +510,7 @@ get_cached_tstate_for_interpreter(
510510
return 0;
511511
}
512512

513-
static void
513+
static inline void
514514
set_cached_tstate_for_interpreter(
515515
RemoteUnwinderObject *self,
516516
uintptr_t interpreter_addr,
@@ -759,7 +759,7 @@ _remote_debugging_RemoteUnwinder_get_stack_trace_impl(RemoteUnwinderObject *self
759759
// Target specific thread (only process first interpreter)
760760
current_tstate = self->tstate_addr;
761761
}
762-
if (current_tstate != 0) {
762+
if (current_tstate != 0 && self->cache_frames) {
763763
set_cached_tstate_for_interpreter(self, current_interpreter, current_tstate);
764764
}
765765

Modules/_remote_debugging/threads.c

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -338,11 +338,12 @@ unwind_stack_for_thread(
338338
PyObject *result = NULL;
339339
StackChunkList chunks = {0};
340340

341-
char ts[SIZEOF_THREAD_STATE];
341+
char local_ts[SIZEOF_THREAD_STATE];
342342
char local_prefetched_frame[SIZEOF_INTERP_FRAME];
343+
const char *ts;
343344
RemoteReadPrefetch ctx_prefetch = {0};
344345
if (prefetch->tstate && prefetch->tstate_addr == *current_tstate) {
345-
memcpy(ts, prefetch->tstate, (size_t)unwinder->debug_offsets.thread_state.size);
346+
ts = prefetch->tstate;
346347
if (prefetch->frame) {
347348
ctx_prefetch.frame = prefetch->frame;
348349
ctx_prefetch.frame_addr = prefetch->frame_addr;
@@ -356,33 +357,35 @@ unwind_stack_for_thread(
356357
predicted_frame_addr = entry->addrs[0];
357358
}
358359

359-
int bytes_read = read_thread_state_and_maybe_frame(
360+
int rc = read_thread_state_and_maybe_frame(
360361
unwinder,
361362
*current_tstate,
362363
(size_t)unwinder->debug_offsets.thread_state.size,
363-
ts,
364+
local_ts,
364365
predicted_frame_addr,
365366
local_prefetched_frame,
366367
&have_prefetched_frame);
367-
if (bytes_read < 0) {
368+
if (rc < 0) {
368369
set_exception_cause(unwinder, PyExc_RuntimeError, "Failed to read thread state");
369370
goto error;
370371
}
372+
ts = local_ts;
371373
if (have_prefetched_frame) {
372374
ctx_prefetch.frame = local_prefetched_frame;
373375
ctx_prefetch.frame_addr = predicted_frame_addr;
374376
}
375377
}
376378
else {
377-
int bytes_read = _Py_RemoteDebug_ReadRemoteMemory(
379+
int rc = _Py_RemoteDebug_ReadRemoteMemory(
378380
&unwinder->handle,
379381
*current_tstate,
380382
(size_t)unwinder->debug_offsets.thread_state.size,
381-
ts);
382-
if (bytes_read < 0) {
383+
local_ts);
384+
if (rc < 0) {
383385
set_exception_cause(unwinder, PyExc_RuntimeError, "Failed to read thread state");
384386
goto error;
385387
}
388+
ts = local_ts;
386389
}
387390
STATS_INC(unwinder, memory_reads);
388391
STATS_ADD(unwinder, memory_bytes_read, unwinder->debug_offsets.thread_state.size);

0 commit comments

Comments
 (0)