]> granicus.if.org Git - python/commitdiff
Expand comments.
authorJeremy Hylton <jeremy@alum.mit.edu>
Fri, 31 Mar 2006 16:41:22 +0000 (16:41 +0000)
committerJeremy Hylton <jeremy@alum.mit.edu>
Fri, 31 Mar 2006 16:41:22 +0000 (16:41 +0000)
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.

Python/pyarena.c

index 242ca1d67da604518c8c5a9d257b08fa47bd60c4..012c46bcea1021bb76a19af4d24e0bd634daa0c5 100644 (file)
@@ -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);
 }