]> granicus.if.org Git - python/commitdiff
Simplify _PyTuple_Resize by not using the tuple free list and dropping
authorNeil Schemenauer <nascheme@enme.ucalgary.ca>
Thu, 5 Oct 2000 19:36:49 +0000 (19:36 +0000)
committerNeil Schemenauer <nascheme@enme.ucalgary.ca>
Thu, 5 Oct 2000 19:36:49 +0000 (19:36 +0000)
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

index 9b15a0521526409b15c934526b7845a72f1937bc..be62d0f51cfc31289525b5e2a187c15d0447d2c2 100644 (file)
@@ -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;
 }