cpython: 135a9a0c09f9 (original) (raw)

Mercurial > cpython

changeset 106396:135a9a0c09f9

Issue #29263: LOAD_METHOD support for C methods Calling builtin method is at most 10% faster. [#29263]

INADA Naoki songofacandy@gmail.com
date Fri, 03 Feb 2017 07:43:03 +0900
parents c23224ebc9e5
children b382206aeb2b
files Include/descrobject.h Include/methodobject.h Lib/test/test_gdb.py Objects/descrobject.c Objects/methodobject.c Objects/object.c Python/ceval.c Tools/gdb/libpython.py
diffstat 8 files changed, 88 insertions(+), 36 deletions(-)[+] [-] Include/descrobject.h 3 Include/methodobject.h 7 Lib/test/test_gdb.py 2 Objects/descrobject.c 38 Objects/methodobject.c 53 Objects/object.c 4 Python/ceval.c 12 Tools/gdb/libpython.py 5

line wrap: on

line diff

--- a/Include/descrobject.h +++ b/Include/descrobject.h @@ -90,6 +90,9 @@ PyAPI_FUNC(PyObject *) PyDescr_NewMember PyAPI_FUNC(PyObject *) PyDescr_NewGetSet(PyTypeObject *, struct PyGetSetDef *); #ifndef Py_LIMITED_API + +PyAPI_FUNC(PyObject *) _PyMethodDescr_FastCallKeywords(

PyAPI_FUNC(PyObject *) PyDescr_NewWrapper(PyTypeObject *, struct wrapperbase *, void *); #define PyDescr_IsData(d) (Py_TYPE(d)->tp_descr_set != NULL)

--- a/Include/methodobject.h +++ b/Include/methodobject.h @@ -102,6 +102,13 @@ PyAPI_FUNC(PyObject *) _PyMethodDef_RawF PyObject **args, Py_ssize_t nargs, PyObject *kwargs); + +PyAPI_FUNC(PyObject *) _PyMethodDef_RawFastCallKeywords(

#endif PyAPI_FUNC(int) PyCFunction_ClearFreeList(void);

--- a/Lib/test/test_gdb.py +++ b/Lib/test/test_gdb.py @@ -846,7 +846,7 @@ id(42) breakpoint='time_gmtime', cmds_after_breakpoint=['py-bt-full'], )

@unittest.skipIf(python_is_optimized(), "Python was compiled with optimizations")

--- a/Objects/descrobject.c +++ b/Objects/descrobject.c @@ -246,6 +246,44 @@ methoddescr_call(PyMethodDescrObject *de return result; } +// same to methoddescr_call(), but use FASTCALL convention. +PyObject * +_PyMethodDescr_FastCallKeywords(PyObject *descrobj,

+{

+

+

+} + static PyObject * classmethoddescr_call(PyMethodDescrObject *descr, PyObject *args, PyObject *kwds)

--- a/Objects/methodobject.c +++ b/Objects/methodobject.c @@ -215,32 +215,24 @@ PyObject * } PyObject * -_PyCFunction_FastCallKeywords(PyObject *func_obj, PyObject **args,

+_PyMethodDef_RawFastCallKeywords(PyMethodDef *method, PyObject *self, PyObject **args,

{

-

switch (flags) { @@ -248,7 +240,7 @@ PyObject * if (nargs != 0) { PyErr_Format(PyExc_TypeError, "%.200s() takes no arguments (%zd given)",

@@ -263,7 +255,7 @@ PyObject * if (nargs != 1) { PyErr_Format(PyExc_TypeError, "%.200s() takes exactly one argument (%zd given)",

@@ -326,16 +318,31 @@ PyObject * return NULL; }

+{

+

+

+} + /* Methods (the standard built-in methods, that is) */ static void

--- a/Objects/object.c +++ b/Objects/object.c @@ -1060,8 +1060,8 @@ int descr = _PyType_Lookup(tp, name); if (descr != NULL) { Py_INCREF(descr);

--- a/Python/ceval.c +++ b/Python/ceval.c @@ -4832,17 +4832,19 @@ call_function(PyObject ***pp_stack, Py_s PyObject *x, *w; Py_ssize_t nkwargs = (kwnames == NULL) ? 0 : PyTuple_GET_SIZE(kwnames); Py_ssize_t nargs = oparg - nkwargs;

/* Always dispatch PyCFunction first, because these are presumed to be the most frequent callable object. */ if (PyCFunction_Check(func)) { PyThreadState *tstate = PyThreadState_GET(); -

@@ -4856,20 +4858,18 @@ call_function(PyObject ***pp_stack, Py_s Py_INCREF(func); Py_SETREF(*pfunc, self); nargs++;

- if (PyFunction_Check(func)) { x = fast_function(func, stack, nargs, kwnames); } else { x = _PyObject_FastCallKeywords(func, stack, nargs, kwnames); } - Py_DECREF(func); }

--- a/Tools/gdb/libpython.py +++ b/Tools/gdb/libpython.py @@ -1540,10 +1540,7 @@ class Frame(object): if caller in ('_PyCFunction_FastCallDict', '_PyCFunction_FastCallKeywords'):