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 504a130

Browse files
add gc and shutdown callbacks
1 parent ac94792 commit 504a130

12 files changed

+322
-20
lines changed

‎Zend/zend_alloc.c‎

Lines changed: 50 additions & 7 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);
@@ -3124,6 +3137,16 @@ ZEND_API zend_mm_heap *zend_mm_get_heap(void)
31243137
return AG(mm_heap);
31253138
}
31263139

3140+
ZEND_API zend_mm_heap *zend_mm_heap_create(void)
3141+
{
3142+
return zend_mm_init();
3143+
}
3144+
3145+
ZEND_API void zend_mm_heap_free(zend_mm_heap *heap)
3146+
{
3147+
zend_mm_chunk_free(heap, heap->main_chunk, ZEND_MM_CHUNK_SIZE);
3148+
}
3149+
31273150
ZEND_API bool zend_mm_is_custom_heap(zend_mm_heap *new_heap)
31283151
{
31293152
#if ZEND_MM_CUSTOM
@@ -3136,7 +3159,9 @@ ZEND_API bool zend_mm_is_custom_heap(zend_mm_heap *new_heap)
31363159
ZEND_API void zend_mm_set_custom_handlers(zend_mm_heap *heap,
31373160
void* (*_malloc)(size_t ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC),
31383161
void (*_free)(void* ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC),
3139-
void* (*_realloc)(void*, size_t 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))
31403165
{
31413166
#if ZEND_MM_CUSTOM
31423167
zend_mm_heap *_heap = (zend_mm_heap*)heap;
@@ -3148,14 +3173,18 @@ 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,
31563183
void* (**_malloc)(size_t ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC),
31573184
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))
3185+
void* (**_realloc)(void*, size_t ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC),
3186+
size_t (**_gc)(void),
3187+
void (**_shutdown)(bool, bool))
31593188
{
31603189
#if ZEND_MM_CUSTOM
31613190
zend_mm_heap *_heap = (zend_mm_heap*)heap;
@@ -3164,15 +3193,29 @@ ZEND_API void zend_mm_get_custom_handlers(zend_mm_heap *heap,
31643193
*_malloc = _heap->custom_heap._malloc;
31653194
*_free = _heap->custom_heap._free;
31663195
*_realloc = _heap->custom_heap._realloc;
3196+
if (_gc != NULL) {
3197+
*_gc = _heap->custom_heap._gc;
3198+
}
3199+
if (_shutdown != NULL) {
3200+
*_shutdown = _heap->custom_heap._shutdown;
3201+
}
31673202
} else {
31683203
*_malloc = NULL;
31693204
*_free = NULL;
31703205
*_realloc = NULL;
3206+
if (_gc != NULL) {
3207+
*_gc = NULL;
3208+
}
3209+
if (_shutdown != NULL) {
3210+
*_shutdown = NULL;
3211+
}
31713212
}
31723213
#else
31733214
*_malloc = NULL;
31743215
*_free = NULL;
31753216
*_realloc = NULL;
3217+
*_gc = NULL;
3218+
*_shutdown = NULL;
31763219
#endif
31773220
}
31783221

‎Zend/zend_alloc.h‎

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -263,6 +263,8 @@ ZEND_API size_t ZEND_FASTCALL _zend_mm_block_size(zend_mm_heap *heap, void *p ZE
263263
#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)
264264
#define zend_mm_block_size_rel(heap, p) _zend_mm_block_size((heap), (p) ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC)
265265

266+
ZEND_API zend_mm_heap *zend_mm_heap_create(void);
267+
ZEND_API void zend_mm_heap_free(zend_mm_heap* heap);
266268
ZEND_API zend_mm_heap *zend_mm_set_heap(zend_mm_heap *new_heap);
267269
ZEND_API zend_mm_heap *zend_mm_get_heap(void);
268270

@@ -274,13 +276,17 @@ ZEND_API size_t zend_mm_gc(zend_mm_heap *heap);
274276

275277
ZEND_API bool zend_mm_is_custom_heap(zend_mm_heap *new_heap);
276278
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));
279+
void* (*_malloc)(size_t ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC),
280+
void (*_free)(void* ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC),
281+
void* (*_realloc)(void*, size_t ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC),
282+
size_t (*_gc)(void),
283+
void (*_shutdown)(bool, bool));
280284
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));
285+
void* (**_malloc)(size_t ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC),
286+
void (**_free)(void* ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC),
287+
void* (**_realloc)(void*, size_t ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC),
288+
size_t (**_gc)(void),
289+
void (**_shutdown)(bool, bool));
284290

285291
typedef struct _zend_mm_storage zend_mm_storage;
286292

‎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: 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
@@ -707,7 +709,9 @@ static PHP_INI_MH(OnUpdateZendTestObserveOplineInZendMM)
707709
ZT_G(zend_test_heap),
708710
zend_test_custom_malloc,
709711
zend_test_custom_free,
710-
zend_test_custom_realloc
712+
zend_test_custom_realloc,
713+
NULL,
714+
NULL
711715
);
712716
ZT_G(zend_orig_heap) = zend_mm_get_heap();
713717
zend_mm_set_heap(ZT_G(zend_test_heap));
@@ -1260,6 +1264,7 @@ PHP_MINIT_FUNCTION(zend_test)
12601264
}
12611265

12621266
zend_test_observer_init(INIT_FUNC_ARGS_PASSTHRU);
1267+
zend_test_mm_custom_handlers_minit(INIT_FUNC_ARGS_PASSTHRU);
12631268
zend_test_fiber_init();
12641269
zend_test_iterators_init();
12651270
zend_test_object_handlers_init();
@@ -1288,6 +1293,7 @@ PHP_RINIT_FUNCTION(zend_test)
12881293
{
12891294
zend_hash_init(&ZT_G(global_weakmap), 8, NULL, ZVAL_PTR_DTOR, 0);
12901295
ZT_G(observer_nesting_depth) = 0;
1296+
zend_test_mm_custom_handlers_rinit();
12911297
return SUCCESS;
12921298
}
12931299

@@ -1305,6 +1311,7 @@ PHP_RSHUTDOWN_FUNCTION(zend_test)
13051311
zend_mm_set_heap(ZT_G(zend_orig_heap));
13061312
}
13071313

1314+
zend_test_mm_custom_handlers_rshutdown();
13081315
return SUCCESS;
13091316
}
13101317

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