root/Zend/zend_arena.h

/* [<][>][^][v][top][bottom][index][help] */

INCLUDED FROM


DEFINITIONS

This source file includes following definitions.
  1. zend_arena_create
  2. zend_arena_destroy
  3. zend_arena_alloc
  4. zend_arena_calloc
  5. zend_arena_checkpoint
  6. zend_arena_release

   1 /*
   2    +----------------------------------------------------------------------+
   3    | Zend Engine                                                          |
   4    +----------------------------------------------------------------------+
   5    | Copyright (c) 1998-2016 Zend Technologies Ltd. (http://www.zend.com) |
   6    +----------------------------------------------------------------------+
   7    | This source file is subject to version 2.00 of the Zend license,     |
   8    | that is bundled with this package in the file LICENSE, and is        |
   9    | available through the world-wide-web at the following url:           |
  10    | http://www.zend.com/license/2_00.txt.                                |
  11    | If you did not receive a copy of the Zend license and are unable to  |
  12    | obtain it through the world-wide-web, please send a note to          |
  13    | license@zend.com so we can mail you a copy immediately.              |
  14    +----------------------------------------------------------------------+
  15    | Authors: Dmitry Stogov <dmitry@zend.com>                             |
  16    +----------------------------------------------------------------------+
  17 */
  18 
  19 /* $Id:$ */
  20 
  21 #ifndef _ZEND_ARENA_H_
  22 #define _ZEND_ARENA_H_
  23 
  24 #include "zend.h"
  25 
  26 typedef struct _zend_arena zend_arena;
  27 
  28 struct _zend_arena {
  29         char            *ptr;
  30         char            *end;
  31         zend_arena  *prev;
  32 };
  33 
  34 static zend_always_inline zend_arena* zend_arena_create(size_t size)
  35 {
  36         zend_arena *arena = (zend_arena*)emalloc(size);
  37 
  38         arena->ptr = (char*) arena + ZEND_MM_ALIGNED_SIZE(sizeof(zend_arena));
  39         arena->end = (char*) arena + size;
  40         arena->prev = NULL;
  41         return arena;
  42 }
  43 
  44 static zend_always_inline void zend_arena_destroy(zend_arena *arena)
  45 {
  46         do {
  47                 zend_arena *prev = arena->prev;
  48                 efree(arena);
  49                 arena = prev;
  50         } while (arena);
  51 }
  52 
  53 #define ZEND_ARENA_ALIGNMENT 8U
  54 
  55 static zend_always_inline void* zend_arena_alloc(zend_arena **arena_ptr, size_t size)
  56 {
  57         zend_arena *arena = *arena_ptr;
  58         char *ptr = arena->ptr;
  59 
  60         size = ZEND_MM_ALIGNED_SIZE(size);
  61 
  62         if (EXPECTED(size <= (size_t)(arena->end - ptr))) {
  63                 arena->ptr = ptr + size;
  64         } else {
  65                 size_t arena_size =
  66                         UNEXPECTED((size + ZEND_MM_ALIGNED_SIZE(sizeof(zend_arena))) > (size_t)(arena->end - (char*) arena)) ?
  67                                 (size + ZEND_MM_ALIGNED_SIZE(sizeof(zend_arena))) :
  68                                 (size_t)(arena->end - (char*) arena);
  69                 zend_arena *new_arena = (zend_arena*)emalloc(arena_size);
  70 
  71                 ptr = (char*) new_arena + ZEND_MM_ALIGNED_SIZE(sizeof(zend_arena));
  72                 new_arena->ptr = (char*) new_arena + ZEND_MM_ALIGNED_SIZE(sizeof(zend_arena)) + size;
  73                 new_arena->end = (char*) new_arena + arena_size;
  74                 new_arena->prev = arena;
  75                 *arena_ptr = new_arena;
  76         }
  77 
  78         return (void*) ptr;
  79 }
  80 
  81 static zend_always_inline void* zend_arena_calloc(zend_arena **arena_ptr, size_t count, size_t unit_size)
  82 {
  83         int overflow;
  84         size_t size;
  85         void *ret;
  86 
  87         size = zend_safe_address(unit_size, count, 0, &overflow);
  88         if (UNEXPECTED(overflow)) {
  89                 zend_error(E_ERROR, "Possible integer overflow in zend_arena_calloc() (%zu * %zu)", unit_size, count);
  90         }
  91         ret = zend_arena_alloc(arena_ptr, size);
  92         memset(ret, 0, size);
  93         return ret;
  94 }
  95 
  96 static zend_always_inline void* zend_arena_checkpoint(zend_arena *arena)
  97 {
  98         return arena->ptr;
  99 }
 100 
 101 static zend_always_inline void zend_arena_release(zend_arena **arena_ptr, void *checkpoint)
 102 {
 103         zend_arena *arena = *arena_ptr;
 104 
 105         while (UNEXPECTED((char*)checkpoint > arena->end) ||
 106                UNEXPECTED((char*)checkpoint <= (char*)arena)) {
 107                 zend_arena *prev = arena->prev;
 108                 efree(arena);
 109                 *arena_ptr = arena = prev;
 110         }
 111         ZEND_ASSERT((char*)checkpoint > (char*)arena && (char*)checkpoint <= arena->end);
 112         arena->ptr = (char*)checkpoint;
 113 }
 114 
 115 #endif /* _ZEND_ARENA_H_ */
 116 
 117 /*
 118  * Local variables:
 119  * tab-width: 4
 120  * c-basic-offset: 4
 121  * indent-tabs-mode: t
 122  * End:
 123  */

/* [<][>][^][v][top][bottom][index][help] */