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 d476664

Browse files
add gc and shutdown callbacks
1 parent 14873dd commit d476664

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
@@ -272,6 +272,8 @@ struct _zend_mm_heap {
272272
void *(*_malloc)(size_t ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC);
273273
void (*_free)(void* ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC);
274274
void *(*_realloc)(void*, size_t ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC);
275+
size_t (*_gc)(void);
276+
void (*_shutdown)(bool full, bool silent);
275277
} custom_heap;
276278
HashTable *tracked_allocs;
277279
#endif
@@ -1961,6 +1963,10 @@ ZEND_API size_t zend_mm_gc(zend_mm_heap *heap)
19611963

19621964
#if ZEND_MM_CUSTOM
19631965
if (heap->use_custom_heap) {
1966+
size_t (*gc)(void) = heap->custom_heap._gc;
1967+
if (gc) {
1968+
return gc();
1969+
}
19641970
return 0;
19651971
}
19661972
#endif
@@ -2255,10 +2261,10 @@ static void zend_mm_check_leaks(zend_mm_heap *heap)
22552261

22562262
#if ZEND_MM_CUSTOM
22572263
static void *tracked_malloc(size_t size ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC);
2258-
static void tracked_free_all(void);
2264+
static void tracked_free_all(zend_mm_heap*heap);
22592265
#endif
22602266

