mirror of
https://github.com/php/php-src.git
synced 2024-11-23 01:44:06 +08:00
Add gc
and shutdown
callbacks to ZendMM custom handlers (#13432)
This commit is contained in:
parent
a1ea464069
commit
f4557b48a6
@ -334,6 +334,8 @@ struct _zend_mm_heap {
|
||||
void *(*_malloc)(size_t ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC);
|
||||
void (*_free)(void* ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC);
|
||||
void *(*_realloc)(void*, size_t ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC);
|
||||
size_t (*_gc)(void);
|
||||
void (*_shutdown)(bool full, bool silent);
|
||||
} custom_heap;
|
||||
HashTable *tracked_allocs;
|
||||
#endif
|
||||
@ -2119,6 +2121,10 @@ ZEND_API size_t zend_mm_gc(zend_mm_heap *heap)
|
||||
|
||||
#if ZEND_MM_CUSTOM
|
||||
if (heap->use_custom_heap) {
|
||||
size_t (*gc)(void) = heap->custom_heap._gc;
|
||||
if (gc) {
|
||||
return gc();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
@ -2421,10 +2427,10 @@ static void zend_mm_check_leaks(zend_mm_heap *heap)
|
||||
|
||||
#if ZEND_MM_CUSTOM
|
||||
static void *tracked_malloc(size_t size ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC);
|
||||
static void tracked_free_all(void);
|
||||
static void tracked_free_all(zend_mm_heap *heap);
|
||||
#endif
|
||||
|
||||
void zend_mm_shutdown(zend_mm_heap *heap, bool full, bool silent)
|
||||
ZEND_API void zend_mm_shutdown(zend_mm_heap *heap, bool full, bool silent)
|
||||
{
|
||||
zend_mm_chunk *p;
|
||||
zend_mm_huge_list *list;
|
||||
@ -2433,7 +2439,7 @@ void zend_mm_shutdown(zend_mm_heap *heap, bool full, bool silent)
|
||||
if (heap->use_custom_heap) {
|
||||
if (heap->custom_heap._malloc == tracked_malloc) {
|
||||
if (silent) {
|
||||
tracked_free_all();
|
||||
tracked_free_all(heap);
|
||||
}
|
||||
zend_hash_clean(heap->tracked_allocs);
|
||||
if (full) {
|
||||
@ -2445,9 +2451,16 @@ void zend_mm_shutdown(zend_mm_heap *heap, bool full, bool silent)
|
||||
heap->size = 0;
|
||||
}
|
||||
|
||||
void (*shutdown)(bool, bool) = heap->custom_heap._shutdown;
|
||||
|
||||
if (full) {
|
||||
heap->custom_heap._free(heap ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC);
|
||||
}
|
||||
|
||||
if (shutdown) {
|
||||
shutdown(full, silent);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
@ -3039,8 +3052,8 @@ static void *tracked_realloc(void *ptr, size_t new_size ZEND_FILE_LINE_DC ZEND_F
|
||||
return ptr;
|
||||
}
|
||||
|
||||
static void tracked_free_all(void) {
|
||||
HashTable *tracked_allocs = AG(mm_heap)->tracked_allocs;
|
||||
static void tracked_free_all(zend_mm_heap *heap) {
|
||||
HashTable *tracked_allocs = heap->tracked_allocs;
|
||||
zend_ulong h;
|
||||
ZEND_HASH_FOREACH_NUM_KEY(tracked_allocs, h) {
|
||||
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,
|
||||
void (*_free)(void* ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC),
|
||||
void* (*_realloc)(void*, size_t ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC))
|
||||
{
|
||||
#if ZEND_MM_CUSTOM
|
||||
zend_mm_set_custom_handlers_ex(heap, _malloc, _free, _realloc, NULL, NULL);
|
||||
#endif
|
||||
}
|
||||
|
||||
ZEND_API void zend_mm_set_custom_handlers_ex(zend_mm_heap *heap,
|
||||
void* (*_malloc)(size_t ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC),
|
||||
void (*_free)(void* ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC),
|
||||
void* (*_realloc)(void*, size_t ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC),
|
||||
size_t (*_gc)(void),
|
||||
void (*_shutdown)(bool, bool))
|
||||
{
|
||||
#if ZEND_MM_CUSTOM
|
||||
zend_mm_heap *_heap = (zend_mm_heap*)heap;
|
||||
|
||||
@ -3148,14 +3173,28 @@ ZEND_API void zend_mm_set_custom_handlers(zend_mm_heap *heap,
|
||||
_heap->custom_heap._malloc = _malloc;
|
||||
_heap->custom_heap._free = _free;
|
||||
_heap->custom_heap._realloc = _realloc;
|
||||
_heap->custom_heap._gc = _gc;
|
||||
_heap->custom_heap._shutdown = _shutdown;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
ZEND_API void zend_mm_get_custom_handlers(zend_mm_heap *heap,
|
||||
void* (**_malloc)(size_t ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC),
|
||||
void (**_free)(void* ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC),
|
||||
void* (**_realloc)(void*, size_t ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC))
|
||||
void* (**_malloc)(size_t ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC),
|
||||
void (**_free)(void* ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC),
|
||||
void* (**_realloc)(void*, size_t ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC))
|
||||
{
|
||||
#if ZEND_MM_CUSTOM
|
||||
zend_mm_get_custom_handlers_ex(heap, _malloc, _free, _realloc, NULL, NULL);
|
||||
#endif
|
||||
}
|
||||
|
||||
ZEND_API void zend_mm_get_custom_handlers_ex(zend_mm_heap *heap,
|
||||
void* (**_malloc)(size_t ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC),
|
||||
void (**_free)(void* ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC),
|
||||
void* (**_realloc)(void*, size_t ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC),
|
||||
size_t (**_gc)(void),
|
||||
void (**_shutdown)(bool, bool))
|
||||
{
|
||||
#if ZEND_MM_CUSTOM
|
||||
zend_mm_heap *_heap = (zend_mm_heap*)heap;
|
||||
@ -3164,15 +3203,29 @@ ZEND_API void zend_mm_get_custom_handlers(zend_mm_heap *heap,
|
||||
*_malloc = _heap->custom_heap._malloc;
|
||||
*_free = _heap->custom_heap._free;
|
||||
*_realloc = _heap->custom_heap._realloc;
|
||||
if (_gc != NULL) {
|
||||
*_gc = _heap->custom_heap._gc;
|
||||
}
|
||||
if (_shutdown != NULL) {
|
||||
*_shutdown = _heap->custom_heap._shutdown;
|
||||
}
|
||||
} else {
|
||||
*_malloc = NULL;
|
||||
*_free = NULL;
|
||||
*_realloc = NULL;
|
||||
if (_gc != NULL) {
|
||||
*_gc = NULL;
|
||||
}
|
||||
if (_shutdown != NULL) {
|
||||
*_shutdown = NULL;
|
||||
}
|
||||
}
|
||||
#else
|
||||
*_malloc = NULL;
|
||||
*_free = NULL;
|
||||
*_realloc = NULL;
|
||||
*_gc = NULL;
|
||||
*_shutdown = NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -274,13 +274,25 @@ ZEND_API size_t zend_mm_gc(zend_mm_heap *heap);
|
||||
|
||||
ZEND_API bool zend_mm_is_custom_heap(zend_mm_heap *new_heap);
|
||||
ZEND_API void zend_mm_set_custom_handlers(zend_mm_heap *heap,
|
||||
void* (*_malloc)(size_t ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC),
|
||||
void (*_free)(void* ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC),
|
||||
void* (*_realloc)(void*, size_t ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC));
|
||||
void* (*_malloc)(size_t ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC),
|
||||
void (*_free)(void* ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC),
|
||||
void* (*_realloc)(void*, size_t ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC));
|
||||
ZEND_API void zend_mm_set_custom_handlers_ex(zend_mm_heap *heap,
|
||||
void* (*_malloc)(size_t ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC),
|
||||
void (*_free)(void* ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC),
|
||||
void* (*_realloc)(void*, size_t ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC),
|
||||
size_t (*_gc)(void),
|
||||
void (*_shutdown)(bool, bool));
|
||||
ZEND_API void zend_mm_get_custom_handlers(zend_mm_heap *heap,
|
||||
void* (**_malloc)(size_t ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC),
|
||||
void (**_free)(void* ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC),
|
||||
void* (**_realloc)(void*, size_t ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC));
|
||||
void* (**_malloc)(size_t ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC),
|
||||
void (**_free)(void* ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC),
|
||||
void* (**_realloc)(void*, size_t ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC));
|
||||
ZEND_API void zend_mm_get_custom_handlers_ex(zend_mm_heap *heap,
|
||||
void* (**_malloc)(size_t ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC),
|
||||
void (**_free)(void* ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC),
|
||||
void* (**_realloc)(void*, size_t ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC),
|
||||
size_t (**_gc)(void),
|
||||
void (**_shutdown)(bool, bool));
|
||||
|
||||
typedef struct _zend_mm_storage zend_mm_storage;
|
||||
|
||||
|
@ -4,5 +4,5 @@ PHP_ARG_ENABLE([zend-test],
|
||||
[Enable zend_test extension])])
|
||||
|
||||
if test "$PHP_ZEND_TEST" != "no"; then
|
||||
PHP_NEW_EXTENSION(zend_test, test.c observer.c fiber.c iterators.c object_handlers.c, $ext_shared,, -DZEND_ENABLE_STATIC_TSRMLS_CACHE=1)
|
||||
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)
|
||||
fi
|
||||
|
@ -3,6 +3,6 @@
|
||||
ARG_ENABLE("zend-test", "enable zend_test extension", "no");
|
||||
|
||||
if (PHP_ZEND_TEST != "no") {
|
||||
EXTENSION("zend_test", "test.c observer.c fiber.c iterators.c object_handlers.c", PHP_ZEND_TEST_SHARED, "/DZEND_ENABLE_STATIC_TSRMLS_CACHE=1");
|
||||
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");
|
||||
ADD_FLAG("CFLAGS_ZEND_TEST", "/D PHP_ZEND_TEST_EXPORTS ");
|
||||
}
|
||||
|
@ -62,6 +62,19 @@ ZEND_BEGIN_MODULE_GLOBALS(zend_test)
|
||||
zend_long quantity_value;
|
||||
zend_string *str_test;
|
||||
zend_string *not_empty_str_test;
|
||||
int zend_mm_custom_handlers_enabled;
|
||||
|
||||
// the previous heap that was found in ZendMM
|
||||
zend_mm_heap* original_heap;
|
||||
// the custom handlers that might have been found in the previous heap
|
||||
void* (*custom_malloc)(size_t ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC);
|
||||
void (*custom_free)(void* ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC);
|
||||
void* (*custom_realloc)(void *, size_t ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC);
|
||||
size_t (*custom_gc)(void);
|
||||
void (*custom_shutdown)(bool, bool);
|
||||
// this is our heap that we install our custom handlers on and inject into
|
||||
// ZendMM
|
||||
zend_mm_heap* observed_heap;
|
||||
ZEND_END_MODULE_GLOBALS(zend_test)
|
||||
|
||||
extern ZEND_DECLARE_MODULE_GLOBALS(zend_test)
|
||||
|
@ -14,6 +14,7 @@
|
||||
+----------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
#include "zend_modules.h"
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
@ -35,6 +36,7 @@
|
||||
#include "test_arginfo.h"
|
||||
#include "zend_call_stack.h"
|
||||
#include "zend_exceptions.h"
|
||||
#include "zend_mm_custom_handlers.h"
|
||||
|
||||
// `php.h` sets `NDEBUG` when not `PHP_DEBUG` which will make `assert()` from
|
||||
// assert.h a no-op. In order to have `assert()` working on NDEBUG builds, we
|
||||
@ -1282,6 +1284,7 @@ PHP_MINIT_FUNCTION(zend_test)
|
||||
}
|
||||
|
||||
zend_test_observer_init(INIT_FUNC_ARGS_PASSTHRU);
|
||||
zend_test_mm_custom_handlers_minit(INIT_FUNC_ARGS_PASSTHRU);
|
||||
zend_test_fiber_init();
|
||||
zend_test_iterators_init();
|
||||
zend_test_object_handlers_init();
|
||||
@ -1310,6 +1313,7 @@ PHP_RINIT_FUNCTION(zend_test)
|
||||
{
|
||||
zend_hash_init(&ZT_G(global_weakmap), 8, NULL, ZVAL_PTR_DTOR, 0);
|
||||
ZT_G(observer_nesting_depth) = 0;
|
||||
zend_test_mm_custom_handlers_rinit();
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
@ -1327,6 +1331,7 @@ PHP_RSHUTDOWN_FUNCTION(zend_test)
|
||||
zend_mm_set_heap(ZT_G(zend_orig_heap));
|
||||
}
|
||||
|
||||
zend_test_mm_custom_handlers_rshutdown();
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
|
12
ext/zend_test/tests/zend_mm_custom_handlers_alloc_01.phpt
Normal file
12
ext/zend_test/tests/zend_mm_custom_handlers_alloc_01.phpt
Normal file
@ -0,0 +1,12 @@
|
||||
--TEST--
|
||||
ZendMM Custom Handlers: garbage collection
|
||||
--EXTENSIONS--
|
||||
zend_test
|
||||
--FILE--
|
||||
<?php
|
||||
ini_set('zend_test.zend_mm_custom_handlers.enabled', 1);
|
||||
$string = str_repeat('String', rand(1,100));
|
||||
ini_set('zend_test.zend_mm_custom_handlers.enabled', 0);
|
||||
?>
|
||||
--EXPECTREGEX--
|
||||
.*Allocated \d+ bytes at.*
|
13
ext/zend_test/tests/zend_mm_custom_handlers_free_01.phpt
Normal file
13
ext/zend_test/tests/zend_mm_custom_handlers_free_01.phpt
Normal file
@ -0,0 +1,13 @@
|
||||
--TEST--
|
||||
ZendMM Custom Handlers: garbage collection
|
||||
--EXTENSIONS--
|
||||
zend_test
|
||||
--FILE--
|
||||
<?php
|
||||
$string = str_repeat('String', rand(1,100));
|
||||
ini_set('zend_test.zend_mm_custom_handlers.enabled', 1);
|
||||
unset($string);
|
||||
ini_set('zend_test.zend_mm_custom_handlers.enabled', 0);
|
||||
?>
|
||||
--EXPECTREGEX--
|
||||
.*Freed memory at.*
|
12
ext/zend_test/tests/zend_mm_custom_handlers_gc_01.phpt
Normal file
12
ext/zend_test/tests/zend_mm_custom_handlers_gc_01.phpt
Normal file
@ -0,0 +1,12 @@
|
||||
--TEST--
|
||||
ZendMM Custom Handlers: garbage collection
|
||||
--EXTENSIONS--
|
||||
zend_test
|
||||
--FILE--
|
||||
<?php
|
||||
ini_set('zend_test.zend_mm_custom_handlers.enabled', 1);
|
||||
gc_mem_caches();
|
||||
ini_set('zend_test.zend_mm_custom_handlers.enabled', 0);
|
||||
?>
|
||||
--EXPECTREGEX--
|
||||
.*ZendMM GC freed \d+ bytes.*
|
180
ext/zend_test/zend_mm_custom_handlers.c
Normal file
180
ext/zend_test/zend_mm_custom_handlers.c
Normal file
@ -0,0 +1,180 @@
|
||||
/*
|
||||
+----------------------------------------------------------------------+
|
||||
| Copyright (c) The PHP Group |
|
||||
+----------------------------------------------------------------------+
|
||||
| This source file is subject to version 3.01 of the PHP license, |
|
||||
| that is bundled with this package in the file LICENSE, and is |
|
||||
| available through the world-wide-web at the following url: |
|
||||
| https://www.php.net/license/3_01.txt |
|
||||
| If you did not receive a copy of the PHP license and are unable to |
|
||||
| obtain it through the world-wide-web, please send a note to |
|
||||
| license@php.net so we can mail you a copy immediately. |
|
||||
+----------------------------------------------------------------------+
|
||||
| Author: Florian Engelhardt <florian@engelhardt.tc> |
|
||||
+----------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
#include "php.h"
|
||||
#include "php_test.h"
|
||||
#include "Zend/zend_alloc.h"
|
||||
#include "zend_portability.h"
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
|
||||
void* observe_malloc(size_t size ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC)
|
||||
{
|
||||
void *ptr = NULL;
|
||||
if (ZT_G(custom_malloc)) {
|
||||
zend_mm_set_heap(ZT_G(original_heap));
|
||||
ptr = ZT_G(custom_malloc)(size ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
|
||||
zend_mm_set_heap(ZT_G(observed_heap));
|
||||
} else {
|
||||
ptr = _zend_mm_alloc(ZT_G(original_heap), size ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
|
||||
}
|
||||
printf("Allocated %zu bytes at %p\n", size, ptr);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
void observe_free(void* ptr ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC)
|
||||
{
|
||||
if (ZT_G(custom_free))
|
||||
{
|
||||
zend_mm_set_heap(ZT_G(original_heap));
|
||||
ZT_G(custom_free)(ptr ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
|
||||
zend_mm_set_heap(ZT_G(observed_heap));
|
||||
} else {
|
||||
_zend_mm_free(ZT_G(original_heap), ptr ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
|
||||
}
|
||||
printf("Freed memory at %p\n", ptr);
|
||||
}
|
||||
|
||||
void* observe_realloc(void* ptr, size_t size ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC)
|
||||
{
|
||||
void * new_ptr;
|
||||
if (ZT_G(custom_realloc))
|
||||
{
|
||||
zend_mm_set_heap(ZT_G(original_heap));
|
||||
new_ptr = ZT_G(custom_realloc)(ptr, size ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
|
||||
zend_mm_set_heap(ZT_G(observed_heap));
|
||||
} else {
|
||||
new_ptr = _zend_mm_realloc(ZT_G(original_heap), ptr, size ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
|
||||
}
|
||||
printf("Realloc of %zu bytes from %p to %p\n", size, ptr, new_ptr);
|
||||
return new_ptr;
|
||||
}
|
||||
|
||||
size_t observe_gc(void)
|
||||
{
|
||||
size_t size = 0;
|
||||
if (ZT_G(custom_gc)) {
|
||||
zend_mm_set_heap(ZT_G(original_heap));
|
||||
size = ZT_G(custom_gc)();
|
||||
zend_mm_set_heap(ZT_G(observed_heap));
|
||||
} else {
|
||||
size = zend_mm_gc(ZT_G(original_heap));
|
||||
}
|
||||
printf("ZendMM GC freed %zu bytes", size);
|
||||
return size;
|
||||
}
|
||||
|
||||
void observe_shutdown(bool full, bool silent)
|
||||
{
|
||||
if (ZT_G(custom_shutdown)) {
|
||||
zend_mm_set_heap(ZT_G(original_heap));
|
||||
ZT_G(custom_shutdown)(full, silent);
|
||||
zend_mm_set_heap(ZT_G(observed_heap));
|
||||
} else {
|
||||
zend_mm_shutdown(ZT_G(original_heap), full, silent);
|
||||
}
|
||||
printf("Shutdown happened: full -> %d, silent -> %d\n", full, silent);
|
||||
}
|
||||
|
||||
void zend_test_mm_custom_handlers_init(void)
|
||||
{
|
||||
if (ZT_G(observed_heap) != NULL) {
|
||||
return;
|
||||
}
|
||||
ZT_G(original_heap) = zend_mm_get_heap();
|
||||
if (zend_mm_is_custom_heap(ZT_G(original_heap))) {
|
||||
zend_mm_get_custom_handlers_ex(
|
||||
ZT_G(original_heap),
|
||||
&ZT_G(custom_malloc),
|
||||
&ZT_G(custom_free),
|
||||
&ZT_G(custom_realloc),
|
||||
&ZT_G(custom_gc),
|
||||
&ZT_G(custom_shutdown)
|
||||
);
|
||||
}
|
||||
printf("Prev handlers at %p, %p, %p, %p, %p\n", ZT_G(custom_malloc), ZT_G(custom_free), ZT_G(custom_realloc), ZT_G(custom_gc), ZT_G(custom_shutdown));
|
||||
ZT_G(observed_heap) = zend_mm_startup();
|
||||
zend_mm_set_custom_handlers_ex(
|
||||
ZT_G(observed_heap),
|
||||
observe_malloc,
|
||||
observe_free,
|
||||
observe_realloc,
|
||||
observe_gc,
|
||||
observe_shutdown
|
||||
);
|
||||
zend_mm_set_heap(ZT_G(observed_heap));
|
||||
printf("Heap at %p installed in ZendMM (orig at %p)\n", ZT_G(observed_heap), ZT_G(original_heap));
|
||||
}
|
||||
|
||||
void zend_test_mm_custom_handlers_shutdown(void)
|
||||
{
|
||||
if (ZT_G(observed_heap) == NULL) {
|
||||
return;
|
||||
}
|
||||
zend_mm_set_heap(ZT_G(original_heap));
|
||||
zend_mm_set_custom_handlers_ex(
|
||||
ZT_G(observed_heap),
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL
|
||||
);
|
||||
zend_mm_shutdown(ZT_G(observed_heap), true, true);
|
||||
ZT_G(observed_heap) = NULL;
|
||||
printf("Prev heap at %p restored in ZendMM\n", ZT_G(original_heap));
|
||||
}
|
||||
|
||||
void zend_test_mm_custom_handlers_rshutdown(void)
|
||||
{
|
||||
zend_test_mm_custom_handlers_shutdown();
|
||||
}
|
||||
|
||||
void zend_test_mm_custom_handlers_rinit(void)
|
||||
{
|
||||
if (ZT_G(zend_mm_custom_handlers_enabled)) {
|
||||
zend_test_mm_custom_handlers_init();
|
||||
}
|
||||
}
|
||||
|
||||
static PHP_INI_MH(OnUpdateZendTestMMCustomHandlersEnabled)
|
||||
{
|
||||
if (new_value == NULL) {
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
int int_value = zend_ini_parse_bool(new_value);
|
||||
|
||||
if (int_value == 1) {
|
||||
zend_test_mm_custom_handlers_init();
|
||||
} else {
|
||||
zend_test_mm_custom_handlers_shutdown();
|
||||
}
|
||||
return OnUpdateBool(entry, new_value, mh_arg1, mh_arg2, mh_arg3, stage);
|
||||
}
|
||||
|
||||
PHP_INI_BEGIN()
|
||||
STD_PHP_INI_BOOLEAN("zend_test.zend_mm_custom_handlers.enabled", "0", PHP_INI_USER, OnUpdateZendTestMMCustomHandlersEnabled, zend_mm_custom_handlers_enabled, zend_zend_test_globals, zend_test_globals)
|
||||
PHP_INI_END()
|
||||
|
||||
void zend_test_mm_custom_handlers_minit(INIT_FUNC_ARGS)
|
||||
{
|
||||
if (type != MODULE_TEMPORARY) {
|
||||
REGISTER_INI_ENTRIES();
|
||||
} else {
|
||||
(void)ini_entries;
|
||||
}
|
||||
}
|
24
ext/zend_test/zend_mm_custom_handlers.h
Normal file
24
ext/zend_test/zend_mm_custom_handlers.h
Normal file
@ -0,0 +1,24 @@
|
||||
/*
|
||||
+----------------------------------------------------------------------+
|
||||
| Copyright (c) The PHP Group |
|
||||
+----------------------------------------------------------------------+
|
||||
| This source file is subject to version 3.01 of the PHP license, |
|
||||
| that is bundled with this package in the file LICENSE, and is |
|
||||
| available through the world-wide-web at the following url: |
|
||||
| https://www.php.net/license/3_01.txt |
|
||||
| If you did not receive a copy of the PHP license and are unable to |
|
||||
| obtain it through the world-wide-web, please send a note to |
|
||||
| license@php.net so we can mail you a copy immediately. |
|
||||
+----------------------------------------------------------------------+
|
||||
| Author: Florian Engelhardt <florian@engelhardt.tc> |
|
||||
+----------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
#ifndef ZEND_TEST_MM_CUSTOM_HANDLERS_H
|
||||
#define ZEND_TEST_MM_CUSTOM_HANDLERS_H
|
||||
|
||||
void zend_test_mm_custom_handlers_minit(INIT_FUNC_ARGS);
|
||||
void zend_test_mm_custom_handlers_rinit(void);
|
||||
void zend_test_mm_custom_handlers_rshutdown(void);
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue
Block a user