Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 07fe9e1

Browse files
add gc and shutdown callbacks
1 parent fd47cd8 commit 07fe9e1

12 files changed

+323
-20
lines changed

‎Zend/zend_alloc.c‎

Lines changed: 56 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -273,11 +273,15 @@ struct _zend_mm_heap {
273273
void *(*_malloc)(size_t);
274274
void (*_free)(void*);
275275
void *(*_realloc)(void*, size_t);
276+
size_t (*_gc)(void);
277+
void (*_shutdown)(bool full, bool silent);
276278
} std;
277279
struct {
278280
void *(*_malloc)(size_t ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC);
279281
void (*_free)(void* ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC);
280282
void *(*_realloc)(void*, size_t ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC);
283+
size_t (*_gc)(void);
284+
void (*_shutdown)(bool full, bool silent);
281285
} debug;
282286
} custom_heap;
283287
HashTable *tracked_allocs;
@@ -1968,6 +1972,10 @@ ZEND_API size_t zend_mm_gc(zend_mm_heap *heap)
19681972

19691973
#if ZEND_MM_CUSTOM
19701974
if (heap->use_custom_heap) {
1975+
size_t (*gc)(void) = heap->custom_heap.std._gc;
1976+
if (gc) {
1977+
return gc();
1978+
}
19711979
return 0;
19721980
}
19731981
#endif
@@ -2262,10 +2270,10 @@ static void zend_mm_check_leaks(zend_mm_heap *heap)
22622270

22632271
#if ZEND_MM_CUSTOM
22642272
static void *tracked_malloc(size_t size);
2265-
static void tracked_free_all(void);
2273+
static void tracked_free_all(zend_mm_heap*heap);
22662274
#endif
22672275

2268-
void zend_mm_shutdown(zend_mm_heap *heap, bool full, bool silent)
2276+
ZEND_APIvoid zend_mm_shutdown(zend_mm_heap *heap, bool full, bool silent)
22692277
{
22702278
zend_mm_chunk *p;
22712279
zend_mm_huge_list *list;
@@ -2274,7 +2282,7 @@ void zend_mm_shutdown(zend_mm_heap *heap, bool full, bool silent)
22742282
if (heap->use_custom_heap) {
22752283
if (heap->custom_heap.std._malloc == tracked_malloc) {
22762284
if (silent) {
2277-
tracked_free_all();
2285+
tracked_free_all(heap);
22782286
}
22792287
zend_hash_clean(heap->tracked_allocs);
22802288
if (full) {
@@ -2286,13 +2294,20 @@ void zend_mm_shutdown(zend_mm_heap *heap, bool full, bool silent)
22862294
heap->size = 0;
22872295
}
22882296

2297+
void (*shutdown)(bool, bool) = heap->custom_heap.std._shutdown;
2298+
22892299
if (full) {
22902300
if (ZEND_DEBUG && heap->use_custom_heap == ZEND_MM_CUSTOM_HEAP_DEBUG) {
22912301
heap->custom_heap.debug._free(heap ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC);
22922302
} else {
22932303
heap->custom_heap.std._free(heap);
22942304
}
22952305
}
2306+
2307+
if (shutdown) {
2308+
shutdown(full, silent);
2309+
}
2310+
22962311
return;
22972312
}
22982313
#endif
@@ -2895,8 +2910,8 @@ static void *tracked_realloc(void *ptr, size_t new_size) {
28952910
return ptr;
28962911
}
28972912

2898-
static void tracked_free_all(void) {
2899-
HashTable *tracked_allocs = AG(mm_heap)->tracked_allocs;
2913+
static void tracked_free_all(zend_mm_heap*heap) {
2914+
HashTable *tracked_allocs = heap->tracked_allocs;
29002915
zend_ulong h;
29012916
ZEND_HASH_FOREACH_NUM_KEY(tracked_allocs, h) {
29022917
void *ptr = (void *) (uintptr_t) (h << ZEND_MM_ALIGNMENT_LOG2);
@@ -2980,6 +2995,16 @@ ZEND_API zend_mm_heap *zend_mm_get_heap(void)
29802995
return AG(mm_heap);
29812996
}
29822997

2998+
ZEND_API zend_mm_heap *zend_mm_heap_create(void)
2999+
{
3000+
return zend_mm_init();
3001+
}
3002+
3003+
ZEND_API void zend_mm_heap_free(zend_mm_heap *heap)
3004+
{
3005+
zend_mm_chunk_free(heap, heap->main_chunk, ZEND_MM_CHUNK_SIZE);
3006+
}
3007+
29833008
ZEND_API bool zend_mm_is_custom_heap(zend_mm_heap *new_heap)
29843009
{
29853010
#if ZEND_MM_CUSTOM
@@ -2990,9 +3015,11 @@ ZEND_API bool zend_mm_is_custom_heap(zend_mm_heap *new_heap)
29903015
}
29913016

29923017
ZEND_API void zend_mm_set_custom_handlers(zend_mm_heap *heap,
2993-
void* (*_malloc)(size_t),
2994-
void (*_free)(void*),
2995-
void* (*_realloc)(void*, size_t))
3018+
void* (*_malloc)(size_t),
3019+
void (*_free)(void*),
3020+
void* (*_realloc)(void*, size_t),
3021+
size_t (*_gc)(void),
3022+
void (*_shutdown)(bool, bool))
29963023
{
29973024
#if ZEND_MM_CUSTOM
29983025
zend_mm_heap *_heap = (zend_mm_heap*)heap;
@@ -3004,14 +3031,18 @@ ZEND_API void zend_mm_set_custom_handlers(zend_mm_heap *heap,
30043031
_heap->custom_heap.std._malloc = _malloc;
30053032
_heap->custom_heap.std._free = _free;
30063033
_heap->custom_heap.std._realloc = _realloc;
3034+
_heap->custom_heap.std._gc = _gc;
3035+
_heap->custom_heap.std._shutdown = _shutdown;
30073036
}
30083037
#endif
30093038
}
30103039

30113040
ZEND_API void zend_mm_get_custom_handlers(zend_mm_heap *heap,
3012-
void* (**_malloc)(size_t),
3013-
void (**_free)(void*),
3014-
void* (**_realloc)(void*, size_t))
3041+
void* (**_malloc)(size_t),
3042+
void (**_free)(void*),
3043+
void* (**_realloc)(void*, size_t),
3044+
size_t (**_gc)(void),
3045+
void (**_shutdown)(bool, bool))
30153046
{
30163047
#if ZEND_MM_CUSTOM
30173048
zend_mm_heap *_heap = (zend_mm_heap*)heap;
@@ -3020,15 +3051,29 @@ ZEND_API void zend_mm_get_custom_handlers(zend_mm_heap *heap,
30203051
*_malloc = _heap->custom_heap.std._malloc;
30213052
*_free = _heap->custom_heap.std._free;
30223053
*_realloc = _heap->custom_heap.std._realloc;
3054+
if (_gc != NULL) {
3055+
*_gc = _heap->custom_heap.std._gc;
3056+
}
3057+
if (_shutdown != NULL) {
3058+
*_shutdown = _heap->custom_heap.std._shutdown;
3059+
}
30233060
} else {
30243061
*_malloc = NULL;
30253062
*_free = NULL;
30263063
*_realloc = NULL;
3064+
if (_gc != NULL) {
3065+
*_gc = NULL;
3066+
}
3067+
if (_shutdown != NULL) {
3068+
*_shutdown = NULL;
3069+
}
30273070
}
30283071
#else
30293072
*_malloc = NULL;
30303073
*_free = NULL;
30313074
*_realloc = NULL;
3075+
*_gc = NULL;
3076+
*_shutdown = NULL;
30323077
#endif
30333078
}
30343079

‎Zend/zend_alloc.h‎

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -261,6 +261,8 @@ ZEND_API size_t ZEND_FASTCALL _zend_mm_block_size(zend_mm_heap *heap, void *p ZE
261261
#define zend_mm_realloc2_rel(heap, p, size, copy_size) _zend_mm_realloc2((heap), (p), (size), (copy_size) ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_CC)
262262
#define zend_mm_block_size_rel(heap, p) _zend_mm_block_size((heap), (p) ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC)
263263

264+
ZEND_API zend_mm_heap *zend_mm_heap_create(void);
265+
ZEND_API void zend_mm_heap_free(zend_mm_heap* heap);
264266
ZEND_API zend_mm_heap *zend_mm_set_heap(zend_mm_heap *new_heap);
265267
ZEND_API zend_mm_heap *zend_mm_get_heap(void);
266268

@@ -274,11 +276,15 @@ ZEND_API bool zend_mm_is_custom_heap(zend_mm_heap *new_heap);
274276
ZEND_API void zend_mm_set_custom_handlers(zend_mm_heap *heap,
275277
void* (*_malloc)(size_t),
276278
void (*_free)(void*),
277-
void* (*_realloc)(void*, size_t));
279+
void* (*_realloc)(void*, size_t),
280+
size_t (*gc)(void),
281+
void (*shutdown)(bool full, bool silent));
278282
ZEND_API void zend_mm_get_custom_handlers(zend_mm_heap *heap,
279283
void* (**_malloc)(size_t),
280284
void (**_free)(void*),
281-
void* (**_realloc)(void*, size_t));
285+
void* (**_realloc)(void*, size_t),
286+
size_t (**gc)(void),
287+
void (**shutdown)(bool full, bool silent));
282288

283289
#if ZEND_DEBUG
284290
ZEND_API void zend_mm_set_custom_debug_handlers(zend_mm_heap *heap,

‎ext/zend_test/config.m4‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,5 @@ PHP_ARG_ENABLE([zend-test],
44
[Enable zend_test extension])])
55

66
if test "$PHP_ZEND_TEST" != "no"; then
7-
PHP_NEW_EXTENSION(zend_test, test.c observer.c fiber.c iterators.c object_handlers.c, $ext_shared,, -DZEND_ENABLE_STATIC_TSRMLS_CACHE=1)
7+
PHP_NEW_EXTENSION(zend_test, test.c observer.c fiber.c iterators.c object_handlers.c zend_mm_custom_handlers.c, $ext_shared,, -DZEND_ENABLE_STATIC_TSRMLS_CACHE=1)
88
fi

‎ext/zend_test/config.w32‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,6 @@
33
ARG_ENABLE("zend-test", "enable zend_test extension", "no");
44

55
if (PHP_ZEND_TEST != "no") {
6-
EXTENSION("zend_test", "test.c observer.c fiber.c iterators.c object_handlers.c", PHP_ZEND_TEST_SHARED, "/DZEND_ENABLE_STATIC_TSRMLS_CACHE=1");
6+
EXTENSION("zend_test", "test.c observer.c fiber.c iterators.c object_handlers.c zend_mm_custom_handlers.c", PHP_ZEND_TEST_SHARED, "/DZEND_ENABLE_STATIC_TSRMLS_CACHE=1");
77
ADD_FLAG("CFLAGS_ZEND_TEST", "/D PHP_ZEND_TEST_EXPORTS ");
88
}

‎ext/zend_test/php_test.h‎

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,19 @@ ZEND_BEGIN_MODULE_GLOBALS(zend_test)
6262
zend_long quantity_value;
6363
zend_string *str_test;
6464
zend_string *not_empty_str_test;
65+
int zend_mm_custom_handlers_enabled;
66+
67+
// the previous heap that was found in ZendMM
68+
zend_mm_heap* original_heap;
69+
// the custom handlers that might have been found in the previous heap
70+
void* (*custom_malloc)(size_t);
71+
void (*custom_free)(void*);
72+
void* (*custom_realloc)(void *, size_t);
73+
size_t (*custom_gc)(void);
74+
void (*custom_shutdown)(bool, bool);
75+
// this is our heap that we install our custom handlers on and inject into
76+
// ZendMM
77+
zend_mm_heap* observed_heap;
6578
ZEND_END_MODULE_GLOBALS(zend_test)
6679

