Clarify JIT publication registration semantics

This commit is contained in:
Diego Russo 2026-05-03 01:41:58 +01:00
parent 01df23912b
commit cf16da06e2
2 changed files with 15 additions and 7 deletions

View file

@ -11,9 +11,13 @@ typedef struct _PyJitCodeRegistration _PyJitCodeRegistration;
#ifdef _Py_JIT
/* Return a teardown handle when any backend stores registration state.
* A NULL result is valid when publication succeeded only through backends
* with no unregister step, such as perf map output.
/* Publish JIT code to optional tooling backends.
*
* The return value is a backend-specific deregistration handle, not a
* success/failure indicator. NULL means there is nothing to unregister later:
* perf does not need a handle, and GDB/GNU backtrace registration failures
* are intentionally non-fatal because tooling support must not make JIT
* compilation fail.
*/
_PyJitCodeRegistration *_PyJit_RegisterCode(const void *code_addr,
size_t code_size,

View file

@ -82,6 +82,8 @@ _PyJit_RegisterCode(const void *code_addr, size_t code_size,
const char *entry, const char *filename)
{
jit_register_perf_code(code_addr, code_size, entry, filename);
// Perf publication has no teardown handle, so it is intentionally
// not counted below.
#if !defined(PY_HAVE_JIT_GDB_UNWIND) \
&& !defined(PY_HAVE_JIT_GNU_BACKTRACE_UNWIND)
@ -93,18 +95,20 @@ _PyJit_RegisterCode(const void *code_addr, size_t code_size,
return NULL;
}
int registered = 0;
// Partial failures are non-fatal: the JIT code can still execute, but
// unavailable tooling may not be able to unwind it.
int any_registered = 0;
# if defined(PY_HAVE_JIT_GDB_UNWIND)
jit_register_gdb_code(
registration, code_addr, code_size, entry, filename);
registered |= registration->gdb_handle != NULL;
any_registered |= registration->gdb_handle != NULL;
# endif
# if defined(PY_HAVE_JIT_GNU_BACKTRACE_UNWIND)
jit_register_gnu_backtrace_code(
registration, code_addr, code_size);
registered |= registration->gnu_backtrace_handle != NULL;
any_registered |= registration->gnu_backtrace_handle != NULL;
# endif
if (!registered) {
if (!any_registered) {
PyMem_RawFree(registration);
return NULL;
}