From a7a0ad6f73bbff0d3a30fca42be8ee36b90dc944 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Sun, 24 May 2015 21:38:06 +0300 Subject: Issue #24276: Fixed optimization of property descriptor getter. --- Misc/NEWS | 2 ++ Objects/descrobject.c | 25 +++++++++++++++++++++---- 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/Misc/NEWS b/Misc/NEWS index ef2a0f0..88818b6 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -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; } -- cgit v0.12