summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSjoerd Mullender <sjoerd@acm.org>1993-11-01 13:46:50 (GMT)
committerSjoerd Mullender <sjoerd@acm.org>1993-11-01 13:46:50 (GMT)
commit615194a3526ce2cd50a255113470ba24e3fca0b9 (patch)
treeb4619ccf736036474866cbbe53a22bafd96b6bc0
parent0a2fa75a9c2d6618b5fc9e4745551adfc7dd4aba (diff)
downloadcpython-615194a3526ce2cd50a255113470ba24e3fca0b9.zip
cpython-615194a3526ce2cd50a255113470ba24e3fca0b9.tar.gz
cpython-615194a3526ce2cd50a255113470ba24e3fca0b9.tar.bz2
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.
-rw-r--r--Include/tupleobject.h2
-rw-r--r--Objects/stringobject.c10
-rw-r--r--Objects/tupleobject.c63
-rw-r--r--Python/bltinmodule.c2
4 files changed, 59 insertions, 18 deletions
diff --git a/Include/tupleobject.h b/Include/tupleobject.h
index 8fe28a2..9897f6d 100644
--- a/Include/tupleobject.h
+++ b/Include/tupleobject.h
@@ -58,7 +58,7 @@ extern int gettuplesize PROTO((object *));
extern object *gettupleitem PROTO((object *, int));
extern int settupleitem PROTO((object *, int, object *));
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 */
#define GETTUPLEITEM(op, i) ((op)->ob_item[i])
diff --git a/Objects/stringobject.c b/Objects/stringobject.c
index 61863b6..0d03a3b 100644
--- a/Objects/stringobject.c
+++ b/Objects/stringobject.c
@@ -39,7 +39,9 @@ int null_strings, one_strings;
#endif
static stringobject *characters[UCHAR_MAX + 1];
+#ifndef DONT_SHARE_SHORT_STRINGS
static stringobject *nullstring;
+#endif
/*
Newsizedstringobject() and newstringobject() try in certain cases
@@ -62,6 +64,7 @@ newsizedstringobject(str, size)
int size;
{
register stringobject *op;
+#ifndef DONT_SHARE_SHORT_STRINGS
if (size == 0 && (op = nullstring) != NULL) {
#ifdef COUNT_ALLOCS
null_strings++;
@@ -76,6 +79,7 @@ newsizedstringobject(str, size)
INCREF(op);
return (object *)op;
}
+#endif /* DONT_SHARE_SHORT_STRINGS */
op = (stringobject *)
malloc(sizeof(stringobject) + size * sizeof(char));
if (op == NULL)
@@ -89,6 +93,7 @@ newsizedstringobject(str, size)
if (str != NULL)
memcpy(op->ob_sval, str, size);
op->ob_sval[size] = '\0';
+#ifndef DONT_SHARE_SHORT_STRINGS
if (size == 0) {
nullstring = op;
INCREF(op);
@@ -96,6 +101,7 @@ newsizedstringobject(str, size)
characters[*str & UCHAR_MAX] = op;
INCREF(op);
}
+#endif
return (object *) op;
}
@@ -105,6 +111,7 @@ newstringobject(str)
{
register unsigned int size = strlen(str);
register stringobject *op;
+#ifndef DONT_SHARE_SHORT_STRINGS
if (size == 0 && (op = nullstring) != NULL) {
#ifdef COUNT_ALLOCS
null_strings++;
@@ -119,6 +126,7 @@ newstringobject(str)
INCREF(op);
return (object *)op;
}
+#endif /* DONT_SHARE_SHORT_STRINGS */
op = (stringobject *)
malloc(sizeof(stringobject) + size * sizeof(char));
if (op == NULL)
@@ -130,6 +138,7 @@ newstringobject(str)
#endif
NEWREF(op);
strcpy(op->ob_sval, str);
+#ifndef DONT_SHARE_SHORT_STRINGS
if (size == 0) {
nullstring = op;
INCREF(op);
@@ -137,6 +146,7 @@ newstringobject(str)
characters[*str & UCHAR_MAX] = op;
INCREF(op);
}
+#endif
return (object *) op;
}
diff --git a/Objects/tupleobject.c b/Objects/tupleobject.c
index 0047a09..68fed9e 100644
--- a/Objects/tupleobject.c
+++ b/Objects/tupleobject.c
@@ -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
tuple () of which at most one instance will be allocated.
*/
-static tupleobject *free_list[MAXSAVESIZE];
+static tupleobject *free_tuples[MAXSAVESIZE];
#endif
#ifdef COUNT_ALLOCS
int fast_tuple_allocs;
@@ -52,16 +52,16 @@ newtupleobject(size)
return NULL;
}
#if MAXSAVESIZE > 0
- if (size == 0 && free_list[0]) {
- op = free_list[0];
+ if (size == 0 && free_tuples[0]) {
+ op = free_tuples[0];
INCREF(op);
#ifdef COUNT_ALLOCS
tuple_zero_allocs++;
#endif
return (object *) op;
}
- if (0 < size && size < MAXSAVESIZE && (op = free_list[size]) != NULL) {
- free_list[size] = (tupleobject *) op->ob_item[0];
+ if (0 < size && size < MAXSAVESIZE && (op = free_tuples[size]) != NULL) {
+ free_tuples[size] = (tupleobject *) op->ob_item[0];
#ifdef COUNT_ALLOCS
fast_tuple_allocs++;
#endif
@@ -80,7 +80,7 @@ newtupleobject(size)
NEWREF(op);
#if MAXSAVESIZE > 0
if (size == 0) {
- free_list[0] = op;
+ free_tuples[0] = op;
INCREF(op); /* extra INCREF so that this is never freed */
}
#endif
@@ -149,8 +149,8 @@ tupledealloc(op)
XDECREF(op->ob_item[i]);
#if MAXSAVESIZE > 0
if (0 < op->ob_size && op->ob_size < MAXSAVESIZE) {
- op->ob_item[0] = (object *) free_list[op->ob_size];
- free_list[op->ob_size] = op;
+ op->ob_item[0] = (object *) free_tuples[op->ob_size];
+ free_tuples[op->ob_size] = op;
} else
#endif
free((ANY *)op);
@@ -397,36 +397,67 @@ typeobject Tupletype = {
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... */
+ 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
-resizetuple(pv, newsize)
+resizetuple(pv, newsize, last_is_sticky)
object **pv;
int newsize;
+ int last_is_sticky;
{
- register object *v;
+ register tupleobject *v;
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) {
*pv = 0;
DECREF(v);
err_badcall();
return -1;
}
+ if (sizediff == 0)
+ return 0;
/* XXX UNREF/NEWREF interface should be more symmetrical */
#ifdef REF_DEBUG
--ref_total;
#endif
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,
sizeof(tupleobject) + newsize * sizeof(object *));
- if (*pv == NULL) {
+ *pv = (object *) sv;
+ if (sv == NULL) {
DEL(v);
err_nomem();
return -1;
}
- NEWREF(*pv);
- ((tupleobject *) *pv)->ob_size = newsize;
+ NEWREF(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;
+ }
+ }
+ sv->ob_size = newsize;
return 0;
}
diff --git a/Python/bltinmodule.c b/Python/bltinmodule.c
index f4d7f47..6069ae0 100644
--- a/Python/bltinmodule.c
+++ b/Python/bltinmodule.c
@@ -1319,7 +1319,7 @@ filtertuple(func, tuple)
}
}
- if (resizetuple(&result, j) < 0)
+ if (resizetuple(&result, j, 0) < 0)
return NULL;
if (shared)