symbian-qemu-0.9.1-12/python-2.6.1/Python/pyarena.c
changeset 1 2fb8b9db1c86
equal deleted inserted replaced
0:ffa851df0825 1:2fb8b9db1c86
       
     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;
       
   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,
       
   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 }