summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Objects/floatobject.c75
-rw-r--r--Objects/intobject.c73
2 files changed, 97 insertions, 51 deletions
diff --git a/Objects/floatobject.c b/Objects/floatobject.c
index c11f8f7..34fd317 100644
--- a/Objects/floatobject.c
+++ b/Objects/floatobject.c
@@ -94,24 +94,33 @@ double (*_Py_math_funcs_hack[])() = {
#endif
/* Special free list -- see comments for same code in intobject.c. */
-static PyFloatObject *free_list = NULL;
-static PyFloatObject *block_list = NULL;
#define BLOCK_SIZE 1000 /* 1K less typical malloc overhead */
-#define BHEAD_SIZE 8 /* Hope this is enough alignment */
+#define BHEAD_SIZE 8 /* Enough for a 64-bit pointer */
#define N_FLOATOBJECTS ((BLOCK_SIZE - BHEAD_SIZE) / sizeof(PyFloatObject))
+
#define PyMem_MALLOC malloc
#define PyMem_FREE free
+struct _floatblock {
+ struct _floatblock *next;
+ PyFloatObject objects[N_FLOATOBJECTS];
+};
+
+typedef struct _floatblock PyFloatBlock;
+
+static PyFloatBlock *block_list = NULL;
+static PyFloatObject *free_list = NULL;
+
static PyFloatObject *
fill_free_list()
{
PyFloatObject *p, *q;
- p = (PyFloatObject *)PyMem_MALLOC(BLOCK_SIZE);
+ p = (PyFloatObject *)PyMem_MALLOC(sizeof(PyFloatBlock));
if (p == NULL)
return (PyFloatObject *)PyErr_NoMemory();
- *(PyFloatObject **)p = block_list;
- block_list = p;
- p = (PyFloatObject *)((char *)p + BHEAD_SIZE);
+ ((PyFloatBlock *)p)->next = block_list;
+ block_list = (PyFloatBlock *)p;
+ p = &((PyFloatBlock *)p)->objects[0];
q = p + N_FLOATOBJECTS;
while (--q > p)
q->ob_type = (struct _typeobject *)(q-1);
@@ -611,7 +620,8 @@ PyTypeObject PyFloat_Type = {
void
PyFloat_Fini()
{
- PyFloatObject *p, *list;
+ PyFloatObject *p;
+ PyFloatBlock *list, *next;
int i;
int bc, bf; /* block count, number of freed blocks */
int frem, fsum; /* remaining unfreed floats per block, total */
@@ -622,36 +632,51 @@ PyFloat_Fini()
list = block_list;
block_list = NULL;
while (list != NULL) {
- p = list;
- p = (PyFloatObject *)((char *)p + BHEAD_SIZE);
+ p = &list->objects[0];
bc++;
frem = 0;
for (i = 0; i < N_FLOATOBJECTS; i++, p++) {
if (PyFloat_Check(p) && p->ob_refcnt != 0)
frem++;
}
- p = list;
- list = *(PyFloatObject **)p;
+ next = list->next;
if (frem) {
- *(PyFloatObject **)p = block_list;
- block_list = p;
+ list->next = block_list;
+ block_list = list;
}
else {
- PyMem_FREE(p);
+ PyMem_FREE(list);
bf++;
}
fsum += frem;
+ list = next;
}
- if (Py_VerboseFlag) {
- fprintf(stderr, "# cleanup floats");
- if (!fsum) {
- fprintf(stderr, "\n");
- }
- else {
- fprintf(stderr,
- ": %d unfreed float%s in %d out of %d block%s\n",
- fsum, fsum == 1 ? "" : "s",
- bc - bf, bc, bc == 1 ? "" : "s");
+ if (!Py_VerboseFlag)
+ return;
+ fprintf(stderr, "# cleanup floats");
+ if (!fsum) {
+ fprintf(stderr, "\n");
+ }
+ else {
+ fprintf(stderr,
+ ": %d unfreed float%s in %d out of %d block%s\n",
+ fsum, fsum == 1 ? "" : "s",
+ bc - bf, bc, bc == 1 ? "" : "s");
+ }
+ if (Py_VerboseFlag > 1) {
+ list = block_list;
+ while (list != NULL) {
+ p = &list->objects[0];
+ for (i = 0; i < N_FLOATOBJECTS; i++, p++) {
+ if (PyFloat_Check(p) && p->ob_refcnt != 0) {
+ char buf[100];
+ PyFloat_AsString(buf, p);
+ fprintf(stderr,
+ "# <float object at %lx, refcnt=%d, val=%s>\n",
+ p, p->ob_refcnt, buf);
+ }
+ }
+ list = list->next;
}
}
}
diff --git a/Objects/intobject.c b/Objects/intobject.c
index fa24824..0bf1fc5 100644
--- a/Objects/intobject.c
+++ b/Objects/intobject.c
@@ -90,23 +90,32 @@ err_ovf(msg)
*/
#define BLOCK_SIZE 1000 /* 1K less typical malloc overhead */
-#define N_INTOBJECTS ((BLOCK_SIZE - sizeof(PyIntObject *)) / \
- sizeof(PyIntObject))
+#define BHEAD_SIZE 8 /* Enough for a 64-bit pointer */
+#define N_INTOBJECTS ((BLOCK_SIZE - BHEAD_SIZE) / sizeof(PyIntObject))
#define PyMem_MALLOC malloc
#define PyMem_FREE free
-static PyIntObject *block_list = NULL;
+
+struct _intblock {
+ struct _intblock *next;
+ PyIntObject objects[N_INTOBJECTS];
+};
+
+typedef struct _intblock PyIntBlock;
+
+static PyIntBlock *block_list = NULL;
+static PyIntObject *free_list = NULL;
static PyIntObject *
fill_free_list()
{
PyIntObject *p, *q;
- p = (PyIntObject *)PyMem_MALLOC(BLOCK_SIZE);
+ p = (PyIntObject *)PyMem_MALLOC(sizeof(PyIntBlock));
if (p == NULL)
return (PyIntObject *)PyErr_NoMemory();
- *(PyIntObject **)p = block_list;
- block_list = p;
- p = (PyIntObject *)((char *)p + sizeof(PyIntObject *));
+ ((PyIntBlock *)p)->next = block_list;
+ block_list = (PyIntBlock *)p;
+ p = &((PyIntBlock *)p)->objects[0];
q = p + N_INTOBJECTS;
while (--q > p)
q->ob_type = (struct _typeobject *)(q-1);
@@ -114,7 +123,6 @@ fill_free_list()
return p + N_INTOBJECTS - 1;
}
-static PyIntObject *free_list = NULL;
#ifndef NSMALLPOSINTS
#define NSMALLPOSINTS 100
#endif
@@ -802,7 +810,8 @@ PyTypeObject PyInt_Type = {
void
PyInt_Fini()
{
- PyIntObject *p, *list;
+ PyIntObject *p;
+ PyIntBlock *list, *next;
int i;
int bc, bf; /* block count, number of freed blocks */
int irem, isum; /* remaining unfreed ints per block, total */
@@ -823,36 +832,48 @@ PyInt_Fini()
list = block_list;
block_list = NULL;
while (list != NULL) {
- p = list;
- p = (PyIntObject *)((char *)p + sizeof(PyIntObject *));
+ p = &list->objects[0];
bc++;
irem = 0;
for (i = 0; i < N_INTOBJECTS; i++, p++) {
if (PyInt_Check(p) && p->ob_refcnt != 0)
irem++;
}
- p = list;
- list = *(PyIntObject **)p;
+ next = list->next;
if (irem) {
- *(PyIntObject **)p = block_list;
- block_list = p;
+ list->next = block_list;
+ block_list = list;
}
else {
- PyMem_FREE(p);
+ PyMem_FREE(list);
bf++;
}
isum += irem;
+ list = next;
}
- if (Py_VerboseFlag) {
- fprintf(stderr, "# cleanup ints");
- if (!isum) {
- fprintf(stderr, "\n");
- }
- else {
- fprintf(stderr,
- ": %d unfreed int%s in %d out of %d block%s\n",
- isum, isum == 1 ? "" : "s",
- bc - bf, bc, bc == 1 ? "" : "s");
+ if (!Py_VerboseFlag)
+ return;
+ fprintf(stderr, "# cleanup ints");
+ if (!isum) {
+ fprintf(stderr, "\n");
+ }
+ else {
+ fprintf(stderr,
+ ": %d unfreed int%s in %d out of %d block%s\n",
+ isum, isum == 1 ? "" : "s",
+ bc - bf, bc, bc == 1 ? "" : "s");
+ }
+ if (Py_VerboseFlag > 1) {
+ list = block_list;
+ while (list != NULL) {
+ p = &list->objects[0];
+ for (i = 0; i < N_INTOBJECTS; i++, p++) {
+ if (PyInt_Check(p) && p->ob_refcnt != 0)
+ fprintf(stderr,
+ "# <int object at %lx, refcnt=%d, val=%ld>\n",
+ p, p->ob_refcnt, p->ob_ival);
+ }
+ list = list->next;
}
}
}