1/*
2   +----------------------------------------------------------------------+
3   | Zend Engine                                                          |
4   +----------------------------------------------------------------------+
5   | Copyright (c) 1998-2013 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: Andi Gutmans <andi@zend.com>                                |
16   |          Zeev Suraski <zeev@zend.com>                                |
17   +----------------------------------------------------------------------+
18*/
19
20/* $Id$ */
21
22#ifndef ZEND_ALLOC_H
23#define ZEND_ALLOC_H
24
25#include <stdio.h>
26
27#include "../TSRM/TSRM.h"
28#include "zend.h"
29
30#ifndef ZEND_MM_ALIGNMENT
31# define ZEND_MM_ALIGNMENT 8
32# define ZEND_MM_ALIGNMENT_LOG2 3
33#elif ZEND_MM_ALIGNMENT < 4
34# undef ZEND_MM_ALIGNMENT
35# undef ZEND_MM_ALIGNMENT_LOG2
36# define ZEND_MM_ALIGNMENT 4
37# define ZEND_MM_ALIGNMENT_LOG2 2
38#endif
39
40#define ZEND_MM_ALIGNMENT_MASK ~(ZEND_MM_ALIGNMENT-1)
41
42#define ZEND_MM_ALIGNED_SIZE(size)  (((size) + ZEND_MM_ALIGNMENT - 1) & ZEND_MM_ALIGNMENT_MASK)
43
44typedef struct _zend_leak_info {
45    void *addr;
46    size_t size;
47    char *filename;
48    uint lineno;
49    char *orig_filename;
50    uint orig_lineno;
51} zend_leak_info;
52
53BEGIN_EXTERN_C()
54
55ZEND_API char *zend_strndup(const char *s, unsigned int length) ZEND_ATTRIBUTE_MALLOC;
56
57ZEND_API void *_emalloc(size_t size ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC) ZEND_ATTRIBUTE_MALLOC;
58ZEND_API void *_safe_emalloc(size_t nmemb, size_t size, size_t offset ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC) ZEND_ATTRIBUTE_MALLOC;
59ZEND_API void *_safe_malloc(size_t nmemb, size_t size, size_t offset) ZEND_ATTRIBUTE_MALLOC;
60ZEND_API void _efree(void *ptr ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC);
61ZEND_API void *_ecalloc(size_t nmemb, size_t size ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC) ZEND_ATTRIBUTE_MALLOC;
62ZEND_API void *_erealloc(void *ptr, size_t size, int allow_failure ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC);
63ZEND_API void *_safe_erealloc(void *ptr, size_t nmemb, size_t size, size_t offset ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC);
64ZEND_API void *_safe_realloc(void *ptr, size_t nmemb, size_t size, size_t offset);
65ZEND_API char *_estrdup(const char *s ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC) ZEND_ATTRIBUTE_MALLOC;
66ZEND_API char *_estrndup(const char *s, unsigned int length ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC) ZEND_ATTRIBUTE_MALLOC;
67ZEND_API size_t _zend_mem_block_size(void *ptr TSRMLS_DC ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC);
68
69/* Standard wrapper macros */
70#define emalloc(size)                       _emalloc((size) ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC)
71#define safe_emalloc(nmemb, size, offset)   _safe_emalloc((nmemb), (size), (offset) ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC)
72#define efree(ptr)                          _efree((ptr) ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC)
73#define ecalloc(nmemb, size)                _ecalloc((nmemb), (size) ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC)
74#define erealloc(ptr, size)                 _erealloc((ptr), (size), 0 ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC)
75#define safe_erealloc(ptr, nmemb, size, offset) _safe_erealloc((ptr), (nmemb), (size), (offset) ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC)
76#define erealloc_recoverable(ptr, size)     _erealloc((ptr), (size), 1 ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC)
77#define estrdup(s)                          _estrdup((s) ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC)
78#define estrndup(s, length)                 _estrndup((s), (length) ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC)
79#define zend_mem_block_size(ptr)            _zend_mem_block_size((ptr) TSRMLS_CC ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC)
80
81/* Relay wrapper macros */
82#define emalloc_rel(size)                       _emalloc((size) ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_CC)
83#define safe_emalloc_rel(nmemb, size, offset)   _safe_emalloc((nmemb), (size), (offset) ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_CC)
84#define efree_rel(ptr)                          _efree((ptr) ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_CC)
85#define ecalloc_rel(nmemb, size)                _ecalloc((nmemb), (size) ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_CC)
86#define erealloc_rel(ptr, size)                 _erealloc((ptr), (size), 0 ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_CC)
87#define erealloc_recoverable_rel(ptr, size)     _erealloc((ptr), (size), 1 ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_CC)
88#define safe_erealloc_rel(ptr, nmemb, size, offset) _safe_erealloc((ptr), (nmemb), (size), (offset) ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_CC)
89#define estrdup_rel(s)                          _estrdup((s) ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_CC)
90#define estrndup_rel(s, length)                 _estrndup((s), (length) ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_CC)
91#define zend_mem_block_size_rel(ptr)            _zend_mem_block_size((ptr) TSRMLS_CC ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_CC)
92
93inline static void * __zend_malloc(size_t len)
94{
95    void *tmp = malloc(len);
96    if (tmp) {
97        return tmp;
98    }
99    fprintf(stderr, "Out of memory\n");
100    exit(1);
101}
102
103inline static void * __zend_calloc(size_t nmemb, size_t len)
104{
105    void *tmp = _safe_malloc(nmemb, len, 0);
106    memset(tmp, 0, nmemb * len);
107    return tmp;
108}
109
110inline static void * __zend_realloc(void *p, size_t len)
111{
112    p = realloc(p, len);
113    if (p) {
114        return p;
115    }
116    fprintf(stderr, "Out of memory\n");
117    exit(1);
118}
119
120
121/* Selective persistent/non persistent allocation macros */
122#define pemalloc(size, persistent) ((persistent)?__zend_malloc(size):emalloc(size))
123#define safe_pemalloc(nmemb, size, offset, persistent)  ((persistent)?_safe_malloc(nmemb, size, offset):safe_emalloc(nmemb, size, offset))
124#define pefree(ptr, persistent)  ((persistent)?free(ptr):efree(ptr))
125#define pecalloc(nmemb, size, persistent) ((persistent)?__zend_calloc((nmemb), (size)):ecalloc((nmemb), (size)))
126#define perealloc(ptr, size, persistent) ((persistent)?__zend_realloc((ptr), (size)):erealloc((ptr), (size)))
127#define safe_perealloc(ptr, nmemb, size, offset, persistent)    ((persistent)?_safe_realloc((ptr), (nmemb), (size), (offset)):safe_erealloc((ptr), (nmemb), (size), (offset)))
128#define perealloc_recoverable(ptr, size, persistent) ((persistent)?__zend_realloc((ptr), (size)):erealloc_recoverable((ptr), (size)))
129#define pestrdup(s, persistent) ((persistent)?strdup(s):estrdup(s))
130#define pestrndup(s, length, persistent) ((persistent)?zend_strndup((s),(length)):estrndup((s),(length)))
131
132#define pemalloc_rel(size, persistent) ((persistent)?__zend_malloc(size):emalloc_rel(size))
133#define pefree_rel(ptr, persistent) ((persistent)?free(ptr):efree_rel(ptr))
134#define pecalloc_rel(nmemb, size, persistent) ((persistent)?__zend_calloc((nmemb), (size)):ecalloc_rel((nmemb), (size)))
135#define perealloc_rel(ptr, size, persistent) ((persistent)?__zend_realloc((ptr), (size)):erealloc_rel((ptr), (size)))
136#define perealloc_recoverable_rel(ptr, size, persistent) ((persistent)?__zend_realloc((ptr), (size)):erealloc_recoverable_rel((ptr), (size)))
137#define pestrdup_rel(s, persistent) ((persistent)?strdup(s):estrdup_rel(s))
138
139#define safe_estrdup(ptr)  ((ptr)?(estrdup(ptr)):STR_EMPTY_ALLOC())
140#define safe_estrndup(ptr, len) ((ptr)?(estrndup((ptr), (len))):STR_EMPTY_ALLOC())
141
142ZEND_API int zend_set_memory_limit(size_t memory_limit);
143
144ZEND_API void start_memory_manager(TSRMLS_D);
145ZEND_API void shutdown_memory_manager(int silent, int full_shutdown TSRMLS_DC);
146ZEND_API int is_zend_mm(TSRMLS_D);
147
148#if ZEND_DEBUG
149ZEND_API int _mem_block_check(void *ptr, int silent ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC);
150ZEND_API void _full_mem_check(int silent ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC);
151void zend_debug_alloc_output(char *format, ...);
152#define mem_block_check(ptr, silent) _mem_block_check(ptr, silent ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC)
153#define full_mem_check(silent) _full_mem_check(silent ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC)
154#else
155#define mem_block_check(type, ptr, silent)
156#define full_mem_check(silent)
157#endif
158
159ZEND_API size_t zend_memory_usage(int real_usage TSRMLS_DC);
160ZEND_API size_t zend_memory_peak_usage(int real_usage TSRMLS_DC);
161
162END_EXTERN_C()
163
164/* Macroses for zend_fast_cache.h compatibility */
165
166#define ZEND_FAST_ALLOC(p, type, fc_type)   \
167    (p) = (type *) emalloc(sizeof(type))
168
169#define ZEND_FAST_FREE(p, fc_type)  \
170    efree(p)
171
172#define ZEND_FAST_ALLOC_REL(p, type, fc_type)   \
173    (p) = (type *) emalloc_rel(sizeof(type))
174
175#define ZEND_FAST_FREE_REL(p, fc_type)  \
176    efree_rel(p)
177
178/* fast cache for zval's */
179#define ALLOC_ZVAL(z)   \
180    ZEND_FAST_ALLOC(z, zval, ZVAL_CACHE_LIST)
181
182#define FREE_ZVAL(z)    \
183    ZEND_FAST_FREE(z, ZVAL_CACHE_LIST)
184
185#define ALLOC_ZVAL_REL(z)   \
186    ZEND_FAST_ALLOC_REL(z, zval, ZVAL_CACHE_LIST)
187
188#define FREE_ZVAL_REL(z)    \
189    ZEND_FAST_FREE_REL(z, ZVAL_CACHE_LIST)
190
191/* fast cache for HashTables */
192#define ALLOC_HASHTABLE(ht) \
193    ZEND_FAST_ALLOC(ht, HashTable, HASHTABLE_CACHE_LIST)
194
195#define FREE_HASHTABLE(ht)  \
196    ZEND_FAST_FREE(ht, HASHTABLE_CACHE_LIST)
197
198#define ALLOC_HASHTABLE_REL(ht) \
199    ZEND_FAST_ALLOC_REL(ht, HashTable, HASHTABLE_CACHE_LIST)
200
201#define FREE_HASHTABLE_REL(ht)  \
202    ZEND_FAST_FREE_REL(ht, HASHTABLE_CACHE_LIST)
203
204/* Heap functions */
205typedef struct _zend_mm_heap zend_mm_heap;
206
207ZEND_API zend_mm_heap *zend_mm_startup(void);
208ZEND_API void zend_mm_shutdown(zend_mm_heap *heap, int full_shutdown, int silent TSRMLS_DC);
209ZEND_API void *_zend_mm_alloc(zend_mm_heap *heap, size_t size ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC) ZEND_ATTRIBUTE_MALLOC;
210ZEND_API void _zend_mm_free(zend_mm_heap *heap, void *p ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC);
211ZEND_API void *_zend_mm_realloc(zend_mm_heap *heap, void *p, size_t size ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC);
212ZEND_API size_t _zend_mm_block_size(zend_mm_heap *heap, void *p ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC);
213
214#define zend_mm_alloc(heap, size)           _zend_mm_alloc((heap), (size) ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC)
215#define zend_mm_free(heap, p)               _zend_mm_free((heap), (p) ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC)
216#define zend_mm_realloc(heap, p, size)      _zend_mm_realloc((heap), (p), (size) ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC)
217#define zend_mm_block_size(heap, p)         _zend_mm_block_size((heap), (p) ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC)
218
219#define zend_mm_alloc_rel(heap, size)       _zend_mm_alloc((heap), (size) ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_CC)
220#define zend_mm_free_rel(heap, p)           _zend_mm_free((heap), (p) ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_CC)
221#define zend_mm_realloc_rel(heap, p, size)  _zend_mm_realloc((heap), (p), (size) ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_CC)
222#define zend_mm_block_size_rel(heap, p)     _zend_mm_block_size((heap), (p) ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC)
223
224/* Heaps with user defined storage */
225typedef struct _zend_mm_storage zend_mm_storage;
226
227typedef struct _zend_mm_segment {
228    size_t  size;
229    struct _zend_mm_segment *next_segment;
230} zend_mm_segment;
231
232typedef struct _zend_mm_mem_handlers {
233    const char *name;
234    zend_mm_storage* (*init)(void *params);
235    void (*dtor)(zend_mm_storage *storage);
236    void (*compact)(zend_mm_storage *storage);
237    zend_mm_segment* (*_alloc)(zend_mm_storage *storage, size_t size);
238    zend_mm_segment* (*_realloc)(zend_mm_storage *storage, zend_mm_segment *ptr, size_t size);
239    void (*_free)(zend_mm_storage *storage, zend_mm_segment *ptr);
240} zend_mm_mem_handlers;
241
242struct _zend_mm_storage {
243    const zend_mm_mem_handlers *handlers;
244    void *data;
245};
246
247ZEND_API zend_mm_heap *zend_mm_startup_ex(const zend_mm_mem_handlers *handlers, size_t block_size, size_t reserve_size, int internal, void *params);
248ZEND_API zend_mm_heap *zend_mm_set_heap(zend_mm_heap *new_heap TSRMLS_DC);
249ZEND_API zend_mm_storage *zend_mm_get_storage(zend_mm_heap *heap);
250
251ZEND_API void zend_mm_set_custom_handlers(zend_mm_heap *heap,
252                                          void* (*_malloc)(size_t),
253                                          void  (*_free)(void*),
254                                          void* (*_realloc)(void*, size_t));
255
256#endif
257
258/*
259 * Local variables:
260 * tab-width: 4
261 * c-basic-offset: 4
262 * indent-tabs-mode: t
263 * End:
264 */
265