@@ -48,6 +48,20 @@ struct ZendMMState {
4848 prev_custom_mm_realloc : Option < zend:: VmMmCustomReallocFn > ,
4949 /// The engine's previous custom free function, if there is one.
5050 prev_custom_mm_free : Option < zend:: VmMmCustomFreeFn > ,
51+ prepare_zend_heap : unsafe fn ( heap : * mut zend:: _zend_mm_heap ) -> c_int ,
52+ restore_zend_heap : unsafe fn ( heap : * mut zend:: _zend_mm_heap , custom_heap : c_int ) ,
53+ /// Safety: this function pointer is only allowed to point to `allocation_profiling_prev_alloc()`
54+ /// when at the same time the `ZEND_MM_STATE.prev_custom_mm_alloc` is initialised to a valid
55+ /// function pointer, otherwise there will be dragons.
56+ alloc : unsafe fn ( size_t ) -> * mut c_void ,
57+ /// Safety: this function pointer is only allowed to point to `allocation_profiling_prev_realloc()`
58+ /// when at the same time the `ZEND_MM_STATE.prev_custom_mm_realloc` is initialised to a valid
59+ /// function pointer, otherwise there will be dragons.
60+ realloc : unsafe fn ( * mut c_void , size_t ) -> * mut c_void ,
61+ /// Safety: this function pointer is only allowed to point to `allocation_profiling_prev_free()`
62+ /// when at the same time the `ZEND_MM_STATE.prev_custom_mm_free` is initialised to a valid
63+ /// function pointer, otherwise there will be dragons.
64+ free : unsafe fn ( * mut c_void ) ,
5165}
5266
5367impl AllocationProfilingStats {
@@ -99,7 +113,12 @@ thread_local! {
99113 heap: None ,
100114 prev_custom_mm_alloc: None ,
101115 prev_custom_mm_realloc: None ,
102- prev_custom_mm_free: None
116+ prev_custom_mm_free: None ,
117+ prepare_zend_heap: prepare_zend_heap,
118+ restore_zend_heap: restore_zend_heap,
119+ alloc: allocation_profiling_orig_alloc,
120+ realloc: allocation_profiling_orig_realloc,
121+ free: allocation_profiling_orig_free,
103122 }
104123 )
105124 } ;
@@ -168,19 +187,19 @@ pub fn allocation_profiling_rinit() {
168187 & mut ( * zend_mm_state) . prev_custom_mm_free ,
169188 & mut ( * zend_mm_state) . prev_custom_mm_realloc ,
170189 ) ;
171- ALLOCATION_PROFILING_ALLOC = allocation_profiling_prev_alloc;
172- ALLOCATION_PROFILING_FREE = allocation_profiling_prev_free;
173- ALLOCATION_PROFILING_REALLOC = allocation_profiling_prev_realloc;
174- ALLOCATION_PROFILING_PREPARE_ZEND_HEAP = prepare_zend_heap_none;
175- ALLOCATION_PROFILING_RESTORE_ZEND_HEAP = restore_zend_heap_none;
190+ ( * zend_mm_state ) . alloc = allocation_profiling_prev_alloc;
191+ ( * zend_mm_state ) . free = allocation_profiling_prev_free;
192+ ( * zend_mm_state ) . realloc = allocation_profiling_prev_realloc;
193+ ( * zend_mm_state ) . prepare_zend_heap = prepare_zend_heap_none;
194+ ( * zend_mm_state ) . restore_zend_heap = restore_zend_heap_none;
176195 }
177196 } else {
178197 unsafe {
179- ALLOCATION_PROFILING_ALLOC = allocation_profiling_orig_alloc;
180- ALLOCATION_PROFILING_FREE = allocation_profiling_orig_free;
181- ALLOCATION_PROFILING_REALLOC = allocation_profiling_orig_realloc;
182- ALLOCATION_PROFILING_PREPARE_ZEND_HEAP = prepare_zend_heap;
183- ALLOCATION_PROFILING_RESTORE_ZEND_HEAP = restore_zend_heap;
198+ ( * zend_mm_state ) . alloc = allocation_profiling_orig_alloc;
199+ ( * zend_mm_state ) . free = allocation_profiling_orig_free;
200+ ( * zend_mm_state ) . realloc = allocation_profiling_orig_realloc;
201+ ( * zend_mm_state ) . prepare_zend_heap = prepare_zend_heap;
202+ ( * zend_mm_state ) . restore_zend_heap = restore_zend_heap;
184203 }
185204 }
186205
@@ -286,10 +305,6 @@ pub fn allocation_profiling_startup() {
286305 }
287306}
288307
289- static mut ALLOCATION_PROFILING_PREPARE_ZEND_HEAP : unsafe fn (
290- heap : * mut zend:: _zend_mm_heap ,
291- ) -> c_int = prepare_zend_heap;
292-
293308/// Overrides the ZendMM heap's `use_custom_heap` flag with the default `ZEND_MM_CUSTOM_HEAP_NONE`
294309/// (currently a `u32: 0`). This needs to be done, as the `zend_mm_gc()` and `zend_mm_shutdown()`
295310/// functions alter behaviour in case custom handlers are installed.
@@ -308,11 +323,6 @@ fn prepare_zend_heap_none(_heap: *mut zend::_zend_mm_heap) -> c_int {
308323 0
309324}
310325
311- static mut ALLOCATION_PROFILING_RESTORE_ZEND_HEAP : unsafe fn (
312- heap : * mut zend:: _zend_mm_heap ,
313- custom_heap : c_int ,
314- ) = restore_zend_heap;
315-
316326/// Restore the ZendMM heap's `use_custom_heap` flag, see `prepare_zend_heap` for details
317327unsafe fn restore_zend_heap ( heap : * mut zend:: _zend_mm_heap , custom_heap : c_int ) {
318328 std:: ptr:: write ( heap as * mut c_int , custom_heap) ;
@@ -337,9 +347,15 @@ unsafe extern "C" fn alloc_profiling_gc_mem_caches(
337347 if let Some ( func) = GC_MEM_CACHES_HANDLER {
338348 if allocation_profiling {
339349 let heap = zend:: zend_mm_get_heap ( ) ;
340- let custom_heap = ALLOCATION_PROFILING_PREPARE_ZEND_HEAP ( heap) ;
350+ let custom_heap = ZEND_MM_STATE . with ( |cell| {
351+ let zend_mm_state = cell. get ( ) ;
352+ ( ( * zend_mm_state) . prepare_zend_heap ) ( heap)
353+ } ) ;
341354 func ( execute_data, return_value) ;
342- ALLOCATION_PROFILING_RESTORE_ZEND_HEAP ( heap, custom_heap) ;
355+ ZEND_MM_STATE . with ( |cell| {
356+ let zend_mm_state = cell. get ( ) ;
357+ ( ( * zend_mm_state) . restore_zend_heap ) ( heap, custom_heap) ;
358+ } ) ;
343359 } else {
344360 func ( execute_data, return_value) ;
345361 }
@@ -352,7 +368,10 @@ unsafe extern "C" fn alloc_profiling_malloc(len: size_t) -> *mut c_void {
352368 ALLOCATION_PROFILING_COUNT . fetch_add ( 1 , SeqCst ) ;
353369 ALLOCATION_PROFILING_SIZE . fetch_add ( len as u64 , SeqCst ) ;
354370
355- let ptr: * mut c_void = ALLOCATION_PROFILING_ALLOC ( len) ;
371+ let ptr = ZEND_MM_STATE . with ( |cell| {
372+ let zend_mm_state = cell. get ( ) ;
373+ ( ( * zend_mm_state) . alloc ) ( len)
374+ } ) ;
356375
357376 // during startup, minit, rinit, ... current_execute_data is null
358377 // we are only interested in allocations during userland operations
@@ -368,12 +387,6 @@ unsafe extern "C" fn alloc_profiling_malloc(len: size_t) -> *mut c_void {
368387 ptr
369388}
370389
371- /// Safety: this function pointer is only allowed to point to `allocation_profiling_prev_alloc()`
372- /// when at the same time the `ZEND_MM_STATE.prev_custom_mm_alloc` is initialised to a valid
373- /// function pointer, otherwise there will be dragons.
374- static mut ALLOCATION_PROFILING_ALLOC : unsafe fn ( size_t ) -> * mut c_void =
375- allocation_profiling_orig_alloc;
376-
377390unsafe fn allocation_profiling_prev_alloc ( len : size_t ) -> * mut c_void {
378391 ZEND_MM_STATE . with ( |cell| {
379392 let zend_mm_state = cell. get ( ) ;
@@ -387,9 +400,15 @@ unsafe fn allocation_profiling_prev_alloc(len: size_t) -> *mut c_void {
387400
388401unsafe fn allocation_profiling_orig_alloc ( len : size_t ) -> * mut c_void {
389402 let heap = zend:: zend_mm_get_heap ( ) ;
390- let custom_heap = ALLOCATION_PROFILING_PREPARE_ZEND_HEAP ( heap) ;
403+ let custom_heap = ZEND_MM_STATE . with ( |cell| {
404+ let zend_mm_state = cell. get ( ) ;
405+ ( ( * zend_mm_state) . prepare_zend_heap ) ( heap)
406+ } ) ;
391407 let ptr: * mut c_void = zend:: _zend_mm_alloc ( heap, len) ;
392- ALLOCATION_PROFILING_RESTORE_ZEND_HEAP ( heap, custom_heap) ;
408+ ZEND_MM_STATE . with ( |cell| {
409+ let zend_mm_state = cell. get ( ) ;
410+ ( ( * zend_mm_state) . restore_zend_heap ) ( heap, custom_heap) ;
411+ } ) ;
393412 ptr
394413}
395414
@@ -398,14 +417,12 @@ unsafe fn allocation_profiling_orig_alloc(len: size_t) -> *mut c_void {
398417// installed. We can not just point to the original `zend::_zend_mm_free()` as the function
399418// definitions differ.
400419unsafe extern "C" fn alloc_profiling_free ( ptr : * mut c_void ) {
401- ALLOCATION_PROFILING_FREE ( ptr) ;
420+ ZEND_MM_STATE . with ( |cell| {
421+ let zend_mm_state = cell. get ( ) ;
422+ ( ( * zend_mm_state) . free ) ( ptr) ;
423+ } ) ;
402424}
403425
404- /// Safety: this function pointer is only allowed to point to `allocation_profiling_prev_free()`
405- /// when at the same time the `ZEND_MM_STATE.prev_custom_mm_free` is initialised to a valid
406- /// function pointer, otherwise there will be dragons.
407- static mut ALLOCATION_PROFILING_FREE : unsafe fn ( * mut c_void ) = allocation_profiling_orig_free;
408-
409426unsafe fn allocation_profiling_prev_free ( ptr : * mut c_void ) {
410427 ZEND_MM_STATE . with ( |cell| {
411428 let zend_mm_state = cell. get ( ) ;
@@ -426,7 +443,10 @@ unsafe extern "C" fn alloc_profiling_realloc(prev_ptr: *mut c_void, len: size_t)
426443 ALLOCATION_PROFILING_COUNT . fetch_add ( 1 , SeqCst ) ;
427444 ALLOCATION_PROFILING_SIZE . fetch_add ( len as u64 , SeqCst ) ;
428445
429- let ptr: * mut c_void = ALLOCATION_PROFILING_REALLOC ( prev_ptr, len) ;
446+ let ptr = ZEND_MM_STATE . with ( |cell| {
447+ let zend_mm_state = cell. get ( ) ;
448+ ( ( * zend_mm_state) . realloc ) ( prev_ptr, len)
449+ } ) ;
430450
431451 // during startup, minit, rinit, ... current_execute_data is null
432452 // we are only interested in allocations during userland operations
@@ -442,12 +462,6 @@ unsafe extern "C" fn alloc_profiling_realloc(prev_ptr: *mut c_void, len: size_t)
442462 ptr
443463}
444464
445- /// Safety: this function pointer is only allowed to point to `allocation_profiling_prev_realloc()`
446- /// when at the same time the `ZEND_MM_STATE.prev_custom_mm_realloc` is initialised to a valid
447- /// function pointer, otherwise there will be dragons.
448- static mut ALLOCATION_PROFILING_REALLOC : unsafe fn ( * mut c_void , size_t ) -> * mut c_void =
449- allocation_profiling_orig_realloc;
450-
451465unsafe fn allocation_profiling_prev_realloc ( prev_ptr : * mut c_void , len : size_t ) -> * mut c_void {
452466 ZEND_MM_STATE . with ( |cell| {
453467 let zend_mm_state = cell. get ( ) ;
@@ -461,9 +475,15 @@ unsafe fn allocation_profiling_prev_realloc(prev_ptr: *mut c_void, len: size_t)
461475
462476unsafe fn allocation_profiling_orig_realloc ( prev_ptr : * mut c_void , len : size_t ) -> * mut c_void {
463477 let heap = zend:: zend_mm_get_heap ( ) ;
464- let custom_heap = ALLOCATION_PROFILING_PREPARE_ZEND_HEAP ( heap) ;
478+ let custom_heap = ZEND_MM_STATE . with ( |cell| {
479+ let zend_mm_state = cell. get ( ) ;
480+ ( ( * zend_mm_state) . prepare_zend_heap ) ( heap)
481+ } ) ;
465482 let ptr: * mut c_void = zend:: _zend_mm_realloc ( heap, prev_ptr, len) ;
466- ALLOCATION_PROFILING_RESTORE_ZEND_HEAP ( heap, custom_heap) ;
483+ ZEND_MM_STATE . with ( |cell| {
484+ let zend_mm_state = cell. get ( ) ;
485+ ( ( * zend_mm_state) . restore_zend_heap ) ( heap, custom_heap) ;
486+ } ) ;
467487 ptr
468488}
469489
0 commit comments