Skip to content

Commit 40bc704

Browse files
committed
Add perf trampoline support for macOS
1 parent 77fa7a4 commit 40bc704

File tree

4 files changed

+38
-5
lines changed

4 files changed

+38
-5
lines changed

Python/asm_trampoline.S

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,21 @@
11
.text
2+
#if defined(__APPLE__)
3+
.globl __Py_trampoline_func_start
4+
#else
25
.globl _Py_trampoline_func_start
6+
#endif
37
# The following assembly is equivalent to:
48
# PyObject *
59
# trampoline(PyThreadState *ts, _PyInterpreterFrame *f,
610
# int throwflag, py_evaluator evaluator)
711
# {
812
# return evaluator(ts, f, throwflag);
913
# }
14+
#if defined(__APPLE__)
15+
__Py_trampoline_func_start:
16+
#else
1017
_Py_trampoline_func_start:
18+
#endif
1119
#ifdef __x86_64__
1220
#if defined(__CET__) && (__CET__ & 1)
1321
endbr64
@@ -34,9 +42,14 @@ _Py_trampoline_func_start:
3442
addi sp,sp,16
3543
jr ra
3644
#endif
45+
#if defined(__APPLE__)
46+
.globl __Py_trampoline_func_end
47+
__Py_trampoline_func_end:
48+
#else
3749
.globl _Py_trampoline_func_end
3850
_Py_trampoline_func_end:
3951
.section .note.GNU-stack,"",@progbits
52+
#endif
4053
# Note for indicating the assembly code supports CET
4154
#if defined(__x86_64__) && defined(__CET__) && (__CET__ & 1)
4255
.section .note.gnu.property,"a"

Python/perf_jit_trampoline.c

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -66,15 +66,19 @@
6666
#ifdef PY_HAVE_PERF_TRAMPOLINE
6767

6868
/* Standard library includes for perf jitdump implementation */
69-
#include <elf.h> // ELF architecture constants
69+
#if defined(__linux__)
70+
# include <elf.h> // ELF architecture constants
71+
#endif
7072
#include <fcntl.h> // File control operations
7173
#include <stdio.h> // Standard I/O operations
7274
#include <stdlib.h> // Standard library functions
7375
#include <sys/mman.h> // Memory mapping functions (mmap)
7476
#include <sys/types.h> // System data types
7577
#include <unistd.h> // System calls (sysconf, getpid)
7678
#include <sys/time.h> // Time functions (gettimeofday)
77-
#include <sys/syscall.h> // System call interface
79+
#if defined(__linux__)
80+
# include <sys/syscall.h> // System call interface
81+
#endif
7882

7983
// =============================================================================
8084
// CONSTANTS AND CONFIGURATION
@@ -102,6 +106,15 @@
102106
*/
103107
#define PERF_JIT_CODE_PADDING 0x100
104108

109+
110+
/* These constants are defined inside <elf.h>, which we can't use outside of linux. */
111+
#if !defined(__linux__)
112+
# define EM_386 3
113+
# define EM_ARM 40
114+
# define EM_AARCH64 183
115+
# define EM_RISCV 243
116+
#endif
117+
105118
/* Convenient access to the global trampoline API state */
106119
#define trampoline_api _PyRuntime.ceval.perf.trampoline_api
107120

@@ -195,7 +208,7 @@ struct BaseEvent {
195208
typedef struct {
196209
struct BaseEvent base; // Common event header
197210
uint32_t process_id; // Process ID where code was generated
198-
uint32_t thread_id; // Thread ID where code was generated
211+
uint64_t thread_id; // Thread ID where code was generated
199212
uint64_t vma; // Virtual memory address where code is loaded
200213
uint64_t code_address; // Address of the actual machine code
201214
uint64_t code_size; // Size of the machine code in bytes
@@ -1166,7 +1179,11 @@ static void perf_map_jit_write_entry(void *state, const void *code_addr,
11661179
ev.base.size = sizeof(ev) + (name_length+1) + size;
11671180
ev.base.time_stamp = get_current_monotonic_ticks();
11681181
ev.process_id = getpid();
1182+
#if defined(__APPLE__)
1183+
pthread_threadid_np(NULL, &ev.thread_id);
1184+
#else
11691185
ev.thread_id = syscall(SYS_gettid); // Get thread ID via system call
1186+
#endif
11701187
ev.vma = base; // Virtual memory address
11711188
ev.code_address = base; // Same as VMA for our use case
11721189
ev.code_size = size;
@@ -1262,4 +1279,4 @@ _PyPerf_Callbacks _Py_perfmap_jit_callbacks = {
12621279
&perf_map_jit_fini, // Cleanup function
12631280
};
12641281

1265-
#endif /* PY_HAVE_PERF_TRAMPOLINE */
1282+
#endif /* PY_HAVE_PERF_TRAMPOLINE */

configure

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

configure.ac

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3690,12 +3690,13 @@ case "$ac_sys_system" in
36903690
esac
36913691
AC_MSG_RESULT([$SHLIBS])
36923692

3693-
dnl perf trampoline is Linux specific and requires an arch-specific
3693+
dnl perf trampoline is Linux and macOS specific and requires an arch-specific
36943694
dnl trampoline in assembly.
36953695
AC_MSG_CHECKING([perf trampoline])
36963696
AS_CASE([$PLATFORM_TRIPLET],
36973697
[x86_64-linux-gnu], [perf_trampoline=yes],
36983698
[aarch64-linux-gnu], [perf_trampoline=yes],
3699+
[darwin], [perf_trampoline=yes],
36993700
[perf_trampoline=no]
37003701
)
37013702
AC_MSG_RESULT([$perf_trampoline])

0 commit comments

Comments
 (0)