mirror of
https://github.com/python/cpython.git
synced 2025-08-22 17:55:18 +00:00
gh-109587: Allow "precompiled" perf-trampolines to largely mitigate the cost of enabling perf-trampolines (#109666)
This commit is contained in:
parent
3d2f1f0b83
commit
21f068d80c
8 changed files with 199 additions and 10 deletions
|
@ -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();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue