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.
This commit is contained in:
Neil Schemenauer 2000-10-05 19:36:49 +00:00
parent 98dc065c1b
commit 08b53e6a2a
1 changed files with 24 additions and 86 deletions

View 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;
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;
}
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;
}
}
_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;
}