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

Skip to content

Commit 615194a

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 0a2fa75 commit 615194a

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)