11#include "Python.h"
22#include "pyarena.h"
33
4- /* An arena list is a linked list that can store PyObjects. */
5-
6- typedef struct _arena_list {
7- struct _arena_list * al_next ;
8- void * al_pointer ;
9- } PyArenaList ;
10-
114/* A simple arena block structure */
125/* TODO(jhylton): Measurement to justify block size. */
136
@@ -19,38 +12,17 @@ typedef struct _block {
1912 void * ab_mem ;
2013} block ;
2114
15+ /* The arena manages two kinds of memory, blocks of raw memory
16+ and a list of PyObject* pointers. PyObjects are decrefed
17+ when the arena is freed.
18+ */
19+
2220struct _arena {
2321 block * a_head ;
2422 block * a_cur ;
25- PyArenaList * a_object_head ;
26- PyArenaList * a_object_tail ;
23+ PyObject * a_objects ;
2724};
2825
29- static PyArenaList *
30- PyArenaList_New (void )
31- {
32- PyArenaList * alist = (PyArenaList * )malloc (sizeof (PyArenaList ));
33- if (!alist )
34- return NULL ;
35-
36- alist -> al_next = NULL ;
37- alist -> al_pointer = NULL ;
38- return alist ;
39- }
40-
41- static void
42- PyArenaList_FreeObject (PyArenaList * alist )
43- {
44- while (alist ) {
45- PyArenaList * prev ;
46- Py_XDECREF ((PyObject * )alist -> al_pointer );
47- alist -> al_pointer = NULL ;
48- prev = alist ;
49- alist = alist -> al_next ;
50- free (prev );
51- }
52- }
53-
5426static block *
5527block_new (size_t size )
5628{
@@ -110,8 +82,16 @@ PyArena_New()
11082
11183 arena -> a_head = block_new (DEFAULT_BLOCK_SIZE );
11284 arena -> a_cur = arena -> a_head ;
113- arena -> a_object_head = PyArenaList_New ();
114- arena -> a_object_tail = arena -> a_object_head ;
85+ if (!arena -> a_head ) {
86+ free ((void * )arena );
87+ return NULL ;
88+ }
89+ arena -> a_objects = PyList_New (16 );
90+ if (!arena -> a_objects ) {
91+ block_free (arena -> a_head );
92+ free ((void * )arena );
93+ return NULL ;
94+ }
11595 return arena ;
11696}
11797
@@ -120,7 +100,8 @@ PyArena_Free(PyArena *arena)
120100{
121101 assert (arena );
122102 block_free (arena -> a_head );
123- PyArenaList_FreeObject (arena -> a_object_head );
103+ assert (arena -> a_objects -> ob_refcnt == 1 );
104+ Py_DECREF (arena -> a_objects );
124105 free (arena );
125106}
126107
@@ -138,12 +119,7 @@ PyArena_Malloc(PyArena *arena, size_t size)
138119}
139120
140121int
141- PyArena_AddPyObject (PyArena * arena , PyObject * pointer )
122+ PyArena_AddPyObject (PyArena * arena , PyObject * obj )
142123{
143- PyArenaList * tail = arena -> a_object_tail ;
144- assert (pointer );
145- tail -> al_next = PyArenaList_New ();
146- tail -> al_pointer = pointer ;
147- arena -> a_object_tail = tail -> al_next ;
148- return 1 ;
124+ return PyList_Append (arena -> a_objects , obj ) >= 0 ;
149125}
0 commit comments