-
-
Notifications
You must be signed in to change notification settings - Fork 34.6k
Expand file tree
/
Copy pathjit_publish.c
More file actions
137 lines (123 loc) · 3.75 KB
/
jit_publish.c
File metadata and controls
137 lines (123 loc) · 3.75 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
#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 {
void *gdb_handle;
void *gnu_backtrace_handle;
};
#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