Skip to content

Commit

Permalink
cleanup
Browse files Browse the repository at this point in the history
  • Loading branch information
realFlowControl committed Dec 2, 2024
1 parent cf2866c commit e0e3862
Show file tree
Hide file tree
Showing 6 changed files with 110 additions and 21 deletions.
2 changes: 1 addition & 1 deletion profiling/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -358,7 +358,7 @@ fn cfg_php_feature_flags(vernum: u64) {
if vernum >= 80400 {
println!("cargo:rustc-cfg=php_frameless");
println!("cargo:rustc-cfg=php_opcache_restart_hook");
println!("cargo:rustc-cfg=php_new_zendmm_hooks");
println!("cargo:rustc-cfg=php_zend_mm_set_custom_handlers_ex");
}
}

Expand Down
67 changes: 62 additions & 5 deletions profiling/src/allocation/allocation_ge84.rs
Original file line number Diff line number Diff line change
Expand Up @@ -87,12 +87,24 @@ macro_rules! tls_zend_mm_state {
};
}

pub fn alloc_prof_rinit() {
#[allow(dead_code)]
pub fn alloc_prof_minit() {
#[cfg(not(php_zts))]
alloc_prof_ginit();
}

#[allow(dead_code)]
pub fn alloc_prof_mshutdown() {
#[cfg(not(php_zts))]
alloc_prof_gshutdown();
}

pub fn alloc_prof_ginit() {
ZEND_MM_STATE.with(|cell| {
let zend_mm_state = cell.get();

// Only need to create an observed heap once per thread. When we have it, we can just
// install the observed hook via `zend::zend_mm_set_heap()`
// install the observed heap via `zend::zend_mm_set_heap()`
if unsafe { (*zend_mm_state).heap.is_null() } {
// Safety: `zend_mm_get_heap()` always returns a non-null pointer to a valid heap structure
let prev_heap = unsafe { zend::zend_mm_get_heap() };
Expand Down Expand Up @@ -130,7 +142,7 @@ pub fn alloc_prof_rinit() {
}
}

// Create our observed heap and prepare custom handlers
// Create a new (to be observed) heap and prepare custom handlers
let heap = unsafe { zend::zend_mm_startup() };
unsafe { ptr::addr_of_mut!((*zend_mm_state).heap).write(heap) };

Expand All @@ -145,10 +157,55 @@ pub fn alloc_prof_rinit() {
Some(alloc_prof_shutdown),
);
}
debug!("New observed heap created");
}
});
}

// install the observed heap into ZendMM
pub fn alloc_prof_gshutdown() {
ZEND_MM_STATE.with(|cell| {
let zend_mm_state = cell.get();
unsafe {
// remove custom handlers to allow for ZendMM internal shutdown
zend::zend_mm_set_custom_handlers_ex(
(*zend_mm_state).heap,
None,
None,
None,
None,
None,
);

// reset to defaults
ptr::addr_of_mut!((*zend_mm_state).alloc).write(alloc_prof_orig_alloc);
ptr::addr_of_mut!((*zend_mm_state).free).write(alloc_prof_orig_free);
ptr::addr_of_mut!((*zend_mm_state).realloc).write(alloc_prof_orig_realloc);
ptr::addr_of_mut!((*zend_mm_state).gc).write(alloc_prof_orig_gc);
ptr::addr_of_mut!((*zend_mm_state).shutdown).write(alloc_prof_orig_shutdown);
ptr::addr_of_mut!((*zend_mm_state).prev_custom_mm_alloc).write(None);
ptr::addr_of_mut!((*zend_mm_state).prev_custom_mm_free).write(None);
ptr::addr_of_mut!((*zend_mm_state).prev_custom_mm_realloc).write(None);
ptr::addr_of_mut!((*zend_mm_state).prev_custom_mm_gc).write(None);
ptr::addr_of_mut!((*zend_mm_state).prev_custom_mm_shutdown).write(None);

// This shutdown will free the observed heap we created in minit
zend::zend_mm_shutdown((*zend_mm_state).heap, true, true);

ptr::addr_of_mut!((*zend_mm_state).heap).write(ptr::null_mut());
ptr::addr_of_mut!((*zend_mm_state).prev_heap).write(ptr::null_mut());

debug!("Observed heap was freed and `zend_mm_state` reset");
}
});
}

