diff options
author | Jeremy Hylton <jeremy@alum.mit.edu> | 2006-03-31 16:41:22 (GMT) |
---|---|---|
committer | Jeremy Hylton <jeremy@alum.mit.edu> | 2006-03-31 16:41:22 (GMT) |
commit | 296aef8ebb4701a6fe3af652a230b1107ae5f44a (patch) | |
tree | 4343abd1dcffcd55af17670a450d291c566de49f /Python/pyarena.c | |
parent | 22f3a6ae1c5f43db01fd83f64079224a3ea7c588 (diff) | |
download | cpython-296aef8ebb4701a6fe3af652a230b1107ae5f44a.zip cpython-296aef8ebb4701a6fe3af652a230b1107ae5f44a.tar.gz cpython-296aef8ebb4701a6fe3af652a230b1107ae5f44a.tar.bz2 |
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.
Diffstat (limited to 'Python/pyarena.c')
-rw-r--r-- | Python/pyarena.c | 27 |
1 files changed, 27 insertions, 0 deletions
diff --git a/Python/pyarena.c b/Python/pyarena.c index 242ca1d..012c46b 100644 --- a/Python/pyarena.c +++ b/Python/pyarena.c @@ -6,6 +6,9 @@ Measurements with standard library modules suggest the average allocation is about 20 bytes and that most compiles use a single block. + + TODO(jhylton): Think about a realloc API, maybe just for the last + allocation? */ #define DEFAULT_BLOCK_SIZE 8192 @@ -39,9 +42,25 @@ typedef struct _block { */ 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; + + /* 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; + + /* 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; + #if defined(Py_DEBUG) /* Debug output */ size_t total_allocs; @@ -134,6 +153,7 @@ PyArena_New() void PyArena_Free(PyArena *arena) { + int r; assert(arena); #if defined(Py_DEBUG) /* @@ -146,6 +166,13 @@ PyArena_Free(PyArena *arena) #endif block_free(arena->a_head); 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); free(arena); } |