Skip to content

Commit 05799a7

Browse files
author
Pablo Galindo Salgado
committed
fixup! small cleanp
1 parent d576d38 commit 05799a7

2 files changed

Lines changed: 34 additions & 8 deletions

File tree

Modules/_remote_debugging/_remote_debugging.h

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -242,6 +242,7 @@ typedef struct {
242242
typedef struct {
243243
uintptr_t interpreter_addr;
244244
uintptr_t thread_state_addr;
245+
uint64_t code_object_generation;
245246
} InterpreterThreadCacheEntry;
246247

247248
// Carries already-read thread state and/or frame buffers across helpers so the
@@ -288,7 +289,8 @@ typedef struct {
288289
#define STATS_ADD(unwinder, field, val) \
289290
do { if (REMOTE_DEBUG_UNLIKELY((unwinder)->collect_stats)) (unwinder)->stats.field += (val); } while(0)
290291

291-
#define STATS_BATCHED_READ(unwinder, requested, completed) \
292+
#if HAVE_PROCESS_VM_READV
293+
# define STATS_BATCHED_READ(unwinder, requested, completed) \
292294
do { \
293295
if (REMOTE_DEBUG_UNLIKELY((unwinder)->collect_stats)) { \
294296
(unwinder)->stats.batched_read_attempts++; \
@@ -302,6 +304,9 @@ typedef struct {
302304
} \
303305
} \
304306
} while(0)
307+
#else
308+
# define STATS_BATCHED_READ(unwinder, requested, completed) ((void)0)
309+
#endif
305310

306311
typedef struct {
307312
PyTypeObject *RemoteDebugging_Type;
@@ -342,7 +347,6 @@ typedef struct {
342347
struct _Py_AsyncioModuleDebugOffsets async_debug_offsets;
343348
uintptr_t interpreter_addr;
344349
uintptr_t tstate_addr;
345-
uint64_t code_object_generation;
346350
_Py_hashtable_t *code_object_cache;
347351
int debug;
348352
int only_active_thread;
@@ -355,9 +359,11 @@ typedef struct {
355359
int collect_stats; // whether to collect statistics
356360
uint32_t stale_invalidation_counter; // counter for throttling frame_cache_invalidate_stale
357361
// L1 single-entry shortcut over cached_tstates[]: most workloads sample one
358-
// interpreter, so check this pair before hashing into the table below.
362+
// interpreter, so check these pairs before hashing into the table below.
359363
uintptr_t cached_tstate_interpreter_addr;
360364
uintptr_t cached_tstate_addr;
365+
uintptr_t cached_generation_interpreter_addr;
366+
uint64_t cached_code_object_generation;
361367
RemoteDebuggingState *cached_state;
362368
FrameCacheEntry *frame_cache; // preallocated array of FRAME_CACHE_MAX_THREADS entries
363369
UnwinderStats stats; // statistics for performance analysis

Modules/_remote_debugging/module.c

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -532,14 +532,34 @@ set_cached_tstate_for_interpreter(
532532
static void
533533
refresh_generation_caches_from_interp_state(
534534
RemoteUnwinderObject *self,
535+
uintptr_t interpreter_addr,
535536
const char *interp_state_buffer)
536537
{
537538
uint64_t code_object_generation = GET_MEMBER(uint64_t, interp_state_buffer,
538539
self->debug_offsets.interpreter_state.code_object_generation);
539540

540-
if (code_object_generation != self->code_object_generation) {
541-
self->code_object_generation = code_object_generation;
542-
_Py_hashtable_clear(self->code_object_cache);
541+
if (self->cached_generation_interpreter_addr == interpreter_addr) {
542+
if (code_object_generation != self->cached_code_object_generation) {
543+
self->cached_code_object_generation = code_object_generation;
544+
_Py_hashtable_clear(self->code_object_cache);
545+
}
546+
}
547+
else {
548+
InterpreterThreadCacheEntry *entry =
549+
&self->cached_tstates[interpreter_thread_cache_index(interpreter_addr)];
550+
uint64_t prev_generation = 0;
551+
if (entry->interpreter_addr == interpreter_addr) {
552+
prev_generation = entry->code_object_generation;
553+
}
554+
else {
555+
entry->interpreter_addr = interpreter_addr;
556+
}
557+
entry->code_object_generation = code_object_generation;
558+
if (code_object_generation != prev_generation) {
559+
_Py_hashtable_clear(self->code_object_cache);
560+
}
561+
self->cached_generation_interpreter_addr = interpreter_addr;
562+
self->cached_code_object_generation = code_object_generation;
543563
}
544564

545565
#ifdef Py_GIL_DISABLED
@@ -567,7 +587,7 @@ refresh_generation_caches_for_interpreter(
567587
"Failed to read interpreter state buffer");
568588
return -1;
569589
}
570-
refresh_generation_caches_from_interp_state(self, interp_state_buffer);
590+
refresh_generation_caches_from_interp_state(self, interpreter_addr, interp_state_buffer);
571591
return 0;
572592
}
573593

@@ -712,7 +732,7 @@ _remote_debugging_RemoteUnwinder_get_stack_trace_impl(RemoteUnwinderObject *self
712732
Py_CLEAR(result);
713733
goto exit;
714734
}
715-
refresh_generation_caches_from_interp_state(self, interp_state_buffer);
735+
refresh_generation_caches_from_interp_state(self, current_interpreter, interp_state_buffer);
716736

717737
uintptr_t gc_frame = 0;
718738
if (self->gc) {

0 commit comments

Comments
 (0)