cpython/Include/internal/pycore_function.h
Sam Gross fa3143a1d2
[3.14] gh-145779: Improve classmethod/staticmethod scaling in free-threaded build (gh-145826) (#146088)
Add special cases for classmethod and staticmethod descriptors in
_PyObject_GetMethodStackRef() to avoid calling tp_descr_get, which
avoids reference count contention on the bound method and underlying
callable. This improves scaling when calling classmethods and
staticmethods from multiple threads.

Also refactor method_vectorcall in classobject.c into a new
_PyObject_VectorcallPrepend() helper so that it can be used by
PyObject_VectorcallMethod as well.

(cherry picked from commit e0f7c1097e)
2026-03-19 10:49:12 -04:00

64 lines
1.8 KiB
C

#ifndef Py_INTERNAL_FUNCTION_H
#define Py_INTERNAL_FUNCTION_H
#ifdef __cplusplus
extern "C" {
#endif
#ifndef Py_BUILD_CORE
# error "this header requires Py_BUILD_CORE define"
#endif
extern PyObject* _PyFunction_Vectorcall(
PyObject *func,
PyObject *const *stack,
size_t nargsf,
PyObject *kwnames);
#define FUNC_VERSION_UNSET 0
#define FUNC_VERSION_CLEARED 1
#define FUNC_VERSION_FIRST_VALID 2
extern PyFunctionObject* _PyFunction_FromConstructor(PyFrameConstructor *constr);
static inline int
_PyFunction_IsVersionValid(uint32_t version)
{
return version >= FUNC_VERSION_FIRST_VALID;
}
extern uint32_t _PyFunction_GetVersionForCurrentState(PyFunctionObject *func);
PyAPI_FUNC(void) _PyFunction_SetVersion(PyFunctionObject *func, uint32_t version);
void _PyFunction_ClearCodeByVersion(uint32_t version);
PyFunctionObject *_PyFunction_LookupByVersion(uint32_t version, PyObject **p_code);
extern PyObject *_Py_set_function_type_params(
PyThreadState* unused, PyObject *func, PyObject *type_params);
/* See pycore_code.h for explanation about what "stateless" means. */
PyAPI_FUNC(int)
_PyFunction_VerifyStateless(PyThreadState *, PyObject *);
static inline PyObject* _PyFunction_GET_BUILTINS(PyObject *func) {
return _PyFunction_CAST(func)->func_builtins;
}
#define _PyFunction_GET_BUILTINS(func) _PyFunction_GET_BUILTINS(_PyObject_CAST(func))
/* Get the callable wrapped by a classmethod.
Returns a borrowed reference.
The caller must ensure 'cm' is a classmethod object. */
extern PyObject *_PyClassMethod_GetFunc(PyObject *cm);
/* Get the callable wrapped by a staticmethod.
Returns a borrowed reference.
The caller must ensure 'sm' is a staticmethod object. */
extern PyObject *_PyStaticMethod_GetFunc(PyObject *sm);
#ifdef __cplusplus
}
#endif
#endif /* !Py_INTERNAL_FUNCTION_H */