2261-
void zend_mm_shutdown(zend_mm_heap *heap, bool full, bool silent)
2267+
ZEND_APIvoid zend_mm_shutdown(zend_mm_heap *heap, bool full, bool silent)
22622268
{
22632269
zend_mm_chunk *p;
22642270
zend_mm_huge_list *list;
@@ -2267,7 +2273,7 @@ void zend_mm_shutdown(zend_mm_heap *heap, bool full, bool silent)
22672273
if (heap->use_custom_heap) {
22682274
if (heap->custom_heap._malloc == tracked_malloc) {
22692275
if (silent) {
2270-
tracked_free_all();
2276+
tracked_free_all(heap);
22712277
}
22722278
zend_hash_clean(heap->tracked_allocs);
22732279
if (full) {
@@ -2279,9 +2285,16 @@ void zend_mm_shutdown(zend_mm_heap *heap, bool full, bool silent)
22792285
heap->size = 0;
22802286
}
22812287

2288+
void (*shutdown)(bool, bool) = heap->custom_heap._shutdown;
2289+
22822290
if (full) {
22832291
heap->custom_heap._free(heap ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC);
22842292
}
2293+
2294+
if (shutdown) {
2295+
shutdown(full, silent);
2296+
}
2297+
22852298
return;
22862299
}
22872300
#endif
@@ -2854,8 +2867,8 @@ static void *tracked_realloc(void *ptr, size_t new_size ZEND_FILE_LINE_DC ZEND_F
28542867
return ptr;
28552868
}
28562869

2857-
static void tracked_free_all(void) {
2858-
HashTable *tracked_allocs = AG(mm_heap)->tracked_allocs;
2870+
static void tracked_free_all(zend_mm_heap*heap) {
2871+
HashTable *tracked_allocs = heap->tracked_allocs;
28592872
zend_ulong h;
28602873
ZEND_HASH_FOREACH_NUM_KEY(tracked_allocs, h) {
28612874
void *ptr = (void *) (uintptr_t) (h << ZEND_MM_ALIGNMENT_LOG2);
@@ -2939,6 +2952,16 @@ ZEND_API zend_mm_heap *zend_mm_get_heap(void)
29392952
return AG(mm_heap);
29402953
}
29412954

2955+
ZEND_API zend_mm_heap *zend_mm_heap_create(void)
2956+
{
2957+
return zend_mm_init();
2958+
}
2959+
2960+
ZEND_API void zend_mm_heap_free(zend_mm_heap *heap)
2961+
{
2962+
zend_mm_chunk_free(heap, heap->main_chunk, ZEND_MM_CHUNK_SIZE);
2963+
}
2964+
29422965
ZEND_API bool zend_mm_is_custom_heap(zend_mm_heap *new_heap)
29432966
{
29442967
#if ZEND_MM_CUSTOM
@@ -2951,7 +2974,9 @@ ZEND_API bool zend_mm_is_custom_heap(zend_mm_heap *new_heap)
29512974
ZEND_API void zend_mm_set_custom_handlers(zend_mm_heap *heap,
29522975
void* (*_malloc)(size_t ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC),
29532976
void (*_free)(void* ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC),
2954-
void* (*_realloc)(void*, size_t ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC))
2977+
void* (*_realloc)(void*, size_t ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC),
2978+
size_t (*_gc)(void),
2979+
void (*_shutdown)(bool, bool))
29552980
{
29562981
#if ZEND_MM_CUSTOM
29572982
zend_mm_heap *_heap = (zend_mm_heap*)heap;
@@ -2963,14 +2988,18 @@ ZEND_API void zend_mm_set_custom_handlers(zend_mm_heap *heap,
29632988
_heap->custom_heap._malloc = _malloc;
29642989
_heap->custom_heap._free = _free;
29652990
_heap->custom_heap._realloc = _realloc;
2991+
_heap->custom_heap._gc = _gc;
2992+
_heap->custom_heap._shutdown = _shutdown;
29662993
}
29672994
#endif
29682995
}
29692996

29702997
ZEND_API void zend_mm_get_custom_handlers(zend_mm_heap *heap,
29712998
void* (**_malloc)(size_t ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC),
29722999
void (**_free)(void* ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC),
2973-
void* (**_realloc)(void*, size_t ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC))
3000+
void* (**_realloc)(void*, size_t ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC),
3001+
size_t (**_gc)(void),
3002+
void (**_shutdown)(bool, bool))
29743003
{
29753004
#if ZEND_MM_CUSTOM
29763005
zend_mm_heap *_heap = (zend_mm_heap*)heap;
@@ -2979,15 +3008,29 @@ ZEND_API void zend_mm_get_custom_handlers(zend_mm_heap *heap,
29793008
*_malloc = _heap->custom_heap._malloc;
29803009
*_free = _heap->custom_heap._free;
29813010
*_realloc = _heap->custom_heap._realloc;
3011+
if (_gc != NULL) {
3012+
*_gc = _heap->custom_heap._gc;
3013+
}
3014+
if (_shutdown != NULL) {
3015+
*_shutdown = _heap->custom_heap._shutdown;
3016+
}
29823017
} else {
29833018
*_malloc = NULL;
29843019
*_free = NULL;
29853020
*_realloc = NULL;
3021+
if (_gc != NULL) {
3022+
*_gc = NULL;
3023+
}
3024+
if (_shutdown != NULL) {
3025+
*_shutdown = NULL;
3026+
}
29863027
}
29873028
#else
29883029
*_malloc = NULL;
29893030
*_free = NULL;
29903031
*_realloc = NULL;
3032+
*_gc = NULL;
3033+
*_shutdown = NULL;
29913034
#endif
29923035
}
29933036

‎Zend/zend_alloc.h‎

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

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

@@ -273,13 +275,17 @@ ZEND_API size_t zend_mm_gc(zend_mm_heap *heap);
273275

274276
ZEND_API bool zend_mm_is_custom_heap(zend_mm_heap *new_heap);
275277
ZEND_API void zend_mm_set_custom_handlers(zend_mm_heap *heap,
276-
void* (*_malloc)(size_t ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC),
277-
void (*_free)(void* ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC),
278-
void* (*_realloc)(void*, size_t ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC));
278+
void* (*_malloc)(size_t ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC),
279+
void (*_free)(void* ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC),
280+
void* (*_realloc)(void*, size_t ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC),
281+
size_t (*_gc)(void),
282+
void (*_shutdown)(bool, bool));
279283
ZEND_API void zend_mm_get_custom_handlers(zend_mm_heap *heap,
280-
void* (**_malloc)(size_t ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC),
281-
void (**_free)(void* ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC),
282-
void* (**_realloc)(void*, size_t ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC));
284+
void* (**_malloc)(size_t ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC),
285+
void (**_free)(void* ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC),
286+
void* (**_realloc)(void*, size_t ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC),
287+
size_t (**_gc)(void),
288+
void (**_shutdown)(bool, bool));
283289

284290
typedef struct _zend_mm_storage zend_mm_storage;
285291

‎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
@@ -684,7 +686,9 @@ static PHP_INI_MH(OnUpdateZendTestObserveOplineInZendMM)
684686
ZT_G(zend_test_heap),
685687
zend_test_custom_malloc,
686688
zend_test_custom_free,
687-
zend_test_custom_realloc
689+
zend_test_custom_realloc,
690+
NULL,
691+
NULL
688692
);
689693
ZT_G(zend_orig_heap) = zend_mm_get_heap();
690694
zend_mm_set_heap(ZT_G(zend_test_heap));
@@ -1193,6 +1197,7 @@ PHP_MINIT_FUNCTION(zend_test)
11931197
}
11941198

11951199
zend_test_observer_init(INIT_FUNC_ARGS_PASSTHRU);
1200+
zend_test_mm_custom_handlers_minit(INIT_FUNC_ARGS_PASSTHRU);
11961201
zend_test_fiber_init();
11971202
zend_test_iterators_init();
11981203
zend_test_object_handlers_init();
@@ -1221,6 +1226,7 @@ PHP_RINIT_FUNCTION(zend_test)
12211226
{
12221227
zend_hash_init(&ZT_G(global_weakmap), 8, NULL, ZVAL_PTR_DTOR, 0);
12231228
ZT_G(observer_nesting_depth) = 0;
1229+
zend_test_mm_custom_handlers_rinit();
12241230
return SUCCESS;
12251231
}
12261232

@@ -1238,6 +1244,7 @@ PHP_RSHUTDOWN_FUNCTION(zend_test)
12381244
zend_mm_set_heap(ZT_G(zend_orig_heap));
12391245
}
12401246

1247+
zend_test_mm_custom_handlers_rshutdown();
12411248
return SUCCESS;
12421249
}
12431250

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