Description
Feature or enhancement
Proposal:
We should add non-refcounted operations for common types (float, int, str) that return _PyStackRef
. This will tie in nicely with optimizations in the JIT #134584 , and also eventually speed up the default/free-threaded builds.
For example,
PyObject *
PyFloat_FromDouble(double fval)
{
PyFloatObject *op = _Py_FREELIST_POP(PyFloatObject, floats);
if (op == NULL) {
op = PyObject_Malloc(sizeof(PyFloatObject));
if (!op) {
return PyErr_NoMemory();
}
_PyObject_Init((PyObject*)op, &PyFloat_Type);
}
op->ob_fval = fval;
return (PyObject *) op;
}
Should become
_PyStackRef
PyFloat_FromDouble(double fval)
{
PyFloatObject *op = _Py_FREELIST_POP_NO_NEWREF(PyFloatObject, floats);
if (op == NULL) {
op = PyObject_Malloc(sizeof(PyFloatObject));
if (!op) {
return PyErr_NoMemory();
}
_PyObject_Init_NoNewRef((PyObject*)op, &PyFloat_Type);
}
op->ob_fval = fval;
return PyStackRef_FromPyObjectBorrow((PyObject *) op);
}
Where NoNewRef
variants don't initialize a refcount field.
The above is safe as PyFloat_Type
is a static type, and when escaping to external functions, we can re-create the refcount as needed in PyStackRef_AsPyObjectSteal
.
The safest way to start with this is a backwards "used" analysis pass, which will determine if we can eliminate result operations in the JIT. We can then cautiously expand this to the default and FT builds.
I will start with a simple example, then I will split up the work to allow other contributors to contribute.
Has this already been discussed elsewhere?
No response given
Links to previous discussion of this feature:
No response