mirror of
https://github.com/python/cpython.git
synced 2025-07-24 03:35:53 +00:00
Vladimir has restructured his code somewhat so that the blocks are now
represented by an explicit structure. (There are still too many casts in the code, but that may be unavoidable.) Also added code so that with -vv it is very chatty about what it does.
This commit is contained in:
parent
4edf656402
commit
3fce883922
2 changed files with 97 additions and 51 deletions
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue