@@ -273,11 +273,15 @@ struct _zend_mm_heap {
273
273
void * (* _malloc )(size_t );
274
274
void (* _free )(void * );
275
275
void * (* _realloc )(void * , size_t );
276
+ size_t (* _gc )(void );
277
+ void (* _shutdown )(bool full , bool silent );
276
278
} std ;
277
279
struct {
278
280
void * (* _malloc )(size_t ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC );
279
281
void (* _free )(void * ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC );
280
282
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 );
281
285
} debug ;
282
286
} custom_heap ;
283
287
HashTable * tracked_allocs ;
@@ -1968,6 +1972,10 @@ ZEND_API size_t zend_mm_gc(zend_mm_heap *heap)
1968
1972
1969
1973
#if ZEND_MM_CUSTOM
1970
1974
if (heap -> use_custom_heap ) {
1975
+ size_t (* gc )(void ) = heap -> custom_heap .std ._gc ;
1976
+ if (gc ) {
1977
+ return gc ();
1978
+ }
1971
1979
return 0 ;
1972
1980
}
1973
1981
#endif
@@ -2262,10 +2270,10 @@ static void zend_mm_check_leaks(zend_mm_heap *heap)
2262
2270
2263
2271
#if ZEND_MM_CUSTOM
2264
2272
static void * tracked_malloc (size_t size );
2265
- static void tracked_free_all (void );
2273
+ static void tracked_free_all (zend_mm_heap * heap );
2266
2274
#endif
2267
2275
2268
- void zend_mm_shutdown (zend_mm_heap * heap , bool full , bool silent )
2276
+ ZEND_API void zend_mm_shutdown (zend_mm_heap * heap , bool full , bool silent )
2269
2277
{
2270
2278
zend_mm_chunk * p ;
2271
2279
zend_mm_huge_list * list ;
@@ -2274,7 +2282,7 @@ void zend_mm_shutdown(zend_mm_heap *heap, bool full, bool silent)
2274
2282
if (heap -> use_custom_heap ) {
2275
2283
if (heap -> custom_heap .std ._malloc == tracked_malloc ) {
2276
2284
if (silent ) {
2277
- tracked_free_all ();
2285
+ tracked_free_all (heap );
2278
2286
}
2279
2287
zend_hash_clean (heap -> tracked_allocs );
2280
2288
if (full ) {
@@ -2286,13 +2294,20 @@ void zend_mm_shutdown(zend_mm_heap *heap, bool full, bool silent)
2286
2294
heap -> size = 0 ;
2287
2295
}
2288
2296
2297
+ void (* shutdown )(bool , bool ) = heap -> custom_heap .std ._shutdown ;
2298
+
2289
2299
if (full ) {
2290
2300
if (ZEND_DEBUG && heap -> use_custom_heap == ZEND_MM_CUSTOM_HEAP_DEBUG ) {
2291
2301
heap -> custom_heap .debug ._free (heap ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC );
2292
2302
} else {
2293
2303
heap -> custom_heap .std ._free (heap );
2294
2304
}
2295
2305
}
2306
+
2307
+ if (shutdown ) {
2308
+ shutdown (full , silent );
2309
+ }
2310
+
2296
2311
return ;
2297
2312
}
2298
2313
#endif
@@ -2895,8 +2910,8 @@ static void *tracked_realloc(void *ptr, size_t new_size) {
2895
2910
return ptr ;
2896
2911
}
2897
2912
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 ;
2900
2915
zend_ulong h ;
2901
2916
ZEND_HASH_FOREACH_NUM_KEY (tracked_allocs , h ) {
2902
2917
void * ptr = (void * ) (uintptr_t ) (h << ZEND_MM_ALIGNMENT_LOG2 );
@@ -2980,6 +2995,16 @@ ZEND_API zend_mm_heap *zend_mm_get_heap(void)
2980
2995
return AG (mm_heap );
2981
2996
}
2982
2997
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
+
2983
3008
ZEND_API bool zend_mm_is_custom_heap (zend_mm_heap * new_heap )
2984
3009
{
2985
3010
#if ZEND_MM_CUSTOM
@@ -2990,9 +3015,11 @@ ZEND_API bool zend_mm_is_custom_heap(zend_mm_heap *new_heap)
2990
3015
}
2991
3016
2992
3017
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 ))
2996
3023
{
2997
3024
#if ZEND_MM_CUSTOM
2998
3025
zend_mm_heap * _heap = (zend_mm_heap * )heap ;
@@ -3004,14 +3031,18 @@ ZEND_API void zend_mm_set_custom_handlers(zend_mm_heap *heap,
3004
3031
_heap -> custom_heap .std ._malloc = _malloc ;
3005
3032
_heap -> custom_heap .std ._free = _free ;
3006
3033
_heap -> custom_heap .std ._realloc = _realloc ;
3034
+ _heap -> custom_heap .std ._gc = _gc ;
3035
+ _heap -> custom_heap .std ._shutdown = _shutdown ;
3007
3036
}
3008
3037
#endif
3009
3038
}
3010
3039
3011
3040
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 ))
3015
3046
{
3016
3047
#if ZEND_MM_CUSTOM
3017
3048
zend_mm_heap * _heap = (zend_mm_heap * )heap ;
@@ -3020,15 +3051,29 @@ ZEND_API void zend_mm_get_custom_handlers(zend_mm_heap *heap,
3020
3051
* _malloc = _heap -> custom_heap .std ._malloc ;
3021
3052
* _free = _heap -> custom_heap .std ._free ;
3022
3053
* _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
+ }
3023
3060
} else {
3024
3061
* _malloc = NULL ;
3025
3062
* _free = NULL ;
3026
3063
* _realloc = NULL ;
3064
+ if (_gc != NULL ) {
3065
+ * _gc = NULL ;
3066
+ }
3067
+ if (_shutdown != NULL ) {
3068
+ * _shutdown = NULL ;
3069
+ }
3027
3070
}
3028
3071
#else
3029
3072
* _malloc = NULL ;
3030
3073
* _free = NULL ;
3031
3074
* _realloc = NULL ;
3075
+ * _gc = NULL ;
3076
+ * _shutdown = NULL ;
3032
3077
#endif
3033
3078
}
3034
3079
0 commit comments