mirror of
https://github.com/python/cpython.git
synced 2025-11-02 19:12:55 +00:00
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.
This commit is contained in:
parent
0a2fa75a9c
commit
615194a352
4 changed files with 59 additions and 18 deletions
|
|
@ -58,7 +58,7 @@ extern int gettuplesize PROTO((object *));
|
||||||
extern object *gettupleitem PROTO((object *, int));
|
extern object *gettupleitem PROTO((object *, int));
|
||||||
extern int settupleitem PROTO((object *, int, object *));
|
extern int settupleitem PROTO((object *, int, object *));
|
||||||
extern object *gettupleslice PROTO((object *, int, int));
|
extern object *gettupleslice PROTO((object *, int, int));
|
||||||
extern int resizetuple PROTO((object **, int));
|
extern int resizetuple PROTO((object **, int, int));
|
||||||
|
|
||||||
/* Macro, trading safety for speed */
|
/* Macro, trading safety for speed */
|
||||||
#define GETTUPLEITEM(op, i) ((op)->ob_item[i])
|
#define GETTUPLEITEM(op, i) ((op)->ob_item[i])
|
||||||
|
|
|
||||||
|
|
@ -39,7 +39,9 @@ int null_strings, one_strings;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static stringobject *characters[UCHAR_MAX + 1];
|
static stringobject *characters[UCHAR_MAX + 1];
|
||||||
|
#ifndef DONT_SHARE_SHORT_STRINGS
|
||||||
static stringobject *nullstring;
|
static stringobject *nullstring;
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Newsizedstringobject() and newstringobject() try in certain cases
|
Newsizedstringobject() and newstringobject() try in certain cases
|
||||||
|
|
@ -62,6 +64,7 @@ newsizedstringobject(str, size)
|
||||||
int size;
|
int size;
|
||||||
{
|
{
|
||||||
register stringobject *op;
|
register stringobject *op;
|
||||||
|
#ifndef DONT_SHARE_SHORT_STRINGS
|
||||||
if (size == 0 && (op = nullstring) != NULL) {
|
if (size == 0 && (op = nullstring) != NULL) {
|
||||||
#ifdef COUNT_ALLOCS
|
#ifdef COUNT_ALLOCS
|
||||||
null_strings++;
|
null_strings++;
|
||||||
|
|
@ -76,6 +79,7 @@ newsizedstringobject(str, size)
|
||||||
INCREF(op);
|
INCREF(op);
|
||||||
return (object *)op;
|
return (object *)op;
|
||||||
}
|
}
|
||||||
|
#endif /* DONT_SHARE_SHORT_STRINGS */
|
||||||
op = (stringobject *)
|
op = (stringobject *)
|
||||||
malloc(sizeof(stringobject) + size * sizeof(char));
|
malloc(sizeof(stringobject) + size * sizeof(char));
|
||||||
if (op == NULL)
|
if (op == NULL)
|
||||||
|
|
@ -89,6 +93,7 @@ newsizedstringobject(str, size)
|
||||||
if (str != NULL)
|
if (str != NULL)
|
||||||
memcpy(op->ob_sval, str, size);
|
memcpy(op->ob_sval, str, size);
|
||||||
op->ob_sval[size] = '\0';
|
op->ob_sval[size] = '\0';
|
||||||
|
#ifndef DONT_SHARE_SHORT_STRINGS
|
||||||
if (size == 0) {
|
if (size == 0) {
|
||||||
nullstring = op;
|
nullstring = op;
|
||||||
INCREF(op);
|
INCREF(op);
|
||||||
|
|
@ -96,6 +101,7 @@ newsizedstringobject(str, size)
|
||||||
characters[*str & UCHAR_MAX] = op;
|
characters[*str & UCHAR_MAX] = op;
|
||||||
INCREF(op);
|
INCREF(op);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
return (object *) op;
|
return (object *) op;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -105,6 +111,7 @@ newstringobject(str)
|
||||||
{
|
{
|
||||||
register unsigned int size = strlen(str);
|
register unsigned int size = strlen(str);
|
||||||
register stringobject *op;
|
register stringobject *op;
|
||||||
|
#ifndef DONT_SHARE_SHORT_STRINGS
|
||||||
if (size == 0 && (op = nullstring) != NULL) {
|
if (size == 0 && (op = nullstring) != NULL) {
|
||||||
#ifdef COUNT_ALLOCS
|
#ifdef COUNT_ALLOCS
|
||||||
null_strings++;
|
null_strings++;
|
||||||
|
|
@ -119,6 +126,7 @@ newstringobject(str)
|
||||||
INCREF(op);
|
INCREF(op);
|
||||||
return (object *)op;
|
return (object *)op;
|
||||||
}
|
}
|
||||||
|
#endif /* DONT_SHARE_SHORT_STRINGS */
|
||||||
op = (stringobject *)
|
op = (stringobject *)
|
||||||
malloc(sizeof(stringobject) + size * sizeof(char));
|
malloc(sizeof(stringobject) + size * sizeof(char));
|
||||||
if (op == NULL)
|
if (op == NULL)
|
||||||
|
|
@ -130,6 +138,7 @@ newstringobject(str)
|
||||||
#endif
|
#endif
|
||||||
NEWREF(op);
|
NEWREF(op);
|
||||||
strcpy(op->ob_sval, str);
|
strcpy(op->ob_sval, str);
|
||||||
|
#ifndef DONT_SHARE_SHORT_STRINGS
|
||||||
if (size == 0) {
|
if (size == 0) {
|
||||||
nullstring = op;
|
nullstring = op;
|
||||||
INCREF(op);
|
INCREF(op);
|
||||||
|
|
@ -137,6 +146,7 @@ newstringobject(str)
|
||||||
characters[*str & UCHAR_MAX] = op;
|
characters[*str & UCHAR_MAX] = op;
|
||||||
INCREF(op);
|
INCREF(op);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
return (object *) op;
|
return (object *) op;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,7 @@ OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
/* Entries 1 upto MAXSAVESIZE are free lists, entry 0 is the empty
|
/* Entries 1 upto MAXSAVESIZE are free lists, entry 0 is the empty
|
||||||
tuple () of which at most one instance will be allocated.
|
tuple () of which at most one instance will be allocated.
|
||||||
*/
|
*/
|
||||||
static tupleobject *free_list[MAXSAVESIZE];
|
static tupleobject *free_tuples[MAXSAVESIZE];
|
||||||
#endif
|
#endif
|
||||||
#ifdef COUNT_ALLOCS
|
#ifdef COUNT_ALLOCS
|
||||||
int fast_tuple_allocs;
|
int fast_tuple_allocs;
|
||||||
|
|
@ -52,16 +52,16 @@ newtupleobject(size)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
#if MAXSAVESIZE > 0
|
#if MAXSAVESIZE > 0
|
||||||
if (size == 0 && free_list[0]) {
|
if (size == 0 && free_tuples[0]) {
|
||||||
op = free_list[0];
|
op = free_tuples[0];
|
||||||
INCREF(op);
|
INCREF(op);
|
||||||
#ifdef COUNT_ALLOCS
|
#ifdef COUNT_ALLOCS
|
||||||
tuple_zero_allocs++;
|
tuple_zero_allocs++;
|
||||||
#endif
|
#endif
|
||||||
return (object *) op;
|
return (object *) op;
|
||||||
}
|
}
|
||||||
if (0 < size && size < MAXSAVESIZE && (op = free_list[size]) != NULL) {
|
if (0 < size && size < MAXSAVESIZE && (op = free_tuples[size]) != NULL) {
|
||||||
free_list[size] = (tupleobject *) op->ob_item[0];
|
free_tuples[size] = (tupleobject *) op->ob_item[0];
|
||||||
#ifdef COUNT_ALLOCS
|
#ifdef COUNT_ALLOCS
|
||||||
fast_tuple_allocs++;
|
fast_tuple_allocs++;
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -80,7 +80,7 @@ newtupleobject(size)
|
||||||
NEWREF(op);
|
NEWREF(op);
|
||||||
#if MAXSAVESIZE > 0
|
#if MAXSAVESIZE > 0
|
||||||
if (size == 0) {
|
if (size == 0) {
|
||||||
free_list[0] = op;
|
free_tuples[0] = op;
|
||||||
INCREF(op); /* extra INCREF so that this is never freed */
|
INCREF(op); /* extra INCREF so that this is never freed */
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -149,8 +149,8 @@ tupledealloc(op)
|
||||||
XDECREF(op->ob_item[i]);
|
XDECREF(op->ob_item[i]);
|
||||||
#if MAXSAVESIZE > 0
|
#if MAXSAVESIZE > 0
|
||||||
if (0 < op->ob_size && op->ob_size < MAXSAVESIZE) {
|
if (0 < op->ob_size && op->ob_size < MAXSAVESIZE) {
|
||||||
op->ob_item[0] = (object *) free_list[op->ob_size];
|
op->ob_item[0] = (object *) free_tuples[op->ob_size];
|
||||||
free_list[op->ob_size] = op;
|
free_tuples[op->ob_size] = op;
|
||||||
} else
|
} else
|
||||||
#endif
|
#endif
|
||||||
free((ANY *)op);
|
free((ANY *)op);
|
||||||
|
|
@ -397,36 +397,67 @@ typeobject Tupletype = {
|
||||||
is only one module referencing the object. You can also think of it
|
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
|
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
|
more efficiently. In any case, don't use this if the tuple may
|
||||||
already be known to some other part of the code... */
|
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. */
|
||||||
|
|
||||||
int
|
int
|
||||||
resizetuple(pv, newsize)
|
resizetuple(pv, newsize, last_is_sticky)
|
||||||
object **pv;
|
object **pv;
|
||||||
int newsize;
|
int newsize;
|
||||||
|
int last_is_sticky;
|
||||||
{
|
{
|
||||||
register object *v;
|
register tupleobject *v;
|
||||||
register tupleobject *sv;
|
register tupleobject *sv;
|
||||||
v = *pv;
|
int i;
|
||||||
|
int sizediff;
|
||||||
|
|
||||||
|
v = (tupleobject *) *pv;
|
||||||
|
sizediff = newsize - v->ob_size;
|
||||||
if (!is_tupleobject(v) || v->ob_refcnt != 1) {
|
if (!is_tupleobject(v) || v->ob_refcnt != 1) {
|
||||||
*pv = 0;
|
*pv = 0;
|
||||||
DECREF(v);
|
DECREF(v);
|
||||||
err_badcall();
|
err_badcall();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
if (sizediff == 0)
|
||||||
|
return 0;
|
||||||
/* XXX UNREF/NEWREF interface should be more symmetrical */
|
/* XXX UNREF/NEWREF interface should be more symmetrical */
|
||||||
#ifdef REF_DEBUG
|
#ifdef REF_DEBUG
|
||||||
--ref_total;
|
--ref_total;
|
||||||
#endif
|
#endif
|
||||||
UNREF(v);
|
UNREF(v);
|
||||||
*pv = (object *)
|
if (last_is_sticky && sizediff < 0) {
|
||||||
|
/* shrinking: move entries to the front and zero moved entries */
|
||||||
|
for (i = 0; i < newsize; i++) {
|
||||||
|
XDECREF(v->ob_item[i]);
|
||||||
|
v->ob_item[i] = v->ob_item[i - sizediff];
|
||||||
|
v->ob_item[i - sizediff] = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (i = newsize; i < v->ob_size; i++) {
|
||||||
|
XDECREF(v->ob_item[i]);
|
||||||
|
v->ob_item[i] = NULL;
|
||||||
|
}
|
||||||
|
sv = (tupleobject *)
|
||||||
realloc((char *)v,
|
realloc((char *)v,
|
||||||
sizeof(tupleobject) + newsize * sizeof(object *));
|
sizeof(tupleobject) + newsize * sizeof(object *));
|
||||||
if (*pv == NULL) {
|
*pv = (object *) sv;
|
||||||
|
if (sv == NULL) {
|
||||||
DEL(v);
|
DEL(v);
|
||||||
err_nomem();
|
err_nomem();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
NEWREF(*pv);
|
NEWREF(sv);
|
||||||
((tupleobject *) *pv)->ob_size = newsize;
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sv->ob_size = newsize;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1319,7 +1319,7 @@ filtertuple(func, tuple)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (resizetuple(&result, j) < 0)
|
if (resizetuple(&result, j, 0) < 0)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
if (shared)
|
if (shared)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue