summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNeil Schemenauer <nascheme@enme.ucalgary.ca>2000-10-05 19:36:49 (GMT)
committerNeil Schemenauer <nascheme@enme.ucalgary.ca>2000-10-05 19:36:49 (GMT)
commit08b53e6a2ad6b7ba08430e2b0cf6586ae90c564e (patch)
treea9dc764774829faac6d62a28e47bd7302b46f5a8
parent98dc065c1b96705d42c4853fdb28ff5ae64093b9 (diff)
downloadcpython-08b53e6a2ad6b7ba08430e2b0cf6586ae90c564e.zip
cpython-08b53e6a2ad6b7ba08430e2b0cf6586ae90c564e.tar.gz
cpython-08b53e6a2ad6b7ba08430e2b0cf6586ae90c564e.tar.bz2
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.
-rw-r--r--Objects/tupleobject.c110
1 files 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;
}