Skip to content

Commit 2c84fa9

Browse files
Fixed bugs in resizetuple and extended the interface.
Added ifdefs in stringobject.c for shared strings of length 1. Renamed free_list in tupleobject.c to free_tuples.
1 parent a8aa745 commit 2c84fa9

4 files changed

Lines changed: 59 additions & 18 deletions

File tree

Include/tupleobject.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ extern int gettuplesize PROTO((object *));
5858
extern object *gettupleitem PROTO((object *, int));
5959
extern int settupleitem PROTO((object *, int, object *));
6060
extern object *gettupleslice PROTO((object *, int, int));
61-
extern int resizetuple PROTO((object **, int));
61+
extern int resizetuple PROTO((object **, int, int));
6262

6363
/* Macro, trading safety for speed */
6464
#define GETTUPLEITEM(op, i) ((op)->ob_item[i])

Objects/stringobject.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,9 @@ int null_strings, one_strings;
3939
#endif
4040

4141
static stringobject *characters[UCHAR_MAX + 1];
42+
#ifndef DONT_SHARE_SHORT_STRINGS
4243
static stringobject *nullstring;
44+
#endif
4345

4446
/*
4547
Newsizedstringobject() and newstringobject() try in certain cases
@@ -62,6 +64,7 @@ newsizedstringobject(str, size)
6264
int size;
6365
{
6466
register stringobject *op;
67+
#ifndef DONT_SHARE_SHORT_STRINGS
6568
if (size == 0 && (op = nullstring) != NULL) {
6669
#ifdef COUNT_ALLOCS
6770
null_strings++;
@@ -76,6 +79,7 @@ newsizedstringobject(str, size)
7679
INCREF(op);
7780
return (object *)op;
7881
}
82+
#endif /* DONT_SHARE_SHORT_STRINGS */
7983
op = (stringobject *)
8084
malloc(sizeof(stringobject) + size * sizeof(char));
8185
if (op == NULL)
@@ -89,13 +93,15 @@ newsizedstringobject(str, size)
8993
if (str != NULL)
9094
memcpy(op->ob_sval, str, size);
9195
op->ob_sval[size] = '\0';
96+
#ifndef DONT_SHARE_SHORT_STRINGS
9297
if (size == 0) {
9398
nullstring = op;
9499
INCREF(op);
95100
} else if (size == 1 && str != NULL) {
96101
characters[*str & UCHAR_MAX] = op;
97102
INCREF(op);
98103
}
104+
#endif
99105
return (object *) op;
100106
}
101107

@@ -105,6 +111,7 @@ newstringobject(str)
105111
{
106112
register unsigned int size = strlen(str);
107113
register stringobject *op;
114+
#ifndef DONT_SHARE_SHORT_STRINGS
108115
if (size == 0 && (op = nullstring) != NULL) {
109116
#ifdef COUNT_ALLOCS
110117
null_strings++;
@@ -119,6 +126,7 @@ newstringobject(str)
119126
INCREF(op);
120127
return (object *)op;
121128
}
129+
#endif /* DONT_SHARE_SHORT_STRINGS */
122130
op = (stringobject *)
123131
malloc(sizeof(stringobject) + size * sizeof(char));
124132
if (op == NULL)
@@ -130,13 +138,15 @@ newstringobject(str)
130138
#endif
131139
NEWREF(op);
132140
strcpy(op->ob_sval, str);
141+
#ifndef DONT_SHARE_SHORT_STRINGS
133142
if (size == 0) {
134143
nullstring = op;
135144
INCREF(op);
136145
} else if (size == 1) {
137146
characters[*str & UCHAR_MAX] = op;
138147
INCREF(op);
139148
}
149+
#endif
140150
return (object *) op;
141151
}
142152

Objects/tupleobject.c

