Skip to content

Commit 92e6252

Browse files
committed
gh-151436: Add macro for last_profiled_frame updates
1 parent 4c94653 commit 92e6252

7 files changed

Lines changed: 23 additions & 47 deletions

File tree

Include/internal/pycore_interpframe.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -287,6 +287,15 @@ _PyThreadState_GetFrame(PyThreadState *tstate)
287287
return _PyFrame_GetFirstComplete(tstate->current_frame);
288288
}
289289

290+
#define _PyThreadState_UpdateLastProfiledFrame(tstate, frame, previous) \
291+
do { \
292+
PyThreadState *tstate_ = (tstate); \
293+
_PyInterpreterFrame *frame_ = (frame); \
294+
if (tstate_->last_profiled_frame == frame_) { \
295+
tstate_->last_profiled_frame = (previous); \
296+
} \
297+
} while (0)
298+
290299
/* For use by _PyFrame_GetFrameObject
291300
Do not call directly. */
292301
PyAPI_FUNC(PyFrameObject *)

Modules/_testinternalcapi/test_cases.c.h

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

Objects/genobject.c

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -681,9 +681,7 @@ _gen_throw(PyGenObject *gen, int close_on_genexit,
681681
'yield from' or awaiting on with 'await'. */
682682
ret = _gen_throw((PyGenObject *)yf, close_on_genexit,
683683
typ, val, tb);
684-
if (tstate->last_profiled_frame == frame) {
685-
tstate->last_profiled_frame = prev;
686-
}
684+
_PyThreadState_UpdateLastProfiledFrame(tstate, frame, prev);
687685
tstate->current_frame = prev;
688686
frame->previous = NULL;
689687
}
@@ -704,9 +702,7 @@ _gen_throw(PyGenObject *gen, int close_on_genexit,
704702
frame->previous = prev;
705703
tstate->current_frame = frame;
706704
ret = PyObject_CallFunctionObjArgs(meth, typ, val, tb, NULL);
707-
if (tstate->last_profiled_frame == frame) {
708-
tstate->last_profiled_frame = prev;
709-
}
705+
_PyThreadState_UpdateLastProfiledFrame(tstate, frame, prev);
710706
tstate->current_frame = prev;
711707
frame->previous = NULL;
712708
Py_DECREF(meth);

Python/bytecodes.c

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1860,9 +1860,7 @@ dummy_func(
18601860
gen->gi_exc_state.previous_item = NULL;
18611861
_Py_LeaveRecursiveCallPy(tstate);
18621862
_PyInterpreterFrame *gen_frame = frame;
1863-
if (tstate->last_profiled_frame == gen_frame) {
1864-
tstate->last_profiled_frame = gen_frame->previous;
1865-
}
1863+
_PyThreadState_UpdateLastProfiledFrame(tstate, gen_frame, gen_frame->previous);
18661864
frame = tstate->current_frame = frame->previous;
18671865
gen_frame->previous = NULL;
18681866
((_PyThreadStateImpl *)tstate)->generator_return_kind = GENERATOR_YIELD;
@@ -5877,9 +5875,7 @@ dummy_func(
58775875
gen_frame->owner = FRAME_OWNED_BY_GENERATOR;
58785876
_Py_LeaveRecursiveCallPy(tstate);
58795877
_PyInterpreterFrame *prev = frame->previous;
5880-
if (tstate->last_profiled_frame == frame) {
5881-
tstate->last_profiled_frame = prev;
5882-
}
5878+
_PyThreadState_UpdateLastProfiledFrame(tstate, frame, prev);
58835879
_PyThreadState_PopFrame(tstate, frame);
58845880
frame = tstate->current_frame = prev;
58855881
LOAD_IP(frame->return_offset);

Python/ceval.c

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1972,15 +1972,8 @@ clear_gen_frame(PyThreadState *tstate, _PyInterpreterFrame * frame)
19721972
void
19731973
_PyEval_FrameClearAndPop(PyThreadState *tstate, _PyInterpreterFrame * frame)
19741974
{
1975-
// Update last_profiled_frame for remote profiler frame caching.
19761975
// By this point, tstate->current_frame is already set to the parent frame.
1977-
// Only update if we're popping the exact frame that was last profiled.
1978-
// This avoids corrupting the cache when transient frames (called and returned
1979-
// between profiler samples) update last_profiled_frame to addresses the
1980-
// profiler never saw.
1981-
if (tstate->last_profiled_frame != NULL && tstate->last_profiled_frame == frame) {
1982-
tstate->last_profiled_frame = tstate->current_frame;
1983-
}
1976+
_PyThreadState_UpdateLastProfiledFrame(tstate, frame, tstate->current_frame);
19841977

19851978
if (frame->owner == FRAME_OWNED_BY_THREAD) {
19861979
clear_thread_frame(tstate, frame);
@@ -2006,9 +1999,7 @@ _PyEvalFramePushAndInit(PyThreadState *tstate, _PyStackRef func,
20061999
_PyFrame_Initialize(tstate, frame, func, locals, code, 0, previous);
20072000
if (initialize_locals(tstate, func_obj, frame->localsplus, args, argcount, kwnames)) {
20082001
assert(frame->owner == FRAME_OWNED_BY_THREAD);
2009-
if (tstate->last_profiled_frame == frame) {
2010-
tstate->last_profiled_frame = tstate->current_frame;
2011-
}
2002+
_PyThreadState_UpdateLastProfiledFrame(tstate, frame, tstate->current_frame);
20122003
clear_thread_frame(tstate, frame);
20132004
return NULL;
20142005
}

Python/executor_cases.c.h

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

Python/generated_cases.c.h

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

0 commit comments

Comments
 (0)