diff options
author | gsallam <123525874+gsallam@users.noreply.github.com> | 2023-10-26 20:57:29 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-10-27 03:57:29 +0000 |
commit | 21f068d80c6cc5de75f9df70fdd733d0ce9c70de (patch) | |
tree | daceefb593efea137dd642df968075b24c6d52f8 /Python/perf_trampoline.c | |
parent | 3d2f1f0b830d86f16f42c42b54d3ea4453dac318 (diff) | |
download | cpython-21f068d80c6cc5de75f9df70fdd733d0ce9c70de.tar.gz cpython-21f068d80c6cc5de75f9df70fdd733d0ce9c70de.zip |
gh-109587: Allow "precompiled" perf-trampolines to largely mitigate the cost of enabling perf-trampolines (#109666)
Diffstat (limited to 'Python/perf_trampoline.c')
-rw-r--r-- | Python/perf_trampoline.c | 50 |
1 files changed, 44 insertions, 6 deletions
diff --git a/Python/perf_trampoline.c b/Python/perf_trampoline.c index 209a23b6c1c..491223924ed 100644 --- a/Python/perf_trampoline.c +++ b/Python/perf_trampoline.c @@ -193,7 +193,7 @@ typedef struct trampoline_api_st trampoline_api_t; #define perf_code_arena _PyRuntime.ceval.perf.code_arena #define trampoline_api _PyRuntime.ceval.perf.trampoline_api #define perf_map_file _PyRuntime.ceval.perf.map_file - +#define persist_after_fork _PyRuntime.ceval.perf.persist_after_fork static void perf_map_write_entry(void *state, const void *code_addr, @@ -361,6 +361,26 @@ default_eval: } #endif // PY_HAVE_PERF_TRAMPOLINE +int PyUnstable_PerfTrampoline_CompileCode(PyCodeObject *co) +{ +#ifdef PY_HAVE_PERF_TRAMPOLINE + py_trampoline f = NULL; + assert(extra_code_index != -1); + int ret = _PyCode_GetExtra((PyObject *)co, extra_code_index, (void **)&f); + if (ret != 0 || f == NULL) { + py_trampoline new_trampoline = compile_trampoline(); + if (new_trampoline == NULL) { + return 0; + } + trampoline_api.write_state(trampoline_api.state, new_trampoline, + perf_code_arena->code_size, co); + return _PyCode_SetExtra((PyObject *)co, extra_code_index, + (void *)new_trampoline); + } +#endif // PY_HAVE_PERF_TRAMPOLINE + return 0; +} + int _PyIsPerfTrampolineActive(void) { @@ -448,16 +468,34 @@ _PyPerfTrampoline_Fini(void) return 0; } +int +PyUnstable_PerfTrampoline_SetPersistAfterFork(int enable){ +#ifdef PY_HAVE_PERF_TRAMPOLINE + persist_after_fork = enable; + return persist_after_fork; +#endif + return 0; +} + PyStatus _PyPerfTrampoline_AfterFork_Child(void) { #ifdef PY_HAVE_PERF_TRAMPOLINE - // Restart trampoline in file in child. - int was_active = _PyIsPerfTrampolineActive(); - _PyPerfTrampoline_Fini(); PyUnstable_PerfMapState_Fini(); - if (was_active) { - _PyPerfTrampoline_Init(1); + if (persist_after_fork) { + char filename[256]; + pid_t parent_pid = getppid(); + snprintf(filename, sizeof(filename), "/tmp/perf-%d.map", parent_pid); + if (PyUnstable_CopyPerfMapFile(filename) != 0) { + return PyStatus_Error("Failed to copy perf map file."); + } + } else { + // Restart trampoline in file in child. + int was_active = _PyIsPerfTrampolineActive(); + _PyPerfTrampoline_Fini(); + if (was_active) { + _PyPerfTrampoline_Init(1); + } } #endif return PyStatus_Ok(); |