Lines changed: 47 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
3434
/* Entries 1 upto MAXSAVESIZE are free lists, entry 0 is the empty
3535
tuple () of which at most one instance will be allocated.
3636
*/
37-
static tupleobject *free_list[MAXSAVESIZE];
37+
static tupleobject *free_tuples[MAXSAVESIZE];
3838
#endif
3939
#ifdef COUNT_ALLOCS
4040
int fast_tuple_allocs;
@@ -52,16 +52,16 @@ newtupleobject(size)
5252
return NULL;
5353
}
5454
#if MAXSAVESIZE > 0
55-
if (size == 0 && free_list[0]) {
56-
op = free_list[0];
55+
if (size == 0 && free_tuples[0]) {
56+
op = free_tuples[0];
5757
INCREF(op);
5858
#ifdef COUNT_ALLOCS
5959
tuple_zero_allocs++;
6060
#endif
6161
return (object *) op;
6262
}
63-
if (0 < size && size < MAXSAVESIZE && (op = free_list[size]) != NULL) {
64-
free_list[size] = (tupleobject *) op->ob_item[0];
63+
if (0 < size && size < MAXSAVESIZE && (op = free_tuples[size]) != NULL) {
64+
free_tuples[size] = (tupleobject *) op->ob_item[0];
6565
#ifdef COUNT_ALLOCS
6666
fast_tuple_allocs++;
6767
#endif
@@ -80,7 +80,7 @@ newtupleobject(size)
8080
NEWREF(op);
8181
#if MAXSAVESIZE > 0
8282
if (size == 0) {
83-
free_list[0] = op;
83+
free_tuples[0] = op;
8484
INCREF(op); /* extra INCREF so that this is never freed */
8585
}
8686
#endif
@@ -149,8 +149,8 @@ tupledealloc(op)
149149
XDECREF(op->ob_item[i]);
150150
#if MAXSAVESIZE > 0
151151
if (0 < op->ob_size && op->ob_size < MAXSAVESIZE) {
152-
op->ob_item[0] = (object *) free_list[op->ob_size];
153-
free_list[op->ob_size] = op;
152+
op->ob_item[0] = (object *) free_tuples[op->ob_size];
153+
free_tuples[op->ob_size] = op;
154154
} else
155155
#endif
156156
free((ANY *)op);
@@ -397,36 +397,67 @@ typeobject Tupletype = {
397397
is only one module referencing the object. You can also think of it
398398
as creating a new tuple object and destroying the old one, only
399399
more efficiently. In any case, don't use this if the tuple may
400-
already be known to some other part of the code... */
400+
already be known to some other part of the code...
401+
If last_is_sticky is set, the tuple will grow or shrink at the
402+
front, otherwise it will grow or shrink at the end. */
401403

402404
int
403-
resizetuple(pv, newsize)
405+
resizetuple(pv, newsize, last_is_sticky)
404406
object **pv;
405407
int newsize;
408+
int last_is_sticky;
406409
{
407-
register object *v;
410+
register tupleobject *v;
408411
register tupleobject *sv;
409-
v = *pv;
412+
int i;
413+
int sizediff;
414+
415+
v = (tupleobject *) *pv;
416+
sizediff = newsize - v->ob_size;
410417
if (!is_tupleobject(v) || v->ob_refcnt != 1) {
411418
*pv = 0;
412419
DECREF(v);
413420
err_badcall();
414421
return -1;
415422
}
423+
if (sizediff == 0)
424+
return 0;
416425
/* XXX UNREF/NEWREF interface should be more symmetrical */
417426
#ifdef REF_DEBUG
418427
--ref_total;
419428
#endif
420429
UNREF(v);
421-
*pv = (object *)
430+
if (last_is_sticky && sizediff < 0) {
431+
/* shrinking: move entries to the front and zero moved entries */
432+
for (i = 0; i < newsize; i++) {
433+
XDECREF(v->ob_item[i]);
434+
v->ob_item[i] = v->ob_item[i - sizediff];
435+
v->ob_item[i - sizediff] = NULL;
436+
}
437+
}
438+
for (i = newsize; i < v->ob_size; i++) {
439+
XDECREF(v->ob_item[i]);
440+
v->ob_item[i] = NULL;
441+
}
442+
sv = (tupleobject *)
422443
realloc((char *)v,
423444
sizeof(tupleobject) + newsize * sizeof(object *));
424-
if (*pv == NULL) {
445+
*pv = (object *) sv;
446+
if (sv == NULL) {
425447
DEL(v);
426448
err_nomem();
427449
return -1;
428450
}
429-
NEWREF(*pv);
430-
((tupleobject *) *pv)->ob_size = newsize;
451+
NEWREF(sv);
452+
for (i = sv->ob_size; i < newsize; i++)
453+
sv->ob_item[i] = NULL;
454+
if (last_is_sticky && sizediff > 0) {
455+
/* growing: move entries to the end and zero moved entries */
456+
for (i = newsize - 1; i >= sizediff; i--) {
457+
sv->ob_item[i] = sv->ob_item[i - sizediff];
458+
sv->ob_item[i - sizediff] = NULL;
459+
}
460+
}
461+
sv->ob_size = newsize;
431462
return 0;
432463
}

Python/bltinmodule.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1319,7 +1319,7 @@ filtertuple(func, tuple)
13191319
}
13201320
}
13211321

1322-
if (resizetuple(&result, j) < 0)
1322+
if (resizetuple(&result, j, 0) < 0)
13231323
return NULL;
13241324

13251325
if (shared)

0 commit comments

Comments
 (0)