Expand comments.

Explicitly clear all elements from arena->a_objects and remove
assert() that refcount is 1.  It's possible for a program to get a
reference to the list via sys.getobjects() or via gc functions.
This commit is contained in:
Jeremy Hylton 2006-03-31 16:41:22 +00:00
parent 22f3a6ae1c
commit 296aef8ebb
1 changed files with 27 additions and 0 deletions

View File

@ -6,6 +6,9 @@
Measurements with standard library modules suggest the average Measurements with standard library modules suggest the average
allocation is about 20 bytes and that most compiles use a single allocation is about 20 bytes and that most compiles use a single
block. block.
TODO(jhylton): Think about a realloc API, maybe just for the last
allocation?
*/ */
#define DEFAULT_BLOCK_SIZE 8192 #define DEFAULT_BLOCK_SIZE 8192
@ -39,9 +42,25 @@ typedef struct _block {
*/ */
struct _arena { struct _arena {
/* Pointer to the first block allocated for the arena, never NULL.
It is used only to find the first block when the arena is
being freed.
*/
block *a_head; block *a_head;
/* Pointer to the block currently used for allocation. It's
ab_next field should be NULL. If it is not-null after a
call to block_alloc(), it means a new block has been allocated
and a_cur should be reset to point it.
*/
block *a_cur; block *a_cur;
/* A Python list object containing references to all the PyObject
pointers associated with this area. They will be DECREFed
when the arena is freed.
*/
PyObject *a_objects; PyObject *a_objects;
#if defined(Py_DEBUG) #if defined(Py_DEBUG)
/* Debug output */ /* Debug output */
size_t total_allocs; size_t total_allocs;
@ -134,6 +153,7 @@ PyArena_New()
void void
PyArena_Free(PyArena *arena) PyArena_Free(PyArena *arena)
{ {
int r;
assert(arena); assert(arena);
#if defined(Py_DEBUG) #if defined(Py_DEBUG)
/* /*
@ -146,6 +166,13 @@ PyArena_Free(PyArena *arena)
#endif #endif
block_free(arena->a_head); block_free(arena->a_head);
assert(arena->a_objects->ob_refcnt == 1); assert(arena->a_objects->ob_refcnt == 1);
/* Clear all the elements from the list. This is necessary
to guarantee that they will be DECREFed. */
r = PyList_SetSlice(arena->a_objects,
0, PyList_GET_SIZE(arena->a_objects), NULL);
assert(r == 0);
assert(PyList_GET_SIZE(arena->a_objects) == 0);
Py_DECREF(arena->a_objects); Py_DECREF(arena->a_objects);
free(arena); free(arena);
} }