mirror of
https://github.com/python/cpython.git
synced 2026-05-04 09:31:02 +00:00
141 lines
3.9 KiB
C
141 lines
3.9 KiB
C
#include "Python.h"
|
|
|
|
#include "pycore_ceval.h"
|
|
#include "pycore_jit_publish.h"
|
|
#include "pycore_jit_unwind.h"
|
|
|
|
#ifdef _Py_JIT
|
|
|
|
#if defined(PY_HAVE_JIT_GDB_UNWIND) \
|
|
|| defined(PY_HAVE_JIT_GNU_BACKTRACE_UNWIND)
|
|
struct _PyJitCodeRegistration {
|
|
# if defined(PY_HAVE_JIT_GDB_UNWIND)
|
|
void *gdb_handle;
|
|
# endif
|
|
# if defined(PY_HAVE_JIT_GNU_BACKTRACE_UNWIND)
|
|
void *gnu_backtrace_handle;
|
|
# endif
|
|
};
|
|
#endif
|
|
|
|
static void
|
|
jit_register_perf_code(const void *code_addr, size_t code_size,
|
|
const char *entry, const char *filename)
|
|
{
|
|
#ifdef PY_HAVE_PERF_TRAMPOLINE
|
|
_PyPerf_Callbacks callbacks;
|
|
_PyPerfTrampoline_GetCallbacks(&callbacks);
|
|
if (callbacks.write_state == _Py_perfmap_jit_callbacks.write_state) {
|
|
_PyPerfJit_WriteNamedCode(
|
|
code_addr, code_size, entry, filename);
|
|
}
|
|
#else
|
|
(void)code_addr;
|
|
(void)code_size;
|
|
(void)entry;
|
|
(void)filename;
|
|
#endif
|
|
}
|
|
|
|
#if defined(PY_HAVE_JIT_GDB_UNWIND)
|
|
static void
|
|
jit_register_gdb_code(_PyJitCodeRegistration *registration,
|
|
const void *code_addr, size_t code_size,
|
|
const char *entry, const char *filename)
|
|
{
|
|
registration->gdb_handle = _PyJitUnwind_GdbRegisterCode(
|
|
code_addr, code_size, entry, filename);
|
|
}
|
|
|
|
static void
|
|
jit_unregister_gdb_code(_PyJitCodeRegistration *registration)
|
|
{
|
|
if (registration->gdb_handle != NULL) {
|
|
_PyJitUnwind_GdbUnregisterCode(registration->gdb_handle);
|
|
registration->gdb_handle = NULL;
|
|
}
|
|
}
|
|
#endif
|
|
|
|
#if defined(PY_HAVE_JIT_GNU_BACKTRACE_UNWIND)
|
|
static void
|
|
jit_register_gnu_backtrace_code(_PyJitCodeRegistration *registration,
|
|
const void *code_addr, size_t code_size)
|
|
{
|
|
registration->gnu_backtrace_handle =
|
|
_PyJitUnwind_GnuBacktraceRegisterCode(code_addr, code_size);
|
|
}
|
|
|
|
static void
|
|
jit_unregister_gnu_backtrace_code(_PyJitCodeRegistration *registration)
|
|
{
|
|
if (registration->gnu_backtrace_handle != NULL) {
|
|
_PyJitUnwind_GnuBacktraceUnregisterCode(
|
|
registration->gnu_backtrace_handle);
|
|
registration->gnu_backtrace_handle = NULL;
|
|
}
|
|
}
|
|
#endif
|
|
|
|
_PyJitCodeRegistration *
|
|
_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)
|
|
return NULL;
|
|
#else
|
|
_PyJitCodeRegistration *registration = PyMem_RawCalloc(
|
|
1, sizeof(*registration));
|
|
if (registration == NULL) {
|
|
return NULL;
|
|
}
|
|
|
|
// 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);
|
|
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);
|
|
any_registered |= registration->gnu_backtrace_handle != NULL;
|
|
# endif
|
|
if (!any_registered) {
|
|
PyMem_RawFree(registration);
|
|
return NULL;
|
|
}
|
|
return registration;
|
|
#endif
|
|
}
|
|
|
|
void
|
|
_PyJit_UnregisterCode(_PyJitCodeRegistration *registration)
|
|
{
|
|
#if !defined(PY_HAVE_JIT_GDB_UNWIND) \
|
|
&& !defined(PY_HAVE_JIT_GNU_BACKTRACE_UNWIND)
|
|
assert(registration == NULL);
|
|
(void)registration;
|
|
#else
|
|
if (registration == NULL) {
|
|
return;
|
|
}
|
|
|
|
# if defined(PY_HAVE_JIT_GNU_BACKTRACE_UNWIND)
|
|
jit_unregister_gnu_backtrace_code(registration);
|
|
# endif
|
|
# if defined(PY_HAVE_JIT_GDB_UNWIND)
|
|
jit_unregister_gdb_code(registration);
|
|
# endif
|
|
PyMem_RawFree(registration);
|
|
#endif
|
|
}
|
|
|
|
#endif // _Py_JIT
|