php-internal-docs 8.4.8
Unofficial docs for php/php-src
Loading...
Searching...
No Matches
mraw.c
Go to the documentation of this file.
1/*
2 * Copyright (C) 2018-2019 Alexander Borisov
3 *
4 * Author: Alexander Borisov <borisov@lexbor.com>
5 */
6
7#include "lexbor/core/mraw.h"
8
9
10#if defined(LEXBOR_HAVE_ADDRESS_SANITIZER)
11 #include <sanitizer/asan_interface.h>
12#endif
13
14
15#define lexbor_mraw_meta_set(data, size) \
16 do { \
17 memcpy(data, size, sizeof(size_t)); \
18 } \
19 while (0)
20
21#define lexbor_mraw_data_begin(data) \
22 &((uint8_t *) (data))[ lexbor_mraw_meta_size() ]
23
24
25lxb_inline void *
27 size_t size, size_t begin_len, size_t new_size,
28 bool *is_valid);
29
30
33{
34 return lexbor_calloc(1, sizeof(lexbor_mraw_t));
35}
36
38lexbor_mraw_init(lexbor_mraw_t *mraw, size_t chunk_size)
39{
41
42 if (mraw == NULL) {
44 }
45
46 if (chunk_size == 0) {
48 }
49
50 /* Init memory */
51 mraw->mem = lexbor_mem_create();
52
53 status = lexbor_mem_init(mraw->mem, chunk_size + lexbor_mraw_meta_size());
54 if (status) {
55 return status;
56 }
57
58#if defined(LEXBOR_HAVE_ADDRESS_SANITIZER)
59 ASAN_POISON_MEMORY_REGION(mraw->mem->chunk->data, mraw->mem->chunk->size);
60#endif
61
62 /* Cache */
63 mraw->cache = lexbor_bst_create();
64
65 status = lexbor_bst_init(mraw->cache, 512);
66 if (status) {
67 return status;
68 }
69
70 mraw->ref_count = 0;
71
72 return LXB_STATUS_OK;
73}
74
75void
77{
78 if (mraw != NULL) {
79 lexbor_mem_clean(mraw->mem);
81
82 mraw->ref_count = 0;
83 }
84}
85
87lexbor_mraw_destroy(lexbor_mraw_t *mraw, bool destroy_self)
88{
89 if (mraw == NULL) {
90 return NULL;
91 }
92
93 mraw->mem = lexbor_mem_destroy(mraw->mem, true);
94 mraw->cache = lexbor_bst_destroy(mraw->cache, true);
95
96 if (destroy_self) {
97 return lexbor_free(mraw);
98 }
99
100 return mraw;
101}
102
103lxb_inline void *
105{
106 uint8_t *data;
107 lexbor_mem_t *mem = mraw->mem;
108
109 if (length == 0) {
110 return NULL;
111 }
112
113 if ((mem->chunk->length + length) > mem->chunk->size) {
114 lexbor_mem_chunk_t *chunk = mem->chunk;
115
116 if ((SIZE_MAX - mem->chunk_length) == 0) {
117 return NULL;
118 }
119
120 if (chunk->length == 0) {
121 lexbor_mem_chunk_destroy(mem, chunk, false);
122 lexbor_mem_chunk_init(mem, chunk, length);
123
124 chunk->length = length;
125
126#if defined(LEXBOR_HAVE_ADDRESS_SANITIZER)
127 ASAN_POISON_MEMORY_REGION(chunk->data, chunk->size);
128#endif
129
130 return chunk->data;
131 }
132
133 size_t diff = lexbor_mem_align_floor(chunk->size - chunk->length);
134
135 /* Save tail to cache */
136 if (diff > lexbor_mraw_meta_size()) {
137 diff -= lexbor_mraw_meta_size();
138
139#if defined(LEXBOR_HAVE_ADDRESS_SANITIZER)
140 ASAN_UNPOISON_MEMORY_REGION(&chunk->data[chunk->length],
142#endif
143
144 lexbor_mraw_meta_set(&chunk->data[chunk->length], &diff);
145
146#if defined(LEXBOR_HAVE_ADDRESS_SANITIZER)
147 ASAN_POISON_MEMORY_REGION(&chunk->data[chunk->length],
148 diff + lexbor_mraw_meta_size());
149#endif
150
152 lexbor_bst_root_ref(mraw->cache), diff,
153 lexbor_mraw_data_begin(&chunk->data[chunk->length]));
154
155 chunk->length = chunk->size;
156 }
157
158 chunk->next = lexbor_mem_chunk_make(mem, length);
159 if (chunk->next == NULL) {
160 return NULL;
161 }
162
163 chunk->next->prev = chunk;
164 mem->chunk = chunk->next;
165
166 mem->chunk_length++;
167
168#if defined(LEXBOR_HAVE_ADDRESS_SANITIZER)
169 ASAN_POISON_MEMORY_REGION(mem->chunk->data, mem->chunk->size);
170#endif
171 }
172
173 data = &mem->chunk->data[ mem->chunk->length ];
174 mem->chunk->length += length;
175
176 return data;
177}
178
179void *
181{
182 void *data;
183
185
186 if (mraw->cache->tree_length != 0) {
189 size, NULL);
190 if (data != NULL) {
191
192#if defined(LEXBOR_HAVE_ADDRESS_SANITIZER)
193 uint8_t *real_data = ((uint8_t *) data) - lexbor_mraw_meta_size();
194
195 /* Set unpoison for current data size */
196 ASAN_UNPOISON_MEMORY_REGION(real_data, lexbor_mraw_meta_size());
197
198 size_t cur_size = lexbor_mraw_data_size(data);
199
200 ASAN_UNPOISON_MEMORY_REGION(real_data,
201 (cur_size + lexbor_mraw_meta_size()));
202#endif
203
204 mraw->ref_count++;
205
206 return data;
207 }
208 }
209
211
212 if (data == NULL) {
213 return NULL;
214 }
215
216#if defined(LEXBOR_HAVE_ADDRESS_SANITIZER)
217 ASAN_UNPOISON_MEMORY_REGION(data, (size + lexbor_mraw_meta_size()));
218#endif
219
220 mraw->ref_count++;
221
224}
225
226void *
228{
229 void *data = lexbor_mraw_alloc(mraw, size);
230
231 if (data != NULL) {
233 }
234
235 return data;
236}
237
238/*
239 * TODO: I don't really like this interface. Perhaps need to simplify.
240 */
241lxb_inline void *
243 size_t size, size_t begin_len, size_t new_size,
244 bool *is_valid)
245{
246 lexbor_mem_chunk_t *chunk = mraw->mem->chunk;
247
248 if (chunk->size > (begin_len + new_size)) {
249 *is_valid = true;
250
251 if (new_size == 0) {
252 chunk->length = begin_len - lexbor_mraw_meta_size();
253 return NULL;
254 }
255
256#if defined(LEXBOR_HAVE_ADDRESS_SANITIZER)
257 ASAN_UNPOISON_MEMORY_REGION(begin, new_size + lexbor_mraw_meta_size());
258#endif
259
260 chunk->length = begin_len + new_size;
261 memcpy(begin, &new_size, sizeof(size_t));
262
263 return data;
264 }
265
266 /*
267 * If the tail is short then we increase the current data.
268 */
269 if (begin_len == lexbor_mraw_meta_size()) {
270 void *new_data;
271 lexbor_mem_chunk_t new_chunk;
272
273 *is_valid = true;
274
275 lexbor_mem_chunk_init(mraw->mem, &new_chunk,
276 new_size + lexbor_mraw_meta_size());
277 if(new_chunk.data == NULL) {
278 return NULL;
279 }
280
281 lexbor_mraw_meta_set(new_chunk.data, &new_size);
282 new_data = lexbor_mraw_data_begin(new_chunk.data);
283
284 if (size != 0) {
285 memcpy(new_data, data, sizeof(uint8_t) * size);
286 }
287
288#if defined(LEXBOR_HAVE_ADDRESS_SANITIZER)
289 ASAN_UNPOISON_MEMORY_REGION(chunk->data, chunk->size);
290#endif
291
292 lexbor_mem_chunk_destroy(mraw->mem, chunk, false);
293
294 chunk->data = new_chunk.data;
295 chunk->size = new_chunk.size;
296 chunk->length = new_size + lexbor_mraw_meta_size();
297
298 return new_data;
299 }
300
301 *is_valid = false;
302
303 /*
304 * Next, this piece will go into the cache.
305 */
306 size = lexbor_mem_align_floor(size + (chunk->size - chunk->length));
307 memcpy(begin, &size, sizeof(size_t));
308
309 chunk->length = chunk->size;
310
311 return NULL;
312}
313
314void *
315lexbor_mraw_realloc(lexbor_mraw_t *mraw, void *data, size_t new_size)
316{
317 void *begin;
318 size_t size, begin_len;
319 lexbor_mem_chunk_t *chunk = mraw->mem->chunk;
320
321 begin = ((uint8_t *) data) - lexbor_mraw_meta_size();
322 memcpy(&size, begin, sizeof(size_t));
323
324 new_size = lexbor_mem_align(new_size);
325
326 /*
327 * Look, whether there is an opportunity
328 * to prolong the current data in chunk?
329 */
330 if (chunk->length >= size) {
331 begin_len = chunk->length - size;
332
333 if (&chunk->data[begin_len] == data) {
334 bool is_valid;
335 void *ptr = lexbor_mraw_realloc_tail(mraw, data, begin,
336 size, begin_len, new_size,
337 &is_valid);
338 if (is_valid == true) {
339 return ptr;
340 }
341 }
342 }
343
344 if (new_size < size) {
345 if (new_size == 0) {
346
347#if defined(LEXBOR_HAVE_ADDRESS_SANITIZER)
348 ASAN_POISON_MEMORY_REGION(begin, size + lexbor_mraw_meta_size());
349#endif
350 mraw->ref_count--;
351
353 size, data);
354 return NULL;
355 }
356
357 size_t diff = lexbor_mem_align_floor(size - new_size);
358
359 if (diff > lexbor_mraw_meta_size()) {
360 memcpy(begin, &new_size, sizeof(size_t));
361
362 new_size = diff - lexbor_mraw_meta_size();
363 begin = &((uint8_t *) data)[diff];
364
365 lexbor_mraw_meta_set(begin, &new_size);
366
367#if defined(LEXBOR_HAVE_ADDRESS_SANITIZER)
368 ASAN_POISON_MEMORY_REGION(begin, new_size + lexbor_mraw_meta_size());
369#endif
371 new_size, lexbor_mraw_data_begin(begin));
372 }
373
374 return data;
375 }
376
377 begin = lexbor_mraw_alloc(mraw, new_size);
378 if (begin == NULL) {
379 return NULL;
380 }
381
382 if (size != 0) {
383 memcpy(begin, data, sizeof(uint8_t) * size);
384 }
385
386 lexbor_mraw_free(mraw, data);
387
388 return begin;
389}
390
391void *
393{
395
396#if defined(LEXBOR_HAVE_ADDRESS_SANITIZER)
397 uint8_t *real_data = ((uint8_t *) data) - lexbor_mraw_meta_size();
398 ASAN_POISON_MEMORY_REGION(real_data, size + lexbor_mraw_meta_size());
399#endif
400
402 size, data);
403
404 mraw->ref_count--;
405
406 return NULL;
407}
408
409/*
410 * No inline functions for ABI.
411 */
412size_t
417
418void
423
424void *
425lexbor_mraw_dup_noi(lexbor_mraw_t *mraw, const void *src, size_t size)
426{
427 return lexbor_mraw_dup(mraw, src, size);
428}
lexbor_bst_t * lexbor_bst_create(void)
Definition bst.c:12
lxb_status_t lexbor_bst_init(lexbor_bst_t *bst, size_t size)
Definition bst.c:18
void * lexbor_bst_remove_close(lexbor_bst_t *bst, lexbor_bst_entry_t **scope, size_t size, size_t *found_size)
Definition bst.c:248
lexbor_bst_entry_t * lexbor_bst_insert(lexbor_bst_t *bst, lexbor_bst_entry_t **scope, size_t size, void *value)
Definition bst.c:86
lexbor_bst_t * lexbor_bst_destroy(lexbor_bst_t *bst, bool self_destroy)
Definition bst.c:55
void lexbor_bst_clean(lexbor_bst_t *bst)
Definition bst.c:44
#define lexbor_bst_root_ref(bst)
Definition bst.h:21
@ LXB_STATUS_ERROR_OBJECT_IS_NULL
Definition base.h:52
@ LXB_STATUS_ERROR_WRONG_ARGS
Definition base.h:58
@ LXB_STATUS_OK
Definition base.h:49
DNS_STATUS status
Definition dns_win32.c:49
int begin
Definition eaw_table.h:20
new_type size
Definition ffi.c:4365
void * ptr
Definition ffi.c:3814
memcpy(ptr1, ptr2, size)
memset(ptr, 0, type->size)
#define SIZE_MAX
Definition funcs.c:51
#define NULL
Definition gdcache.h:45
LXB_API void * lexbor_free(void *dst)
Definition memory.c:33
LXB_API void * lexbor_calloc(size_t num, size_t size)
Definition memory.c:27
lexbor_mem_chunk_t * lexbor_mem_chunk_make(lexbor_mem_t *mem, size_t length)
Definition mem.c:122
lexbor_mem_t * lexbor_mem_create(void)
Definition mem.c:11
uint8_t * lexbor_mem_chunk_init(lexbor_mem_t *mem, lexbor_mem_chunk_t *chunk, size_t length)
Definition mem.c:98
lexbor_mem_t * lexbor_mem_destroy(lexbor_mem_t *mem, bool destroy_self)
Definition mem.c:69
lexbor_mem_chunk_t * lexbor_mem_chunk_destroy(lexbor_mem_t *mem, lexbor_mem_chunk_t *chunk, bool self_destroy)
Definition mem.c:138
lxb_status_t lexbor_mem_init(lexbor_mem_t *mem, size_t min_chunk_size)
Definition mem.c:17
void lexbor_mem_clean(lexbor_mem_t *mem)
Definition mem.c:42
struct lexbor_mem lexbor_mem_t
Definition mem.h:20
lxb_inline size_t lexbor_mem_align(size_t size)
Definition mem.h:103
struct lexbor_mem_chunk lexbor_mem_chunk_t
Definition mem.h:19
lxb_inline size_t lexbor_mem_align_floor(size_t size)
Definition mem.h:111
lxb_inline void * lexbor_mraw_realloc_tail(lexbor_mraw_t *mraw, void *data, void *begin, size_t size, size_t begin_len, size_t new_size, bool *is_valid)
Definition mraw.c:242
lexbor_mraw_t * lexbor_mraw_create(void)
Definition mraw.c:32
void * lexbor_mraw_free(lexbor_mraw_t *mraw, void *data)
Definition mraw.c:392
void lexbor_mraw_data_size_set_noi(void *data, size_t size)
Definition mraw.c:419
lxb_inline void * lexbor_mraw_mem_alloc(lexbor_mraw_t *mraw, size_t length)
Definition mraw.c:104
#define lexbor_mraw_data_begin(data)
Definition mraw.c:21
void lexbor_mraw_clean(lexbor_mraw_t *mraw)
Definition mraw.c:76
size_t lexbor_mraw_data_size_noi(void *data)
Definition mraw.c:413
void * lexbor_mraw_realloc(lexbor_mraw_t *mraw, void *data, size_t new_size)
Definition mraw.c:315
#define lexbor_mraw_meta_set(data, size)
Definition mraw.c:15
lxb_status_t lexbor_mraw_init(lexbor_mraw_t *mraw, size_t chunk_size)
Definition mraw.c:38
void * lexbor_mraw_calloc(lexbor_mraw_t *mraw, size_t size)
Definition mraw.c:227
void * lexbor_mraw_alloc(lexbor_mraw_t *mraw, size_t size)
Definition mraw.c:180
void * lexbor_mraw_dup_noi(lexbor_mraw_t *mraw, const void *src, size_t size)
Definition mraw.c:425
lexbor_mraw_t * lexbor_mraw_destroy(lexbor_mraw_t *mraw, bool destroy_self)
Definition mraw.c:87
#define lexbor_mraw_meta_size()
Definition mraw.h:21
lxb_inline size_t lexbor_mraw_data_size(void *data)
Definition mraw.h:66
lxb_inline void * lexbor_mraw_dup(lexbor_mraw_t *mraw, const void *src, size_t size)
Definition mraw.h:79
lxb_inline void lexbor_mraw_data_size_set(void *data, size_t size)
Definition mraw.h:72
zend_constant * data
size_t tree_length
Definition bst.h:45
size_t size
Definition mem.h:25
uint8_t * data
Definition mem.h:23
lexbor_mem_chunk_t * next
Definition mem.h:27
size_t length
Definition mem.h:24
size_t chunk_length
Definition mem.h:36
lexbor_mem_chunk_t * chunk
Definition mem.h:32
size_t ref_count
Definition mraw.h:31
lexbor_bst_t * cache
Definition mraw.h:30
lexbor_mem_t * mem
Definition mraw.h:29
unsigned int lxb_status_t
Definition types.h:28
#define lxb_inline
Definition types.h:21