pub fn alloc_prof_rinit() {
ZEND_MM_STATE.with(|cell| {
let zend_mm_state = cell.get();
// Safety: `zend_mm_state.heap` got initialized in `MINIT` and is guaranteed to
// be a non null pointer to a valid `zend::zend_mm_heap` struct
unsafe {
// Install our observed heap into ZendMM
zend::zend_mm_set_heap((*zend_mm_state).heap);
}
});
Expand Down Expand Up @@ -181,7 +238,7 @@ pub fn alloc_prof_rshutdown() {
let mut custom_mm_gc: Option<zend::VmMmCustomGcFn> = None;
let mut custom_mm_shutdown: Option<zend::VmMmCustomShutdownFn> = None;

// Safety: `unwrap()` is safe here, as `heap` is initialized in `RINIT`
// Safety: `unwrap()` is safe here, as `heap` is initialized in `MINIT`
let heap = unsafe { (*zend_mm_state).heap };
unsafe {
zend::zend_mm_get_custom_handlers_ex(
Expand Down
39 changes: 31 additions & 8 deletions profiling/src/allocation/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ use rand_distr::{Distribution, Poisson};
use std::cell::RefCell;
use std::sync::atomic::AtomicU64;

#[cfg(php_new_zendmm_hooks)]
#[cfg(php_zend_mm_set_custom_handlers_ex)]
mod allocation_ge84;
#[cfg(not(php_new_zendmm_hooks))]
#[cfg(not(php_zend_mm_set_custom_handlers_ex))]
pub mod allocation_le83;

/// take a sample every 4096 KiB
Expand Down Expand Up @@ -78,12 +78,35 @@ thread_local! {
}

pub fn alloc_prof_minit() {
#[cfg(not(php_new_zendmm_hooks))]
#[cfg(not(php_zend_mm_set_custom_handlers_ex))]
allocation_le83::alloc_prof_minit();
#[cfg(php_zend_mm_set_custom_handlers_ex)]
allocation_ge84::alloc_prof_minit();
}

#[allow(dead_code)]
pub fn alloc_prof_mshutdown() {
#[cfg(php_zend_mm_set_custom_handlers_ex)]
allocation_ge84::alloc_prof_mshutdown();
}

#[allow(dead_code)]
#[cfg(php_zts)]
pub fn alloc_prof_ginit() {
#[cfg(php_zend_mm_set_custom_handlers_ex)]
allocation_ge84::alloc_prof_ginit();
}

#[allow(dead_code)]
#[cfg(php_zts)]
pub fn alloc_prof_gshutdown() {
#[cfg(php_zend_mm_set_custom_handlers_ex)]
allocation_ge84::alloc_prof_gshutdown();
}

#[allow(dead_code)]
pub fn alloc_prof_startup() {
#[cfg(not(php_new_zendmm_hooks))]
#[cfg(not(php_zend_mm_set_custom_handlers_ex))]
allocation_le83::alloc_prof_startup();
}

Expand All @@ -105,9 +128,9 @@ pub fn alloc_prof_rinit() {
return;
}

#[cfg(not(php_new_zendmm_hooks))]
#[cfg(not(php_zend_mm_set_custom_handlers_ex))]
allocation_le83::alloc_prof_rinit();
#[cfg(php_new_zendmm_hooks)]
#[cfg(php_zend_mm_set_custom_handlers_ex)]
allocation_ge84::alloc_prof_rinit();

trace!("Memory allocation profiling enabled.")
Expand All @@ -124,8 +147,8 @@ pub fn alloc_prof_rshutdown() {
return;
}

#[cfg(not(php_new_zendmm_hooks))]
#[cfg(not(php_zend_mm_set_custom_handlers_ex))]
allocation_le83::alloc_prof_rshutdown();
#[cfg(php_new_zendmm_hooks)]
#[cfg(php_zend_mm_set_custom_handlers_ex)]
allocation_ge84::alloc_prof_rshutdown();
}
4 changes: 2 additions & 2 deletions profiling/src/bindings/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,9 @@ pub type VmMmCustomAllocFn = unsafe extern "C" fn(size_t) -> *mut c_void;
pub type VmMmCustomReallocFn = unsafe extern "C" fn(*mut c_void, size_t) -> *mut c_void;
#[cfg(feature = "allocation_profiling")]
pub type VmMmCustomFreeFn = unsafe extern "C" fn(*mut c_void);
#[cfg(all(feature = "allocation_profiling", php_new_zendmm_hooks))]
#[cfg(all(feature = "allocation_profiling", php_zend_mm_set_custom_handlers_ex))]
pub type VmMmCustomGcFn = unsafe extern "C" fn() -> size_t;
#[cfg(all(feature = "allocation_profiling", php_new_zendmm_hooks))]
#[cfg(all(feature = "allocation_profiling", php_zend_mm_set_custom_handlers_ex))]
pub type VmMmCustomShutdownFn = unsafe extern "C" fn(bool, bool);

// todo: this a lie on some PHP versions; is it a problem even though zend_bool
Expand Down
4 changes: 2 additions & 2 deletions profiling/src/config.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#[cfg(not(php_new_zendmm_hooks))]
#[cfg(not(php_zend_mm_set_custom_handlers_ex))]
use crate::allocation;
use crate::bindings::zai_config_type::*;
use crate::bindings::{
Expand Down Expand Up @@ -102,7 +102,7 @@ impl SystemSettings {
}

// Work around version-specific issues.
#[cfg(not(php_new_zendmm_hooks))]
#[cfg(not(php_zend_mm_set_custom_handlers_ex))]
if allocation::allocation_le83::first_rinit_should_disable_due_to_jit() {
system_settings.profiling_allocation_enabled = false;
}
Expand Down
15 changes: 12 additions & 3 deletions profiling/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -203,12 +203,18 @@ pub extern "C" fn get_module() -> &'static mut zend::ModuleEntry {
unsafe extern "C" fn ginit(_globals_ptr: *mut c_void) {
#[cfg(all(feature = "timeline", php_zts))]
timeline::timeline_ginit();

#[cfg(feature = "allocation_profiling")]
allocation::alloc_prof_ginit();
}

#[cfg(php_zts)]
unsafe extern "C" fn gshutdown(_globals_ptr: *mut c_void) {
#[cfg(all(feature = "timeline", php_zts))]
timeline::timeline_gshutdown();

#[cfg(feature = "allocation_profiling")]
allocation::alloc_prof_gshutdown();
}

/* Important note on the PHP lifecycle:
Expand Down Expand Up @@ -337,15 +343,15 @@ extern "C" fn minit(_type: c_int, module_number: c_int) -> ZendResult {
*/
unsafe { zend::zend_register_extension(&extension, handle) };

#[cfg(feature = "allocation_profiling")]
allocation::alloc_prof_minit();

#[cfg(feature = "timeline")]
timeline::timeline_minit();

#[cfg(feature = "exception_profiling")]
exception::exception_profiling_minit();

#[cfg(feature = "allocation_profiling")]
allocation::alloc_prof_minit();

// There are a few things which need to do something on the first rinit of
// each minit/mshutdown cycle. In Apache, when doing `apachectl graceful`,
// there can be more than one of these cycles per process.
Expand Down Expand Up @@ -851,6 +857,9 @@ extern "C" fn mshutdown(_type: c_int, _module_number: c_int) -> ZendResult {
#[cfg(feature = "exception_profiling")]
exception::exception_profiling_mshutdown();

#[cfg(feature = "allocation_profiling")]
allocation::alloc_prof_mshutdown();

Profiler::stop(Duration::from_secs(1));

ZendResult::Success
Expand Down

0 comments on commit e0e3862

Please sign in to comment.