6780
extern ZEND_DECLARE_MODULE_GLOBALS(zend_test)

‎ext/zend_test/test.c‎

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
+----------------------------------------------------------------------+
1515
*/
1616

17+
#include "zend_modules.h"
1718
#ifdef HAVE_CONFIG_H
1819
# include "config.h"
1920
#endif
@@ -35,6 +36,7 @@
3536
#include "test_arginfo.h"
3637
#include "zend_call_stack.h"
3738
#include "zend_exceptions.h"
39+
#include "zend_mm_custom_handlers.h"
3840

3941
// `php.h` sets `NDEBUG` when not `PHP_DEBUG` which will make `assert()` from
4042
// assert.h a no-op. In order to have `assert()` working on NDEBUG builds, we
@@ -682,7 +684,9 @@ static PHP_INI_MH(OnUpdateZendTestObserveOplineInZendMM)
682684
ZT_G(zend_test_heap),
683685
zend_test_custom_malloc,
684686
zend_test_custom_free,
685-
zend_test_custom_realloc
687+
zend_test_custom_realloc,
688+
NULL,
689+
NULL
686690
);
687691
ZT_G(zend_orig_heap) = zend_mm_get_heap();
688692
zend_mm_set_heap(ZT_G(zend_test_heap));
@@ -1189,6 +1193,7 @@ PHP_MINIT_FUNCTION(zend_test)
11891193
}
11901194

11911195
zend_test_observer_init(INIT_FUNC_ARGS_PASSTHRU);
1196+
zend_test_mm_custom_handlers_minit(INIT_FUNC_ARGS_PASSTHRU);
11921197
zend_test_fiber_init();
11931198
zend_test_iterators_init();
11941199
zend_test_object_handlers_init();
@@ -1217,6 +1222,7 @@ PHP_RINIT_FUNCTION(zend_test)
12171222
{
12181223
zend_hash_init(&ZT_G(global_weakmap), 8, NULL, ZVAL_PTR_DTOR, 0);
12191224
ZT_G(observer_nesting_depth) = 0;
1225+
zend_test_mm_custom_handlers_rinit();
12201226
return SUCCESS;
12211227
}
12221228

@@ -1234,6 +1240,7 @@ PHP_RSHUTDOWN_FUNCTION(zend_test)
12341240
zend_mm_set_heap(ZT_G(zend_orig_heap));
12351241
}
12361242

1243+
zend_test_mm_custom_handlers_rshutdown();
12371244
return SUCCESS;
12381245
}
12391246

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
--TEST--
2+
ZendMM Custom Handlers: garbage collection
3+
--EXTENSIONS--
4+
zend_test
5+
--FILE--
6+
<?php
7+
ini_set('zend_test.zend_mm_custom_handlers.enabled', 1);
8+
$string = str_repeat('String', rand(1,100));
9+
ini_set('zend_test.zend_mm_custom_handlers.enabled', 0);
10+
?>
11+
--EXPECTREGEX--
12+
.*Allocated \d+ bytes at.*
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
--TEST--
2+
ZendMM Custom Handlers: garbage collection
3+
--EXTENSIONS--
4+
zend_test
5+
--FILE--
6+
<?php
7+
$string = str_repeat('String', rand(1,100));
8+
ini_set('zend_test.zend_mm_custom_handlers.enabled', 1);
9+
unset($string);
10+
ini_set('zend_test.zend_mm_custom_handlers.enabled', 0);
11+
?>
12+
--EXPECTREGEX--
13+
.*Freed memory at.*
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
--TEST--
2+
ZendMM Custom Handlers: garbage collection
3+
--EXTENSIONS--
4+
zend_test
5+
--FILE--
6+
<?php
7+
ini_set('zend_test.zend_mm_custom_handlers.enabled', 1);
8+
gc_mem_caches();
9+
ini_set('zend_test.zend_mm_custom_handlers.enabled', 0);
10+
?>
11+
--EXPECTREGEX--
12+
.*ZendMM GC freed \d+ bytes.*

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /