mirror of
https://github.com/python/cpython.git
synced 2026-06-05 01:10:53 +00:00
gh-149584: Fix excessive overhead in the Tachyon profiler regarding the cache behavior (#149649)
Use exact remote reads for interpreter state, thread state, and interpreter frame structs instead of pulling full remote pages into the profiler page cache. This matches the core change from python/cpython#149585. The profiler clears the page cache between samples, so live entries are always packed at the front. Track the live count and only clear/search that prefix instead of scanning all 1024 slots on the hot path. Use the frame cache to predict the next thread state and top frame address, then batch interpreter/thread/frame reads with process_vm_readv when profiling a Linux target. Reuse prefetched frame buffers in the frame walker when the prediction is valid. Cache the last FrameInfo tuple per code object/instruction offset, reuse cached thread id objects, and append cached parent frames directly on full frame-cache hits. This cuts Python allocation churn in the steady-state profiler path.
This commit is contained in:
parent
06a2830aa8
commit
661df25692
12 changed files with 739 additions and 127 deletions
|
|
@ -405,6 +405,8 @@ parse_code_object(RemoteUnwinderObject *unwinder,
|
|||
meta->func_name = func;
|
||||
meta->file_name = file;
|
||||
meta->linetable = linetable;
|
||||
meta->last_frame_info = NULL;
|
||||
meta->last_addrq = -1;
|
||||
meta->first_lineno = GET_MEMBER(int, code_object, unwinder->debug_offsets.code_object.firstlineno);
|
||||
meta->addr_code_adaptive = real_address + (uintptr_t)unwinder->debug_offsets.code_object.co_code_adaptive;
|
||||
|
||||
|
|
@ -482,6 +484,12 @@ parse_code_object(RemoteUnwinderObject *unwinder,
|
|||
addrq = (uint16_t *)ip - (uint16_t *)meta->addr_code_adaptive;
|
||||
#endif
|
||||
; // Empty statement to avoid C23 extension warning
|
||||
|
||||
if (!unwinder->opcodes && meta->last_frame_info != NULL && meta->last_addrq == addrq) {
|
||||
*result = Py_NewRef(meta->last_frame_info);
|
||||
return 0;
|
||||
}
|
||||
|
||||
LocationInfo info = {0};
|
||||
bool ok = parse_linetable(addrq, PyBytes_AS_STRING(meta->linetable),
|
||||
PyBytes_GET_SIZE(meta->linetable),
|
||||
|
|
@ -529,6 +537,11 @@ parse_code_object(RemoteUnwinderObject *unwinder,
|
|||
goto error;
|
||||
}
|
||||
|
||||
if (!unwinder->opcodes) {
|
||||
Py_XSETREF(meta->last_frame_info, Py_NewRef(tuple));
|
||||
meta->last_addrq = addrq;
|
||||
}
|
||||
|
||||
*result = tuple;
|
||||
return 0;
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue