gh-146031: Allow keeping specialization enabled when specifying eval frame function (#146032)

Allow keeping specialization enabled when specifying eval frame function
This commit is contained in:
Dino Viehland 2026-04-16 09:44:26 -07:00 committed by GitHub
parent cecf564073
commit c0af5c024b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
10 changed files with 196 additions and 20 deletions

View file

@ -220,14 +220,14 @@ do { \
DISPATCH_GOTO_NON_TRACING(); \
}
#define DISPATCH_INLINED(NEW_FRAME) \
do { \
assert(tstate->interp->eval_frame == NULL); \
_PyFrame_SetStackPointer(frame, stack_pointer); \
assert((NEW_FRAME)->previous == frame); \
frame = tstate->current_frame = (NEW_FRAME); \
CALL_STAT_INC(inlined_py_calls); \
JUMP_TO_LABEL(start_frame); \
#define DISPATCH_INLINED(NEW_FRAME) \
do { \
assert(!IS_PEP523_HOOKED(tstate)); \
_PyFrame_SetStackPointer(frame, stack_pointer); \
assert((NEW_FRAME)->previous == frame); \
frame = tstate->current_frame = (NEW_FRAME); \
CALL_STAT_INC(inlined_py_calls); \
JUMP_TO_LABEL(start_frame); \
} while (0)
/* Tuple access macros */

View file

@ -3026,9 +3026,32 @@ _PyInterpreterState_SetEvalFrameFunc(PyInterpreterState *interp,
RARE_EVENT_INC(set_eval_frame_func);
_PyEval_StopTheWorld(interp);
interp->eval_frame = eval_frame;
// reset when evaluator is reset
interp->eval_frame_allow_specialization = 0;
_PyEval_StartTheWorld(interp);
}
void
_PyInterpreterState_SetEvalFrameAllowSpecialization(PyInterpreterState *interp,
int allow_specialization)
{
if (allow_specialization == interp->eval_frame_allow_specialization) {
return;
}
_Py_Executors_InvalidateAll(interp, 1);
RARE_EVENT_INC(set_eval_frame_func);
_PyEval_StopTheWorld(interp);
interp->eval_frame_allow_specialization = allow_specialization;
_PyEval_StartTheWorld(interp);
}
int
_PyInterpreterState_IsSpecializationEnabled(PyInterpreterState *interp)
{
return interp->eval_frame == NULL
|| interp->eval_frame_allow_specialization;
}
const PyConfig*
_PyInterpreterState_GetConfig(PyInterpreterState *interp)

View file

@ -838,7 +838,7 @@ do_specialize_instance_load_attr(PyObject* owner, _Py_CODEUNIT* instr, PyObject*
return -1;
}
/* Don't specialize if PEP 523 is active */
if (_PyInterpreterState_GET()->eval_frame) {
if (!_PyInterpreterState_IsSpecializationEnabled(_PyInterpreterState_GET())) {
SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_OTHER);
return -1;
}
@ -922,7 +922,7 @@ do_specialize_instance_load_attr(PyObject* owner, _Py_CODEUNIT* instr, PyObject*
return -1;
}
/* Don't specialize if PEP 523 is active */
if (_PyInterpreterState_GET()->eval_frame) {
if (!_PyInterpreterState_IsSpecializationEnabled(_PyInterpreterState_GET())) {
SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_OTHER);
return -1;
}
@ -1740,7 +1740,7 @@ specialize_py_call(PyFunctionObject *func, _Py_CODEUNIT *instr, int nargs,
PyCodeObject *code = (PyCodeObject *)func->func_code;
int kind = function_kind(code);
/* Don't specialize if PEP 523 is active */
if (_PyInterpreterState_GET()->eval_frame) {
if (!_PyInterpreterState_IsSpecializationEnabled(_PyInterpreterState_GET())) {
SPECIALIZATION_FAIL(CALL, SPEC_FAIL_CALL_PEP_523);
return -1;
}
@ -1783,7 +1783,7 @@ specialize_py_call_kw(PyFunctionObject *func, _Py_CODEUNIT *instr, int nargs,
PyCodeObject *code = (PyCodeObject *)func->func_code;
int kind = function_kind(code);
/* Don't specialize if PEP 523 is active */
if (_PyInterpreterState_GET()->eval_frame) {
if (!_PyInterpreterState_IsSpecializationEnabled(_PyInterpreterState_GET())) {
SPECIALIZATION_FAIL(CALL, SPEC_FAIL_CALL_PEP_523);
return -1;
}
@ -2046,7 +2046,7 @@ binary_op_fail_kind(int oparg, PyObject *lhs, PyObject *rhs)
return SPEC_FAIL_WRONG_NUMBER_ARGUMENTS;
}
if (_PyInterpreterState_GET()->eval_frame) {
if (!_PyInterpreterState_IsSpecializationEnabled(_PyInterpreterState_GET())) {
/* Don't specialize if PEP 523 is active */
Py_DECREF(descriptor);
return SPEC_FAIL_OTHER;
@ -2449,7 +2449,7 @@ _Py_Specialize_BinaryOp(_PyStackRef lhs_st, _PyStackRef rhs_st, _Py_CODEUNIT *in
PyHeapTypeObject *ht = (PyHeapTypeObject *)container_type;
if (kind == SIMPLE_FUNCTION &&
fcode->co_argcount == 2 &&
!_PyInterpreterState_GET()->eval_frame && /* Don't specialize if PEP 523 is active */
_PyInterpreterState_IsSpecializationEnabled(_PyInterpreterState_GET()) && /* Don't specialize if PEP 523 is active */
_PyType_CacheGetItemForSpecialization(ht, descriptor, (uint32_t)tp_version))
{
specialize(instr, BINARY_OP_SUBSCR_GETITEM);
@ -2707,7 +2707,7 @@ _Py_Specialize_ForIter(_PyStackRef iter, _PyStackRef null_or_index, _Py_CODEUNIT
instr[oparg + INLINE_CACHE_ENTRIES_FOR_ITER + 1].op.code == INSTRUMENTED_END_FOR
);
/* Don't specialize if PEP 523 is active */
if (_PyInterpreterState_GET()->eval_frame) {
if (!_PyInterpreterState_IsSpecializationEnabled(_PyInterpreterState_GET())) {
goto failure;
}
specialize(instr, FOR_ITER_GEN);
@ -2750,7 +2750,7 @@ _Py_Specialize_Send(_PyStackRef receiver_st, _Py_CODEUNIT *instr)
PyTypeObject *tp = Py_TYPE(receiver);
if (tp == &PyGen_Type || tp == &PyCoro_Type) {
/* Don't specialize if PEP 523 is active */
if (_PyInterpreterState_GET()->eval_frame) {
if (!_PyInterpreterState_IsSpecializationEnabled(_PyInterpreterState_GET())) {
SPECIALIZATION_FAIL(SEND, SPEC_FAIL_OTHER);
goto failure;
}
@ -2773,7 +2773,7 @@ _Py_Specialize_CallFunctionEx(_PyStackRef func_st, _Py_CODEUNIT *instr)
if (Py_TYPE(func) == &PyFunction_Type &&
((PyFunctionObject *)func)->vectorcall == _PyFunction_Vectorcall) {
if (_PyInterpreterState_GET()->eval_frame) {
if (!_PyInterpreterState_IsSpecializationEnabled(_PyInterpreterState_GET())) {
goto failure;
}
specialize(instr, CALL_EX_PY);