Skip to content

Commit 14ece3d

Browse files
make all prev and handlers tls
1 parent 891be06 commit 14ece3d

File tree

1 file changed

+66
-46
lines changed

1 file changed

+66
-46
lines changed

profiling/src/allocation.rs

Lines changed: 66 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -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

5367
impl 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
317327
unsafe 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-
377390
unsafe 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

388401
unsafe 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.
400419
unsafe 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-
409426
unsafe 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-
451465
unsafe 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

462476
unsafe 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

Comments
 (0)