From 08b53e6a2ad6b7ba08430e2b0cf6586ae90c564e Mon Sep 17 00:00:00 2001 From: Neil Schemenauer Date: Thu, 5 Oct 2000 19:36:49 +0000 Subject: Simplify _PyTuple_Resize by not using the tuple free list and dropping support for the last_is_sticky flag. A few hard to find bugs may be fixed by this patch since the old code was buggy. --- Objects/tupleobject.c | 110 +++++++++++--------------------------------------- 1 file changed, 24 insertions(+), 86 deletions(-) diff --git a/Objects/tupleobject.c b/Objects/tupleobject.c index 9b15a05..be62d0f 100644 --- a/Objects/tupleobject.c +++ b/Objects/tupleobject.c @@ -424,11 +424,10 @@ PyTypeObject PyTuple_Type = { /* The following function breaks the notion that tuples are immutable: it changes the size of a tuple. We get away with this only if there is only one module referencing the object. You can also think of it - as creating a new tuple object and destroying the old one, only - more efficiently. In any case, don't use this if the tuple may - already be known to some other part of the code... - If last_is_sticky is set, the tuple will grow or shrink at the - front, otherwise it will grow or shrink at the end. */ + as creating a new tuple object and destroying the old one, only more + efficiently. In any case, don't use this if the tuple may already be + known to some other part of the code. The last_is_sticky is not used + and must always be false. */ int _PyTuple_Resize(PyObject **pv, int newsize, int last_is_sticky) @@ -439,106 +438,45 @@ _PyTuple_Resize(PyObject **pv, int newsize, int last_is_sticky) int sizediff; v = (PyTupleObject *) *pv; - if (v == NULL || !PyTuple_Check(v) || v->ob_refcnt != 1) { + if (v == NULL || !PyTuple_Check(v) || v->ob_refcnt != 1 || + last_is_sticky) { *pv = 0; - Py_DECREF(v); + Py_XDECREF(v); PyErr_BadInternalCall(); return -1; } sizediff = newsize - v->ob_size; if (sizediff == 0) return 0; + /* XXX UNREF/NEWREF interface should be more symmetrical */ #ifdef Py_REF_DEBUG --_Py_RefTotal; #endif - _Py_ForgetReference((PyObject *)v); - if (last_is_sticky && sizediff < 0) { - /* shrinking: - move entries to the front and zero moved entries */ - for (i = 0; i < newsize; i++) { - Py_XDECREF(v->ob_item[i]); - v->ob_item[i] = v->ob_item[i - sizediff]; - v->ob_item[i - sizediff] = NULL; - } - } + _Py_ForgetReference((PyObject *) v); for (i = newsize; i < v->ob_size; i++) { Py_XDECREF(v->ob_item[i]); v->ob_item[i] = NULL; } -#if MAXSAVESIZE > 0 - if (newsize == 0 && free_tuples[0]) { - num_free_tuples[0]--; - sv = free_tuples[0]; - sv->ob_size = 0; - Py_INCREF(sv); -#ifdef COUNT_ALLOCS - tuple_zero_allocs++; -#endif - tupledealloc(v); - *pv = (PyObject*) sv; - return 0; - } - if (0 < newsize && newsize < MAXSAVESIZE && - (sv = free_tuples[newsize]) != NULL) - { - free_tuples[newsize] = (PyTupleObject *) sv->ob_item[0]; - num_free_tuples[newsize]--; -#ifdef COUNT_ALLOCS - fast_tuple_allocs++; -#endif -#ifdef Py_TRACE_REFS - sv->ob_type = &PyTuple_Type; -#endif - for (i = 0; i < newsize; ++i){ - sv->ob_item[i] = v->ob_item[i]; - v->ob_item[i] = NULL; - } - sv->ob_size = v->ob_size; - tupledealloc(v); - *pv = (PyObject *) sv; - } else -#endif - { -#ifdef WITH_CYCLE_GC - PyGC_Head *g = PyObject_AS_GC((PyObject *)v); - PyObject_GC_Fini((PyObject *)v); - g = (PyGC_Head *) - PyObject_REALLOC((char *)g, sizeof(PyTupleObject) - + PyGC_HEAD_SIZE - + newsize * sizeof(PyObject *)); - if (g == NULL) { - sv = NULL; - } else { - sv = (PyTupleObject *)PyObject_FROM_GC(g); - } -#else - sv = (PyTupleObject *) - PyObject_REALLOC((char *)v, sizeof(PyTupleObject) - + PyGC_HEAD_SIZE - + newsize * sizeof(PyObject *)); -#endif - *pv = (PyObject *) sv; - if (sv == NULL) { - PyObject_GC_Init((PyObject *)v); - v = (PyTupleObject *) PyObject_AS_GC(v); - PyObject_DEL(v); - PyErr_NoMemory(); - return -1; - } + PyObject_GC_Fini(v); + v = (PyTupleObject *) PyObject_AS_GC(v); + sv = (PyTupleObject *) PyObject_REALLOC((char *)v, + sizeof(PyTupleObject) + + PyGC_HEAD_SIZE + + newsize * sizeof(PyObject *)); + if (sv == NULL) { + *pv = NULL; + PyObject_DEL(v); + PyErr_NoMemory(); + return -1; } - _Py_NewReference((PyObject *)sv); + sv = (PyTupleObject *) PyObject_FROM_GC(sv); + _Py_NewReference((PyObject *) sv); for (i = sv->ob_size; i < newsize; i++) sv->ob_item[i] = NULL; - if (last_is_sticky && sizediff > 0) { - /* growing: move entries to the end and zero moved entries */ - for (i = newsize - 1; i >= sizediff; i--) { - sv->ob_item[i] = sv->ob_item[i - sizediff]; - sv->ob_item[i - sizediff] = NULL; - } - } - PyObject_GC_Init(sv); sv->ob_size = newsize; + *pv = (PyObject *) sv; + PyObject_GC_Init(sv); return 0; } -- cgit v0.12