--- Objects/floatobject.c.orig Thu Feb 7 21:50:07 2008 +++ Objects/floatobject.c Thu Feb 7 22:26:07 2008 @@ -21,39 +21,6 @@ extern int finite(double); #endif -/* Special free list -- see comments for same code in intobject.c. */ -#define BLOCK_SIZE 1000 /* 1K less typical malloc overhead */ -#define BHEAD_SIZE 8 /* Enough for a 64-bit pointer */ -#define N_FLOATOBJECTS ((BLOCK_SIZE - BHEAD_SIZE) / sizeof(PyFloatObject)) - -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(void) -{ - PyFloatObject *p, *q; - /* XXX Float blocks escape the object heap. Use PyObject_MALLOC ??? */ - p = (PyFloatObject *) PyMem_MALLOC(sizeof(PyFloatBlock)); - if (p == NULL) - return (PyFloatObject *) PyErr_NoMemory(); - ((PyFloatBlock *)p)->next = block_list; - block_list = (PyFloatBlock *)p; - p = &((PyFloatBlock *)p)->objects[0]; - q = p + N_FLOATOBJECTS; - while (--q > p) - Py_TYPE(q) = (struct _typeobject *)(q-1); - Py_TYPE(q) = NULL; - return p + N_FLOATOBJECTS - 1; -} - double PyFloat_GetMax(void) { @@ -143,13 +110,11 @@ PyFloat_FromDouble(double fval) { register PyFloatObject *op; - if (free_list == NULL) { - if ((free_list = fill_free_list()) == NULL) - return NULL; - } + /* Inline PyObject_New */ - op = free_list; - free_list = (PyFloatObject *)Py_TYPE(op); + op = (PyFloatObject *) PyObject_MALLOC(_PyObject_SIZE(&PyFloat_Type)); + if (op == NULL) + return PyErr_NoMemory(); PyObject_INIT(op, &PyFloat_Type); op->ob_fval = fval; return (PyObject *) op; @@ -287,10 +252,8 @@ static void float_dealloc(PyFloatObject *op) { - if (PyFloat_CheckExact(op)) { - Py_TYPE(op) = (struct _typeobject *)free_list; - free_list = op; - } + if (PyFloat_CheckExact(op)) + PyObject_Del((PyObject *)op); else Py_TYPE(op)->tp_free((PyObject *)op); } @@ -1611,99 +1574,11 @@ void PyFloat_CompactFreeList(size_t *pbc, size_t *pbf, size_t *bsum) { - 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 */ - - list = block_list; - block_list = NULL; - free_list = NULL; - while (list != NULL) { - bc++; - frem = 0; - for (i = 0, p = &list->objects[0]; - i < N_FLOATOBJECTS; - i++, p++) { - if (PyFloat_CheckExact(p) && Py_REFCNT(p) != 0) - frem++; - } - next = list->next; - if (frem) { - list->next = block_list; - block_list = list; - for (i = 0, p = &list->objects[0]; - i < N_FLOATOBJECTS; - i++, p++) { - if (!PyFloat_CheckExact(p) || - Py_REFCNT(p) == 0) { - Py_TYPE(p) = (struct _typeobject *) - free_list; - free_list = p; - } - } - } - else { - PyMem_FREE(list); /* XXX PyObject_FREE ??? */ - bf++; - } - fsum += frem; - list = next; - } - *pbc = bc; - *pbf = bf; - *bsum = fsum; } void 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 */ - - PyFloat_CompactFreeList(&bc, &bf, &fsum); - - if (!Py_VerboseFlag) - return; - fprintf(stderr, "# cleanup floats"); - if (!fsum) { - fprintf(stderr, "\n"); - } - else { - fprintf(stderr, - ": %" PY_FORMAT_SIZE_T "d unfreed floats%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"); - } - if (Py_VerboseFlag > 1) { - list = block_list; - while (list != NULL) { - for (i = 0, p = &list->objects[0]; - i < N_FLOATOBJECTS; - i++, p++) { - if (PyFloat_CheckExact(p) && - Py_REFCNT(p) != 0) { - char buf[100]; - PyFloat_AsString(buf, p); - /* XXX(twouters) cast refcount to - long until %zd is universally - available - */ - fprintf(stderr, - "# \n", - p, (long)Py_REFCNT(p), buf); - } - } - list = list->next; - } - } } /*---------------------------------------------------------------------------- --- Objects/intobject.c.orig Thu Feb 7 21:50:07 2008 +++ Objects/intobject.c Thu Feb 7 22:39:48 2008 @@ -29,40 +29,6 @@ via abuse of their ob_type members. */ -#define BLOCK_SIZE 1000 /* 1K less typical malloc overhead */ -#define BHEAD_SIZE 8 /* Enough for a 64-bit pointer */ -#define N_INTOBJECTS ((BLOCK_SIZE - BHEAD_SIZE) / sizeof(PyIntObject)) - -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(void) -{ - PyIntObject *p, *q; - /* Python's object allocator isn't appropriate for large blocks. */ - p = (PyIntObject *) PyMem_MALLOC(sizeof(PyIntBlock)); - if (p == NULL) - return (PyIntObject *) PyErr_NoMemory(); - ((PyIntBlock *)p)->next = block_list; - block_list = (PyIntBlock *)p; - /* Link the int objects together, from rear to front, then return - the address of the last int object in the block. */ - p = &((PyIntBlock *)p)->objects[0]; - q = p + N_INTOBJECTS; - while (--q > p) - Py_TYPE(q) = (struct _typeobject *)(q-1); - Py_TYPE(q) = NULL; - return p + N_INTOBJECTS - 1; -} - #ifndef NSMALLPOSINTS #define NSMALLPOSINTS 257 #endif @@ -98,13 +64,10 @@ return (PyObject *) v; } #endif - if (free_list == NULL) { - if ((free_list = fill_free_list()) == NULL) - return NULL; - } /* Inline PyObject_New */ - v = free_list; - free_list = (PyIntObject *)Py_TYPE(v); + v = (PyIntObject *) PyObject_MALLOC(_PyObject_SIZE(&PyInt_Type)); + if (v == NULL) + return PyErr_NoMemory(); PyObject_INIT(v, &PyInt_Type); v->ob_ival = ival; return (PyObject *) v; @@ -129,10 +92,8 @@ static void int_dealloc(PyIntObject *v) { - if (PyInt_CheckExact(v)) { - Py_TYPE(v) = (struct _typeobject *)free_list; - free_list = v; - } + if (PyInt_CheckExact(v)) + PyObject_Del((PyObject *)v); else Py_TYPE(v)->tp_free((PyObject *)v); } @@ -140,8 +101,7 @@ static void int_free(PyIntObject *v) { - Py_TYPE(v) = (struct _typeobject *)free_list; - free_list = v; + PyObject_Del((PyObject *)v); } long @@ -1184,15 +1144,14 @@ int _PyInt_Init(void) { +#if NSMALLNEGINTS + NSMALLPOSINTS > 0 PyIntObject *v; int ival; -#if NSMALLNEGINTS + NSMALLPOSINTS > 0 for (ival = -NSMALLNEGINTS; ival < NSMALLPOSINTS; ival++) { - if (!free_list && (free_list = fill_free_list()) == NULL) - return 0; /* PyObject_New is inlined */ - v = free_list; - free_list = (PyIntObject *)Py_TYPE(v); + v = (PyIntObject *) PyObject_MALLOC(_PyObject_SIZE(&PyInt_Type)); + if (v == NULL) + return 0; PyObject_INIT(v, &PyInt_Type); v->ob_ival = ival; small_ints[ival + NSMALLNEGINTS] = v; @@ -1204,72 +1163,11 @@ void PyInt_CompactFreeList(size_t *pbc, size_t *pbf, size_t *bsum) { - 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 */ - - 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++) { - if (PyInt_CheckExact(p) && p->ob_refcnt != 0) - irem++; - } - next = list->next; - if (irem) { - list->next = block_list; - block_list = list; - for (ctr = 0, p = &list->objects[0]; - ctr < N_INTOBJECTS; - ctr++, p++) { - if (!PyInt_CheckExact(p) || - p->ob_refcnt == 0) { - Py_TYPE(p) = (struct _typeobject *) - free_list; - free_list = p; - } -#if NSMALLNEGINTS + NSMALLPOSINTS > 0 - else if (-NSMALLNEGINTS <= p->ob_ival && - p->ob_ival < NSMALLPOSINTS && - small_ints[p->ob_ival + - NSMALLNEGINTS] == NULL) { - Py_INCREF(p); - small_ints[p->ob_ival + - NSMALLNEGINTS] = p; - } -#endif - } - } - else { - PyMem_FREE(list); - bf++; - } - isum += irem; - list = next; - } - - *pbc = bc; - *pbf = bf; - *bsum = isum; } void 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 */ - #if NSMALLNEGINTS + NSMALLPOSINTS > 0 int i; PyIntObject **q; @@ -1281,38 +1179,4 @@ *q++ = NULL; } #endif - PyInt_CompactFreeList(&bc, &bf, &isum); - if (!Py_VerboseFlag) - return; - fprintf(stderr, "# cleanup ints"); - if (!isum) { - fprintf(stderr, "\n"); - } - else { - fprintf(stderr, - ": %" PY_FORMAT_SIZE_T "d unfreed ints%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"); - } - if (Py_VerboseFlag > 1) { - list = block_list; - while (list != NULL) { - for (ctr = 0, p = &list->objects[0]; - ctr < N_INTOBJECTS; - ctr++, p++) { - if (PyInt_CheckExact(p) && p->ob_refcnt != 0) - /* XXX(twouters) cast refcount to - long until %zd is universally - available - */ - fprintf(stderr, - "# \n", - p, (long)p->ob_refcnt, - p->ob_ival); - } - list = list->next; - } - } }