Ignore:
Timestamp:
Mar 19, 2014, 11:31:01 PM (11 years ago)
Author:
dmik
Message:

python: Merge vendor 2.7.6 to trunk.

Location:
python/trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • python/trunk

  • python/trunk/Python/pyarena.c

    r2 r391  
    1313
    1414#define DEFAULT_BLOCK_SIZE 8192
    15 #define ALIGNMENT               8
    16 #define ALIGNMENT_MASK          (ALIGNMENT - 1)
    17 #define ROUNDUP(x)              (((x) + ALIGNMENT_MASK) & ~ALIGNMENT_MASK)
     15#define ALIGNMENT               8
     16#define ALIGNMENT_MASK          (ALIGNMENT - 1)
     17#define ROUNDUP(x)              (((x) + ALIGNMENT_MASK) & ~ALIGNMENT_MASK)
    1818
    1919typedef 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;
     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;
    4141} block;
    4242
     
    4747
    4848struct _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;
     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;
    7575#endif
    7676};
     
    7979block_new(size_t size)
    8080{
    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;
     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;
    9292}
    9393
    9494static void
    9595block_free(block *b) {
    96         while (b) {
    97                 block *next = b->ab_next;
    98                 free(b);
    99                 b = next;
    100         }
     96    while (b) {
     97        block *next = b->ab_next;
     98        free(b);
     99        b = next;
     100    }
    101101}
    102102
     
    104104block_alloc(block *b, size_t size)
    105105{
    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;
     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;
    128128}
    129129
     
    131131PyArena_New()
    132132{
    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;
     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;
    157157}
    158158
     
    160160PyArena_Free(PyArena *arena)
    161161{
    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);
     162    assert(arena);
     163#if defined(Py_DEBUG)
     164    /*
     165    fprintf(stderr,
     166        "alloc=%d size=%d blocks=%d block_size=%d big=%d objects=%d\n",
     167        arena->total_allocs, arena->total_size, arena->total_blocks,
     168        arena->total_block_size, arena->total_big_blocks,
     169        PyList_Size(arena->a_objects));
     170    */
     171#endif
     172    block_free(arena->a_head);
     173    /* This property normally holds, except when the code being compiled
     174       is sys.getobjects(0), in which case there will be two references.
     175    assert(arena->a_objects->ob_refcnt == 1);
     176    */
     177
     178    Py_DECREF(arena->a_objects);
     179    free(arena);
    187180}
    188181
     
    190183PyArena_Malloc(PyArena *arena, size_t size)
    191184{
    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;
     185    void *p = block_alloc(arena->a_cur, size);
     186    if (!p)
     187        return PyErr_NoMemory();
     188#if defined(Py_DEBUG)
     189    arena->total_allocs++;
     190    arena->total_size += size;
     191#endif
     192    /* Reset cur if we allocated a new block. */
     193    if (arena->a_cur->ab_next) {
     194        arena->a_cur = arena->a_cur->ab_next;
     195#if defined(Py_DEBUG)
     196        arena->total_blocks++;
     197        arena->total_block_size += arena->a_cur->ab_size;
     198        if (arena->a_cur->ab_size > DEFAULT_BLOCK_SIZE)
     199            ++arena->total_big_blocks;
     200#endif
     201    }
     202    return p;
    210203}
    211204
     
    213206PyArena_AddPyObject(PyArena *arena, PyObject *obj)
    214207{
    215         int r = PyList_Append(arena->a_objects, obj);
    216         if (r >= 0) {
    217                 Py_DECREF(obj);
    218         }
    219         return r;
    220 }
     208    int r = PyList_Append(arena->a_objects, obj);
     209    if (r >= 0) {
     210        Py_DECREF(obj);
     211    }
     212    return r;
     213}
Note: See TracChangeset for help on using the changeset viewer.