- Issue #2862: Make int and float freelist management consistent with other

freelists.  Changes their CompactFreeList apis into ClearFreeList apis and
  calls them via gc.collect().
This commit is contained in:
Gregory P. Smith 2008-07-06 03:35:58 +00:00
parent 17f2e4acb9
commit 2fe77060eb
11 changed files with 62 additions and 107 deletions

View file

@ -1608,30 +1608,28 @@ _PyFloat_Init(void)
PyStructSequence_InitType(&FloatInfoType, &floatinfo_desc);
}
void
PyFloat_CompactFreeList(size_t *pbc, size_t *pbf, size_t *bsum)
int
PyFloat_ClearFreeList(void)
{
PyFloatObject *p;
PyFloatBlock *list, *next;
unsigned i;
size_t bc = 0, bf = 0; /* block count, number of freed blocks */
size_t fsum = 0; /* total unfreed ints */
int frem; /* remaining unfreed ints per block */
int i;
int u; /* remaining unfreed ints per block */
int freelist_size = 0;
list = block_list;
block_list = NULL;
free_list = NULL;
while (list != NULL) {
bc++;
frem = 0;
u = 0;
for (i = 0, p = &list->objects[0];
i < N_FLOATOBJECTS;
i++, p++) {
if (PyFloat_CheckExact(p) && Py_REFCNT(p) != 0)
frem++;
u++;
}
next = list->next;
if (frem) {
if (u) {
list->next = block_list;
block_list = list;
for (i = 0, p = &list->objects[0];
@ -1646,15 +1644,12 @@ PyFloat_CompactFreeList(size_t *pbc, size_t *pbf, size_t *bsum)
}
}
else {
PyMem_FREE(list); /* XXX PyObject_FREE ??? */
bf++;
PyMem_FREE(list);
}
fsum += frem;
freelist_size += u;
list = next;
}
*pbc = bc;
*pbf = bf;
*bsum = fsum;
return freelist_size;
}
void
@ -1662,25 +1657,21 @@ PyFloat_Fini(void)
{
PyFloatObject *p;
PyFloatBlock *list;
unsigned i;
size_t bc, bf; /* block count, number of freed blocks */
size_t fsum; /* total unfreed floats per block */
int i;
int u; /* total unfreed floats per block */
PyFloat_CompactFreeList(&bc, &bf, &fsum);
u = PyFloat_ClearFreeList();
if (!Py_VerboseFlag)
return;
fprintf(stderr, "# cleanup floats");
if (!fsum) {
if (!u) {
fprintf(stderr, "\n");
}
else {
fprintf(stderr,
": %" PY_FORMAT_SIZE_T "d unfreed float%s in %"
PY_FORMAT_SIZE_T "d out of %"
PY_FORMAT_SIZE_T "d block%s\n",
fsum, fsum == 1 ? "" : "s",
bc - bf, bc, bc == 1 ? "" : "s");
": %d unfreed float%s\n",
u, u == 1 ? "" : "s");
}
if (Py_VerboseFlag > 1) {
list = block_list;

View file

@ -1296,35 +1296,33 @@ _PyInt_Init(void)
return 1;
}
void
PyInt_CompactFreeList(size_t *pbc, size_t *pbf, size_t *bsum)
int
PyInt_ClearFreeList(void)
{
PyIntObject *p;
PyIntBlock *list, *next;
unsigned int ctr;
size_t bc = 0, bf = 0; /* block count, number of freed blocks */
size_t isum = 0; /* total unfreed ints */
int irem; /* remaining unfreed ints per block */
int i;
int u; /* remaining unfreed ints per block */
int freelist_size = 0;
list = block_list;
block_list = NULL;
free_list = NULL;
while (list != NULL) {
bc++;
irem = 0;
for (ctr = 0, p = &list->objects[0];
ctr < N_INTOBJECTS;
ctr++, p++) {
u = 0;
for (i = 0, p = &list->objects[0];
i < N_INTOBJECTS;
i++, p++) {
if (PyInt_CheckExact(p) && p->ob_refcnt != 0)
irem++;
u++;
}
next = list->next;
if (irem) {
if (u) {
list->next = block_list;
block_list = list;
for (ctr = 0, p = &list->objects[0];
ctr < N_INTOBJECTS;
ctr++, p++) {
for (i = 0, p = &list->objects[0];
i < N_INTOBJECTS;
i++, p++) {
if (!PyInt_CheckExact(p) ||
p->ob_refcnt == 0) {
Py_TYPE(p) = (struct _typeobject *)
@ -1345,15 +1343,12 @@ PyInt_CompactFreeList(size_t *pbc, size_t *pbf, size_t *bsum)
}
else {
PyMem_FREE(list);
bf++;
}
isum += irem;
freelist_size += u;
list = next;
}
*pbc = bc;
*pbf = bf;
*bsum = isum;
return freelist_size;
}
void
@ -1361,12 +1356,10 @@ PyInt_Fini(void)
{
PyIntObject *p;
PyIntBlock *list;
unsigned int ctr;
size_t bc, bf; /* block count, number of freed blocks */
size_t isum; /* total unfreed ints per block */
int i;
int u; /* total unfreed ints per block */
#if NSMALLNEGINTS + NSMALLPOSINTS > 0
int i;
PyIntObject **q;
i = NSMALLNEGINTS + NSMALLPOSINTS;
@ -1376,27 +1369,24 @@ PyInt_Fini(void)
*q++ = NULL;
}
#endif
PyInt_CompactFreeList(&bc, &bf, &isum);
u = PyInt_ClearFreeList();
if (!Py_VerboseFlag)
return;
fprintf(stderr, "# cleanup ints");
if (!isum) {
if (!u) {
fprintf(stderr, "\n");
}
else {
fprintf(stderr,
": %" PY_FORMAT_SIZE_T "d unfreed int%s in %"
PY_FORMAT_SIZE_T "d out of %"
PY_FORMAT_SIZE_T "d block%s\n",
isum, isum == 1 ? "" : "s",
bc - bf, bc, bc == 1 ? "" : "s");
": %d unfreed int%s\n",
u, u == 1 ? "" : "s");
}
if (Py_VerboseFlag > 1) {
list = block_list;
while (list != NULL) {
for (ctr = 0, p = &list->objects[0];
ctr < N_INTOBJECTS;
ctr++, p++) {
for (i = 0, p = &list->objects[0];
i < N_INTOBJECTS;
i++, p++) {
if (PyInt_CheckExact(p) && p->ob_refcnt != 0)
/* XXX(twouters) cast refcount to
long until %zd is universally