Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 08b53e6

Browse files
committed
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.
1 parent 98dc065 commit 08b53e6

1 file changed

Lines changed: 24 additions & 86 deletions

File tree

Objects/tupleobject.c

Lines changed: 24 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -424,11 +424,10 @@ PyTypeObject PyTuple_Type = {
424424
/* The following function breaks the notion that tuples are immutable:
425425
it changes the size of a tuple. We get away with this only if there
426426
is only one module referencing the object. You can also think of it
427-
as creating a new tuple object and destroying the old one, only
428-
more efficiently. In any case, don't use this if the tuple may
429-
already be known to some other part of the code...
430-
If last_is_sticky is set, the tuple will grow or shrink at the
431-
front, otherwise it will grow or shrink at the end. */
427+
as creating a new tuple object and destroying the old one, only more
428+
efficiently. In any case, don't use this if the tuple may already be
429+
known to some other part of the code. The last_is_sticky is not used
430+
and must always be false. */
432431

433432
int
434433
_PyTuple_Resize(PyObject **pv, int newsize, int last_is_sticky)
@@ -439,106 +438,45 @@ _PyTuple_Resize(PyObject **pv, int newsize, int last_is_sticky)
439438
int sizediff;
440439

441440
v = (PyTupleObject *) *pv;
442-
if (v == NULL || !PyTuple_Check(v) || v->ob_refcnt != 1) {
441+
if (v == NULL || !PyTuple_Check(v) || v->ob_refcnt != 1 ||
442+
last_is_sticky) {
443443
*pv = 0;
444-
Py_DECREF(v);
444+
Py_XDECREF(v);
445445
PyErr_BadInternalCall();
446446
return -1;
447447
}
448448
sizediff = newsize - v->ob_size;
449449
if (sizediff == 0)
450450
return 0;
451+
451452
/* XXX UNREF/NEWREF interface should be more symmetrical */
452453
#ifdef Py_REF_DEBUG
453454
--_Py_RefTotal;
454455
#endif
455-
_Py_ForgetReference((PyObject *)v);
456-
if (last_is_sticky && sizediff < 0) {
457-
/* shrinking:
458-
move entries to the front and zero moved entries */
459-
for (i = 0; i < newsize; i++) {
460-
Py_XDECREF(v->ob_item[i]);
461-
v->ob_item[i] = v->ob_item[i - sizediff];
462-
v->ob_item[i - sizediff] = NULL;
463-
}
464-
}
456+
_Py_ForgetReference((PyObject *) v);
465457
for (i = newsize; i < v->ob_size; i++) {
466458
Py_XDECREF(v->ob_item[i]);
467459
v->ob_item[i] = NULL;
468460
}
469-
#if MAXSAVESIZE > 0
470-
if (newsize == 0 && free_tuples[0]) {
471-
num_free_tuples[0]--;
472-
sv = free_tuples[0];
473-
sv->ob_size = 0;
474-
Py_INCREF(sv);
475-
#ifdef COUNT_ALLOCS
476-
tuple_zero_allocs++;
477-
#endif
478-
tupledealloc(v);
479-
*pv = (PyObject*) sv;
480-
return 0;
481-
}
482-
if (0 < newsize && newsize < MAXSAVESIZE &&
483-
(sv = free_tuples[newsize]) != NULL)
484-
{
485-
free_tuples[newsize] = (PyTupleObject *) sv->ob_item[0];
486-
num_free_tuples[newsize]--;
487-
#ifdef COUNT_ALLOCS
488-
fast_tuple_allocs++;
489-
#endif
490-
#ifdef Py_TRACE_REFS
491-
sv->ob_type = &PyTuple_Type;
492-
#endif
493-
for (i = 0; i < newsize; ++i){
494-
sv->ob_item[i] = v->ob_item[i];
495-
v->ob_item[i] = NULL;
496-
}
497-
sv->ob_size = v->ob_size;
498-
tupledealloc(v);
499-
*pv = (PyObject *) sv;
500-
} else
501-
#endif
502-
{
503-
#ifdef WITH_CYCLE_GC
504-
PyGC_Head *g = PyObject_AS_GC((PyObject *)v);
505-
PyObject_GC_Fini((PyObject *)v);
506-
g = (PyGC_Head *)
507-
PyObject_REALLOC((char *)g, sizeof(PyTupleObject)
508-
+ PyGC_HEAD_SIZE
509-
+ newsize * sizeof(PyObject *));
510-
if (g == NULL) {
511-
sv = NULL;
512-
} else {
513-
sv = (PyTupleObject *)PyObject_FROM_GC(g);
514-
}
515-
#else
516-
sv = (PyTupleObject *)
517-
PyObject_REALLOC((char *)v, sizeof(PyTupleObject)
518-
+ PyGC_HEAD_SIZE
519-
+ newsize * sizeof(PyObject *));
520-
#endif
521-
*pv = (PyObject *) sv;
522-
if (sv == NULL) {
523-
PyObject_GC_Init((PyObject *)v);
524-
v = (PyTupleObject *) PyObject_AS_GC(v);
525-
PyObject_DEL(v);
526-
PyErr_NoMemory();
527-
return -1;
528-
}
461+
PyObject_GC_Fini(v);
462+
v = (PyTupleObject *) PyObject_AS_GC(v);
463+
sv = (PyTupleObject *) PyObject_REALLOC((char *)v,
464+
sizeof(PyTupleObject)
465+
+ PyGC_HEAD_SIZE
466+
+ newsize * sizeof(PyObject *));
467+
if (sv == NULL) {
468+
*pv = NULL;
469+
PyObject_DEL(v);
470+
PyErr_NoMemory();
471+
return -1;
529472
}
530-
_Py_NewReference((PyObject *)sv);
473+
sv = (PyTupleObject *) PyObject_FROM_GC(sv);
474+
_Py_NewReference((PyObject *) sv);
531475
for (i = sv->ob_size; i < newsize; i++)
532476
sv->ob_item[i] = NULL;
533-
if (last_is_sticky && sizediff > 0) {
534-
/* growing: move entries to the end and zero moved entries */
535-
for (i = newsize - 1; i >= sizediff; i--) {
536-
sv->ob_item[i] = sv->ob_item[i - sizediff];
537-
sv->ob_item[i - sizediff] = NULL;
538-
}
539-
}
540-
PyObject_GC_Init(sv);
541477
sv->ob_size = newsize;
478+
*pv = (PyObject *) sv;
479+
PyObject_GC_Init(sv);
542480
return 0;
543481
}
544482

0 commit comments

Comments
 (0)