mirror of
https://github.com/python/cpython.git
synced 2025-08-25 03:04:55 +00:00
gh-131586: Avoid refcount contention in some "special" calls (#131588)
In the free threaded build, the `_PyObject_LookupSpecial()` call can lead to reference count contention on the returned function object becuase it doesn't use stackrefs. Refactor some of the callers to use `_PyObject_MaybeCallSpecialNoArgs`, which uses stackrefs internally. This fixes the scaling bottleneck in the "lookup_special" microbenchmark in `ftscalingbench.py`. However, the are still some uses of `_PyObject_LookupSpecial()` that need to be addressed in future PRs.
This commit is contained in:
parent
3d4ac1a2c2
commit
67fbfb42bd
16 changed files with 450 additions and 374 deletions
|
@ -2537,22 +2537,19 @@ static PyObject *
|
|||
builtin_round_impl(PyObject *module, PyObject *number, PyObject *ndigits)
|
||||
/*[clinic end generated code: output=ff0d9dd176c02ede input=275678471d7aca15]*/
|
||||
{
|
||||
PyObject *round, *result;
|
||||
|
||||
round = _PyObject_LookupSpecial(number, &_Py_ID(__round__));
|
||||
if (round == NULL) {
|
||||
if (!PyErr_Occurred())
|
||||
PyErr_Format(PyExc_TypeError,
|
||||
"type %.100s doesn't define __round__ method",
|
||||
Py_TYPE(number)->tp_name);
|
||||
return NULL;
|
||||
PyObject *result;
|
||||
if (ndigits == Py_None) {
|
||||
result = _PyObject_MaybeCallSpecialNoArgs(number, &_Py_ID(__round__));
|
||||
}
|
||||
else {
|
||||
result = _PyObject_MaybeCallSpecialOneArg(number, &_Py_ID(__round__),
|
||||
ndigits);
|
||||
}
|
||||
if (result == NULL && !PyErr_Occurred()) {
|
||||
PyErr_Format(PyExc_TypeError,
|
||||
"type %.100s doesn't define __round__ method",
|
||||
Py_TYPE(number)->tp_name);
|
||||
}
|
||||
|
||||
if (ndigits == Py_None)
|
||||
result = _PyObject_CallNoArgs(round);
|
||||
else
|
||||
result = PyObject_CallOneArg(round, ndigits);
|
||||
Py_DECREF(round);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue