4
/* A simple arena block structure.
6
Measurements with standard library modules suggest the average
7
allocation is about 20 bytes and that most compiles use a single
10
TODO(jhylton): Think about a realloc API, maybe just for the last
14
#define DEFAULT_BLOCK_SIZE 8192
16
#define ALIGNMENT_MASK (ALIGNMENT - 1)
17
#define ROUNDUP(x) (((x) + ALIGNMENT_MASK) & ~ALIGNMENT_MASK)
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
26
/* Total number of bytes already passed out. The next byte available
27
* to pass out starts at ab_mem + ab_offset.
31
/* An arena maintains a singly-linked, NULL-terminated list of
32
* all blocks owned by the arena. These are linked via the
35
struct _block *ab_next;
37
/* Pointer to the first allocatable byte owned by this block. Read-
38
* only after initialization.
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.
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
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.
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.
73
size_t total_block_size;
74
size_t total_big_blocks;
79
block_new(size_t size)
81
/* Allocate header and block as one unit.
82
ab_mem points just past header. */
83
block *b = (block *)malloc(sizeof(block) + size);
87
b->ab_mem = (void *)(b + 1);
89
b->ab_offset = ROUNDUP((Py_uintptr_t)(b->ab_mem)) -
90
(Py_uintptr_t)(b->ab_mem);
95
block_free(block *b) {
97
block *next = b->ab_next;
104
block_alloc(block *b, size_t size)
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);
124
assert(b->ab_offset + size <= b->ab_size);
125
p = (void *)(((char *)b->ab_mem) + b->ab_offset);
126
b->ab_offset += size;
133
PyArena* arena = (PyArena *)malloc(sizeof(PyArena));
135
return (PyArena*)PyErr_NoMemory();
137
arena->a_head = block_new(DEFAULT_BLOCK_SIZE);
138
arena->a_cur = arena->a_head;
139
if (!arena->a_head) {
141
return (PyArena*)PyErr_NoMemory();
143
arena->a_objects = PyList_New(0);
144
if (!arena->a_objects) {
145
block_free(arena->a_head);
147
return (PyArena*)PyErr_NoMemory();
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;
160
PyArena_Free(PyArena *arena)
164
#if defined(Py_DEBUG)
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));
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);
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,
182
0, PyList_GET_SIZE(arena->a_objects), NULL);
184
assert(PyList_GET_SIZE(arena->a_objects) == 0);
185
Py_DECREF(arena->a_objects);
190
PyArena_Malloc(PyArena *arena, size_t size)
192
void *p = block_alloc(arena->a_cur, size);
194
return PyErr_NoMemory();
195
#if defined(Py_DEBUG)
196
arena->total_allocs++;
197
arena->total_size += size;
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;
213
PyArena_AddPyObject(PyArena *arena, PyObject *obj)
215
int r = PyList_Append(arena->a_objects, obj);