[Python-Dev] cpython: Tighten-up code in the set iterator to use an entry pointer rather than
Serhiy Storchaka
storchaka at gmail.com
Tue Jul 7 09:42:43 CEST 2015
On 07.07.15 05:03, raymond.hettinger wrote:
> https://hg.python.org/cpython/rev/c9782a9ac031
> changeset: 96865:c9782a9ac031
> user: Raymond Hettinger <python at rcn.com>
> date: Mon Jul 06 19:03:01 2015 -0700
> summary:
> Tighten-up code in the set iterator to use an entry pointer rather than indexing.
>
> files:
> Objects/setobject.c | 35 ++++++++++++--------------------
> 1 files changed, 13 insertions(+), 22 deletions(-)
>
>
> diff --git a/Objects/setobject.c b/Objects/setobject.c
> --- a/Objects/setobject.c
> +++ b/Objects/setobject.c
> @@ -766,8 +766,8 @@
> PyObject_HEAD
> PySetObject *si_set; /* Set to NULL when iterator is exhausted */
> Py_ssize_t si_used;
> - Py_ssize_t si_pos;
> Py_ssize_t len;
> + setentry *entry;
> } setiterobject;
>
> static void
> @@ -845,8 +845,6 @@
>
> static PyObject *setiter_iternext(setiterobject *si)
> {
> - PyObject *key;
> - Py_ssize_t i, mask;
> setentry *entry;
> PySetObject *so = si->si_set;
>
> @@ -860,25 +858,18 @@
> si->si_used = -1; /* Make this state sticky */
> return NULL;
> }
> -
> - i = si->si_pos;
> - assert(i>=0);
> - entry = so->table;
> - mask = so->mask;
> - while (i <= mask && (entry[i].key == NULL || entry[i].key == dummy))
> - i++;
> - si->si_pos = i+1;
> - if (i > mask)
> - goto fail;
> + if (si->len <= 0) {
> + Py_DECREF(so);
> + si->si_set = NULL;
> + return NULL;
> + }
> + entry = si->entry;
> + while (entry->key == NULL || entry->key == dummy)
> + entry++;
> si->len--;
> - key = entry[i].key;
> - Py_INCREF(key);
> - return key;
> -
> -fail:
> - Py_DECREF(so);
> - si->si_set = NULL;
> - return NULL;
> + si->entry = entry + 1;
> + Py_INCREF(entry->key);
> + return entry->key;
> }
>
> PyTypeObject PySetIter_Type = {
> @@ -923,8 +914,8 @@
> Py_INCREF(so);
> si->si_set = so;
> si->si_used = so->used;
> - si->si_pos = 0;
> si->len = so->used;
> + si->entry = so->table;
> _PyObject_GC_TRACK(si);
> return (PyObject *)si;
> }
What if so->table was reallocated during the iteration, but so->used is
left the same? This change looks unsafe to me.
More information about the Python-Dev
mailing list