gh-141367: Use CALL_LIST_APPEND instruction only for lists, not for list subclasses (GH-141398)

Co-authored-by: Ken Jin <kenjin4096@gmail.com>
This commit is contained in:
Mikhail Efimov 2025-11-15 00:38:39 +03:00 committed by GitHub
parent f26ed455d5
commit 1281be1caf
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 44 additions and 20 deletions

View file

@ -1602,8 +1602,8 @@ specialize_class_call(PyObject *callable, _Py_CODEUNIT *instr, int nargs)
}
static int
specialize_method_descriptor(PyMethodDescrObject *descr, _Py_CODEUNIT *instr,
int nargs)
specialize_method_descriptor(PyMethodDescrObject *descr, PyObject *self_or_null,
_Py_CODEUNIT *instr, int nargs)
{
switch (descr->d_method->ml_flags &
(METH_VARARGS | METH_FASTCALL | METH_NOARGS | METH_O |
@ -1627,8 +1627,11 @@ specialize_method_descriptor(PyMethodDescrObject *descr, _Py_CODEUNIT *instr,
bool pop = (next.op.code == POP_TOP);
int oparg = instr->op.arg;
if ((PyObject *)descr == list_append && oparg == 1 && pop) {
specialize(instr, CALL_LIST_APPEND);
return 0;
assert(self_or_null != NULL);
if (PyList_CheckExact(self_or_null)) {
specialize(instr, CALL_LIST_APPEND);
return 0;
}
}
specialize(instr, CALL_METHOD_DESCRIPTOR_O);
return 0;
@ -1766,7 +1769,7 @@ specialize_c_call(PyObject *callable, _Py_CODEUNIT *instr, int nargs)
}
Py_NO_INLINE void
_Py_Specialize_Call(_PyStackRef callable_st, _Py_CODEUNIT *instr, int nargs)
_Py_Specialize_Call(_PyStackRef callable_st, _PyStackRef self_or_null_st, _Py_CODEUNIT *instr, int nargs)
{
PyObject *callable = PyStackRef_AsPyObjectBorrow(callable_st);
@ -1784,7 +1787,9 @@ _Py_Specialize_Call(_PyStackRef callable_st, _Py_CODEUNIT *instr, int nargs)
fail = specialize_class_call(callable, instr, nargs);
}
else if (Py_IS_TYPE(callable, &PyMethodDescr_Type)) {
fail = specialize_method_descriptor((PyMethodDescrObject *)callable, instr, nargs);
PyObject *self_or_null = PyStackRef_AsPyObjectBorrow(self_or_null_st);
fail = specialize_method_descriptor((PyMethodDescrObject *)callable,
self_or_null, instr, nargs);
}
else if (PyMethod_Check(callable)) {
PyObject *func = ((PyMethodObject *)callable)->im_func;