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 f4557b4

Browse files
Add gc and shutdown callbacks to ZendMM custom handlers (#13432)
1 parent a1ea464 commit f4557b4

11 files changed

+340
-16
lines changed

‎Zend/zend_alloc.c‎

Lines changed: 61 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -334,6 +334,8 @@ struct _zend_mm_heap {
334334
void *(*_malloc)(size_t ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC);
335335
void (*_free)(void* ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC);
336336
void *(*_realloc)(void*, size_t ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC);
337+
size_t (*_gc)(void);
338+
void (*_shutdown)(bool full, bool silent);
337339
} custom_heap;
338340
HashTable *tracked_allocs;
339341
#endif
@@ -2119,6 +2121,10 @@ ZEND_API size_t zend_mm_gc(zend_mm_heap *heap)
21192121

21202122
#if ZEND_MM_CUSTOM
21212123
if (heap->use_custom_heap) {
2124+
size_t (*gc)(void) = heap->custom_heap._gc;
2125+
if (gc) {
2126+
return gc();
2127+
}
21222128
return 0;
21232129
}
21242130
#endif
@@ -2421,10 +2427,10 @@ static void zend_mm_check_leaks(zend_mm_heap *heap)
24212427

24222428
#if ZEND_MM_CUSTOM
24232429
static void *tracked_malloc(size_t size ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC);
2424-
static void tracked_free_all(void);
2430+
static void tracked_free_all(zend_mm_heap*heap);
24252431
#endif
24262432

2427-
void zend_mm_shutdown(zend_mm_heap *heap, bool full, bool silent)
2433+
ZEND_APIvoid zend_mm_shutdown(zend_mm_heap *heap, bool full, bool silent)
24282434
{
24292435
zend_mm_chunk *p;
24302436
zend_mm_huge_list *list;
@@ -2433,7 +2439,7 @@ void zend_mm_shutdown(zend_mm_heap *heap, bool full, bool silent)
24332439
if (heap->use_custom_heap) {
24342440
if (heap->custom_heap._malloc == tracked_malloc) {
24352441
if (silent) {
2436-
tracked_free_all();
2442+
tracked_free_all(heap);
24372443
}
24382444
zend_hash_clean(heap->tracked_allocs);
24392445
if (full) {
@@ -2445,9 +2451,16 @@ void zend_mm_shutdown(zend_mm_heap *heap, bool full, bool silent)
24452451
heap->size = 0;
24462452
}
24472453

2454+
void (*shutdown)(bool, bool) = heap->custom_heap._shutdown;
2455+
24482456
if (full) {
24492457
heap->custom_heap._free(heap ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC);
24502458
}
2459+
2460+
if (shutdown) {
2461+
shutdown(full, silent);
2462+
}
2463+
24512464
return;
24522465
}
24532466
#endif
@@ -3039,8 +3052,8 @@ static void *tracked_realloc(void *ptr, size_t new_size ZEND_FILE_LINE_DC ZEND_F
30393052
return ptr;
30403053
}
30413054

3042-
static void tracked_free_all(void) {
3043-
HashTable *tracked_allocs = AG(mm_heap)->tracked_allocs;
3055+
static void tracked_free_all(zend_mm_heap*heap) {
3056+
HashTable *tracked_allocs = heap->tracked_allocs;
30443057
zend_ulong h;
30453058
ZEND_HASH_FOREACH_NUM_KEY(tracked_allocs, h) {
30463059
void *ptr = (void *) (uintptr_t) (h << ZEND_MM_ALIGNMENT_LOG2);
@@ -3138,6 +3151,18 @@ ZEND_API void zend_mm_set_custom_handlers(zend_mm_heap *heap,
31383151
void (*_free)(void* ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC),
31393152
void* (*_realloc)(void*, size_t ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC))
31403153
{
3154+
#if ZEND_MM_CUSTOM
3155+
zend_mm_set_custom_handlers_ex(heap, _malloc, _free, _realloc, NULL, NULL);
3156+
#endif
3157+
}
3158+
3159+
ZEND_API void zend_mm_set_custom_handlers_ex(zend_mm_heap *heap,
3160+
void* (*_malloc)(size_t ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC),
3161+
void (*_free)(void* ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC),
3162+
void* (*_realloc)(void*, size_t ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC),
3163+
size_t (*_gc)(void),
3164+
void (*_shutdown)(bool, bool))
3165+
{
31413166
#if ZEND_MM_CUSTOM
31423167
zend_mm_heap *_heap = (zend_mm_heap*)heap;
31433168

@@ -3148,14 +3173,28 @@ ZEND_API void zend_mm_set_custom_handlers(zend_mm_heap *heap,
31483173
_heap->custom_heap._malloc = _malloc;
31493174
_heap->custom_heap._free = _free;
31503175
_heap->custom_heap._realloc = _realloc;
3176+
_heap->custom_heap._gc = _gc;
3177+
_heap->custom_heap._shutdown = _shutdown;
31513178
}
31523179
#endif
31533180
}
31543181

31553182
ZEND_API void zend_mm_get_custom_handlers(zend_mm_heap *heap,
3156-
void* (**_malloc)(size_t ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC),
3157-
void (**_free)(void* ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC),
3158-
void* (**_realloc)(void*, size_t ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC))
3183+
void* (**_malloc)(size_t ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC),
3184+
void (**_free)(void* ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC),
3185+
void* (**_realloc)(void*, size_t ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC))
3186+
{
3187+
#if ZEND_MM_CUSTOM
3188+
zend_mm_get_custom_handlers_ex(heap, _malloc, _free, _realloc, NULL, NULL);
3189+
#endif
3190+
}
3191+
3192+
ZEND_API void zend_mm_get_custom_handlers_ex(zend_mm_heap *heap,
3193+
void* (**_malloc)(size_t ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC),
3194+
void (**_free)(void* ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC),
3195+
void* (**_realloc)(void*, size_t ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC),
3196+
size_t (**_gc)(void),
3197+
void (**_shutdown)(bool, bool))
31593198
{
31603199
#if ZEND_MM_CUSTOM
31613200
zend_mm_heap *_heap = (zend_mm_heap*)heap;
@@ -3164,15 +3203,29 @@ ZEND_API void zend_mm_get_custom_handlers(zend_mm_heap *heap,
31643203
*_malloc = _heap->custom_heap._malloc;
31653204
*_free = _heap->custom_heap._free;
31663205
*_realloc = _heap->custom_heap._realloc;
3206+
if (_gc != NULL) {
3207+
*_gc = _heap->custom_heap._gc;
3208+
}
3209+
if (_shutdown != NULL) {
3210+
*_shutdown = _heap->custom_heap._shutdown;
3211+
}
31673212
} else {
31683213
*_malloc = NULL;
31693214
*_free = NULL;
31703215
*_realloc = NULL;
3216+
if (_gc != NULL) {
3217+
*_gc = NULL;
3218+
}
3219+
if (_shutdown != NULL) {
3220+
*_shutdown = NULL;
3221+
}
31713222
}
31723223
#else
31733224
*_malloc = NULL;
31743225
*_free = NULL;
31753226
*_realloc = NULL;
3227+
*_gc = NULL;
3228+
*_shutdown = NULL;
31763229
#endif
31773230
}
31783231

‎Zend/zend_alloc.h‎

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -274,13 +274,25 @@ ZEND_API size_t zend_mm_gc(zend_mm_heap *heap);
274274

275275
ZEND_API bool zend_mm_is_custom_heap(zend_mm_heap *new_heap);
276276
ZEND_API void zend_mm_set_custom_handlers(zend_mm_heap *heap,
277-
void* (*_malloc)(size_t ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC),
278-
void (*_free)(void* ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC),
279-
void* (*_realloc)(void*, size_t ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC));
277+
void* (*_malloc)(size_t ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC),
278+
void (*_free)(void* ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC),
279+
void* (*_realloc)(void*, size_t ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC));
280+
ZEND_API void zend_mm_set_custom_handlers_ex(zend_mm_heap *heap,
281+
void* (*_malloc)(size_t ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC),
282+
void (*_free)(void* ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC),
283+
void* (*_realloc)(void*, size_t ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC),
284+
size_t (*_gc)(void),
285+
void (*_shutdown)(bool, bool));
280286
ZEND_API void zend_mm_get_custom_handlers(zend_mm_heap *heap,
281-
void* (**_malloc)(size_t ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC),
282-
void (**_free)(void* ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC),
283-
void* (**_realloc)(void*, size_t ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC));
287+
void* (**_malloc)(size_t ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC),
288+
void (**_free)(void* ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC),
289+
void* (**_realloc)(void*, size_t ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC));
290+
ZEND_API void zend_mm_get_custom_handlers_ex(zend_mm_heap *heap,
291+
void* (**_malloc)(size_t ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC),
292+
void (**_free)(void* ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC),
293+
void* (**_realloc)(void*, size_t ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC),
294+
size_t (**_gc)(void),
295+
void (**_shutdown)(bool, bool));
284296

285297
typedef struct _zend_mm_storage zend_mm_storage;
286298

‎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 ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC);
71+
void (*custom_free)(void* ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC);
72+
void* (*custom_realloc)(void *, size_t ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC);
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: 5 additions & 0 deletions
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
@@ -1282,6 +1284,7 @@ PHP_MINIT_FUNCTION(zend_test)
12821284
}
12831285

12841286
zend_test_observer_init(INIT_FUNC_ARGS_PASSTHRU);
1287+
zend_test_mm_custom_handlers_minit(INIT_FUNC_ARGS_PASSTHRU);
12851288
zend_test_fiber_init();
12861289
zend_test_iterators_init();
12871290
zend_test_object_handlers_init();
@@ -1310,6 +1313,7 @@ PHP_RINIT_FUNCTION(zend_test)
13101313
{
13111314
zend_hash_init(&ZT_G(global_weakmap), 8, NULL, ZVAL_PTR_DTOR, 0);
13121315
ZT_G(observer_nesting_depth) = 0;
1316+
zend_test_mm_custom_handlers_rinit();
13131317
return SUCCESS;
13141318
}
13151319

@@ -1327,6 +1331,7 @@ PHP_RSHUTDOWN_FUNCTION(zend_test)
13271331
zend_mm_set_heap(ZT_G(zend_orig_heap));
13281332
}
13291333

1334+
zend_test_mm_custom_handlers_rshutdown();
13301335
return SUCCESS;
13311336
}
13321337

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 によって変換されたページ (->オリジナル) /