Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

use stackrefs in_PyObject_GetMethod and calling APIs #134043

Open
Assignees
kumaraditya303
Labels
@kumaraditya303

Description

@kumaraditya303

Feature or enhancement

Currently the calling APIs such asPyObject_VectorcallMethod use_PyObject_GetMethod to avoid creating a bound method object, however_PyObject_GetMethod increfs and decrefs the object even when the underlying object supports deferred reference counting. This leads to reference counting contention on the object and it doesn't scale well in free threading. This API is heavily used by modules such as asyncio so it is important that_PyObject_GetMethod should scale well with threads.

cpython/Objects/call.c

Lines 829 to 859 in54a6875

PyObject_VectorcallMethod(PyObject*name,PyObject*const*args,
size_tnargsf,PyObject*kwnames)
{
assert(name!=NULL);
assert(args!=NULL);
assert(PyVectorcall_NARGS(nargsf) >=1);
PyThreadState*tstate=_PyThreadState_GET();
PyObject*callable=NULL;
/* Use args[0] as "self" argument */
intunbound=_PyObject_GetMethod(args[0],name,&callable);
if (callable==NULL) {
returnNULL;
}
if (unbound) {
/* We must remove PY_VECTORCALL_ARGUMENTS_OFFSET since
* that would be interpreted as allowing to change args[-1] */
nargsf &= ~PY_VECTORCALL_ARGUMENTS_OFFSET;
}
else {
/* Skip "self". We can keep PY_VECTORCALL_ARGUMENTS_OFFSET since
* args[-1] in the onward call is args[0] here. */
args++;
nargsf--;
}
EVAL_CALL_STAT_INC_IF_FUNCTION(EVAL_CALL_METHOD,callable);
PyObject*result=_PyObject_VectorcallTstate(tstate,callable,
args,nargsf,kwnames);
Py_DECREF(callable);
returnresult;

Proposal:

To take advantage of deferred reference counting, we should add stack ref variant of_PyObject_GetMethod and use it in all calling APIs to avoid reference counting contention on the function object.

Implementation:

  • The new stack ref variant_PyObject_GetMethodStackRef will use_PyType_LookupStackRefAndVersion when looking up method from type cache.
  • A new stack ref variant of_PyObject_TryGetInstanceAttributeStackRef will be added to to be used with_PyObject_GetMethodStackRef.
  • Possibly we can avoid incref and decref when looking up the attribute on instance dict by delaying freeing of object's dictionary and using_Py_dict_lookup_threadsafe_stackref.

    cpython/Objects/object.c

    Lines 1632 to 1640 in54a6875

    Py_INCREF(dict);
    if (PyDict_GetItemRef(dict,name,method)!=0) {
    // found or error
    Py_DECREF(dict);
    Py_XDECREF(descr);
    return0;
    }
    // not found
    Py_DECREF(dict);

Linked PRs

Metadata

Metadata

Labels

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions


    [8]ページ先頭

    ©2009-2025 Movatter.jp