diff options
author | Serhiy Storchaka <storchaka@gmail.com> | 2015-05-24 18:38:06 (GMT) |
---|---|---|
committer | Serhiy Storchaka <storchaka@gmail.com> | 2015-05-24 18:38:06 (GMT) |
commit | a7a0ad6f73bbff0d3a30fca42be8ee36b90dc944 (patch) | |
tree | e03265790d5cee6bc5c726ffd6eecc4dc68bad94 | |
parent | 3805019c588dc9895348f5b8ffedbd0426169a71 (diff) | |
download | cpython-a7a0ad6f73bbff0d3a30fca42be8ee36b90dc944.zip cpython-a7a0ad6f73bbff0d3a30fca42be8ee36b90dc944.tar.gz cpython-a7a0ad6f73bbff0d3a30fca42be8ee36b90dc944.tar.bz2 |
Issue #24276: Fixed optimization of property descriptor getter.
-rw-r--r-- | Misc/NEWS | 2 | ||||
-rw-r--r-- | Objects/descrobject.c | 25 |
2 files changed, 23 insertions, 4 deletions
@@ -10,6 +10,8 @@ Release date: 2015-05-24 Core and Builtins ----------------- +- Issue #24276: Fixed optimization of property descriptor getter. + - Issue #24268: PEP 489: Multi-phase extension module initialization - Issue #23955: Add pyvenv.cfg option to suppress registry/environment diff --git a/Objects/descrobject.c b/Objects/descrobject.c index 24b24e7..1a69b6b 100644 --- a/Objects/descrobject.c +++ b/Objects/descrobject.c @@ -1372,7 +1372,8 @@ property_dealloc(PyObject *self) static PyObject * property_descr_get(PyObject *self, PyObject *obj, PyObject *type) { - static PyObject *args = NULL; + static PyObject * volatile cached_args = NULL; + PyObject *args; PyObject *ret; propertyobject *gs = (propertyobject *)self; @@ -1384,12 +1385,28 @@ property_descr_get(PyObject *self, PyObject *obj, PyObject *type) PyErr_SetString(PyExc_AttributeError, "unreadable attribute"); return NULL; } - if (!args && !(args = PyTuple_New(1))) { - return NULL; + args = cached_args; + if (!args || Py_REFCNT(args) != 1) { + Py_CLEAR(cached_args); + if (!(cached_args = args = PyTuple_New(1))) + return NULL; } + Py_INCREF(args); + assert (Py_REFCNT(args) == 2); + Py_INCREF(obj); PyTuple_SET_ITEM(args, 0, obj); ret = PyObject_Call(gs->prop_get, args, NULL); - PyTuple_SET_ITEM(args, 0, NULL); + if (args == cached_args) { + if (Py_REFCNT(args) == 2) { + obj = PyTuple_GET_ITEM(args, 0); + PyTuple_SET_ITEM(args, 0, NULL); + Py_XDECREF(obj); + } + else { + Py_CLEAR(cached_args); + } + } + Py_DECREF(args); return ret; } |