Python-2.7.3/Python/pyarena.c

Location Tool Test ID Function Issue
/builddir/build/BUILD/Python-2.7.3/Python/pyarena.c:162:9 gcc unused-but-set-variable PyArena_Free variable 'r' set but not used
/builddir/build/BUILD/Python-2.7.3/Python/pyarena.c:181:5 clang-analyzer Value stored to 'r' is never read
  1 #include "Python.h"
  2 #include "pyarena.h"
  3 
  4 /* A simple arena block structure.
  5 
  6    Measurements with standard library modules suggest the average
  7    allocation is about 20 bytes and that most compiles use a single
  8    block.
  9 
 10    TODO(jhylton): Think about a realloc API, maybe just for the last
 11    allocation?
 12 */
 13 
 14 #define DEFAULT_BLOCK_SIZE 8192
 15 #define ALIGNMENT               8
 16 #define ALIGNMENT_MASK          (ALIGNMENT - 1)
 17 #define ROUNDUP(x)              (((x) + ALIGNMENT_MASK) & ~ALIGNMENT_MASK)
 18 
 19 typedef struct _block {
 20     /* Total number of bytes owned by this block available to pass out.
 21      * Read-only after initialization.  The first such byte starts at
 22      * ab_mem.
 23      */
 24     size_t ab_size;
 25 
 26     /* Total number of bytes already passed out.  The next byte available
 27      * to pass out starts at ab_mem + ab_offset.
 28      */
 29     size_t ab_offset;
 30 
 31     /* An arena maintains a singly-linked, NULL-terminated list of
 32      * all blocks owned by the arena.  These are linked via the
 33      * ab_next member.
 34      */
 35     struct _block *ab_next;
 36 
 37     /* Pointer to the first allocatable byte owned by this block.  Read-
 38      * only after initialization.
 39      */
 40     void *ab_mem;
 41 } block;
 42 
 43 /* The arena manages two kinds of memory, blocks of raw memory
 44    and a list of PyObject* pointers.  PyObjects are decrefed
 45    when the arena is freed.
 46 */
 47 
 48 struct _arena {
 49     /* Pointer to the first block allocated for the arena, never NULL.
 50        It is used only to find the first block when the arena is
 51        being freed.
 52      */
 53     block *a_head;
 54 
 55     /* Pointer to the block currently used for allocation.  It's
 56        ab_next field should be NULL.  If it is not-null after a
 57        call to block_alloc(), it means a new block has been allocated
 58        and a_cur should be reset to point it.
 59      */
 60     block *a_cur;
 61 
 62     /* A Python list object containing references to all the PyObject
 63        pointers associated with this area.  They will be DECREFed
 64        when the arena is freed.
 65     */
 66     PyObject *a_objects;
 67 
 68 #if defined(Py_DEBUG)
 69     /* Debug output */
 70     size_t total_allocs;
 71     size_t total_size;
 72     size_t total_blocks;
 73     size_t total_block_size;
 74     size_t total_big_blocks;
 75 #endif
 76 };
 77 
 78 static block *
 79 block_new(size_t size)
 80 {
 81     /* Allocate header and block as one unit.
 82        ab_mem points just past header. */
 83     block *b = (block *)malloc(sizeof(block) + size);
 84     if (!b)
 85         return NULL;
 86     b->ab_size = size;
 87     b->ab_mem = (void *)(b + 1);
 88     b->ab_next = NULL;
 89     b->ab_offset = ROUNDUP((Py_uintptr_t)(b->ab_mem)) -
 90       (Py_uintptr_t)(b->ab_mem);
 91     return b;
 92 }
 93 
 94 static void
 95 block_free(block *b) {
 96     while (b) {
 97         block *next = b->ab_next;
 98         free(b);
 99         b = next;
100     }
101 }
102 
103 static void *
104 block_alloc(block *b, size_t size)
105 {
106     void *p;
107     assert(b);
108     size = ROUNDUP(size);
109     if (b->ab_offset + size > b->ab_size) {
110         /* If we need to allocate more memory than will fit in
111            the default block, allocate a one-off block that is
112            exactly the right size. */
113         /* TODO(jhylton): Think about space waste at end of block */
114         block *newbl = block_new(
115                         size < DEFAULT_BLOCK_SIZE ?
116                         DEFAULT_BLOCK_SIZE : size);
117         if (!newbl)
118             return NULL;
119         assert(!b->ab_next);
120         b->ab_next = newbl;
121         b = newbl;
122     }
123 
124     assert(b->ab_offset + size <= b->ab_size);
125     p = (void *)(((char *)b->ab_mem) + b->ab_offset);
126     b->ab_offset += size;
127     return p;
128 }
129 
130 PyArena *
131 PyArena_New()
132 {
133     PyArena* arena = (PyArena *)malloc(sizeof(PyArena));
134     if (!arena)
135         return (PyArena*)PyErr_NoMemory();
136 
137     arena->a_head = block_new(DEFAULT_BLOCK_SIZE);
138     arena->a_cur = arena->a_head;
139     if (!arena->a_head) {
140         free((void *)arena);
141         return (PyArena*)PyErr_NoMemory();
142     }
143     arena->a_objects = PyList_New(0);
144     if (!arena->a_objects) {
145         block_free(arena->a_head);
146         free((void *)arena);
147         return (PyArena*)PyErr_NoMemory();
148     }
149 #if defined(Py_DEBUG)
150     arena->total_allocs = 0;
151     arena->total_size = 0;
152     arena->total_blocks = 1;
153     arena->total_block_size = DEFAULT_BLOCK_SIZE;
154     arena->total_big_blocks = 0;
155 #endif
156     return arena;
157 }
158 
159 void
160 PyArena_Free(PyArena *arena)
161 {
162     int r;
variable 'r' set but not used
(emitted by gcc)
163 assert(arena); 164 #if defined(Py_DEBUG) 165 /* 166 fprintf(stderr, 167 "alloc=%d size=%d blocks=%d block_size=%d big=%d objects=%d\n", 168 arena->total_allocs, arena->total_size, arena->total_blocks, 169 arena->total_block_size, arena->total_big_blocks, 170 PyList_Size(arena->a_objects)); 171 */ 172 #endif 173 block_free(arena->a_head); 174 /* This property normally holds, except when the code being compiled 175 is sys.getobjects(0), in which case there will be two references. 176 assert(arena->a_objects->ob_refcnt == 1); 177 */ 178 179 /* Clear all the elements from the list. This is necessary 180 to guarantee that they will be DECREFed. */ 181 r = PyList_SetSlice(arena->a_objects,
Value stored to 'r' is never read
(emitted by clang-analyzer)

TODO: a detailed trace is available in the data model (not yet rendered in this report)

182 0, PyList_GET_SIZE(arena->a_objects), NULL); 183 assert(r == 0); 184 assert(PyList_GET_SIZE(arena->a_objects) == 0); 185 Py_DECREF(arena->a_objects); 186 free(arena); 187 } 188 189 void * 190 PyArena_Malloc(PyArena *arena, size_t size) 191 { 192 void *p = block_alloc(arena->a_cur, size); 193 if (!p) 194 return PyErr_NoMemory(); 195 #if defined(Py_DEBUG) 196 arena->total_allocs++; 197 arena->total_size += size; 198 #endif 199 /* Reset cur if we allocated a new block. */ 200 if (arena->a_cur->ab_next) { 201 arena->a_cur = arena->a_cur->ab_next; 202 #if defined(Py_DEBUG) 203 arena->total_blocks++; 204 arena->total_block_size += arena->a_cur->ab_size; 205 if (arena->a_cur->ab_size > DEFAULT_BLOCK_SIZE) 206 ++arena->total_big_blocks; 207 #endif 208 } 209 return p; 210 } 211 212 int 213 PyArena_AddPyObject(PyArena *arena, PyObject *obj) 214 { 215 int r = PyList_Append(arena->a_objects, obj); 216 if (r >= 0) { 217 Py_DECREF(obj); 218 } 219 return r; 220 }