From 3d502541f0d215b2c6a167c494e50958d6cc688a Mon Sep 17 00:00:00 2001 From: Michal Nowacki Date: Wed, 22 Nov 2023 19:18:02 -0500 Subject: [PATCH] reduce # of WordPress plugin/theme name calculation Rather than figuring out the plugin/theme name at runtime, which is slow even with memoisation in hashmap, we can do it only at the point an action or filter is added and store it in the wraprec. --- agent/fw_wordpress.c | 21 ++++++++++++++++++++- agent/php_user_instrument.h | 3 +++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/agent/fw_wordpress.c b/agent/fw_wordpress.c index 1c7034ad8..3e6e2f158 100644 --- a/agent/fw_wordpress.c +++ b/agent/fw_wordpress.c @@ -296,7 +296,9 @@ static char* nr_wordpress_plugin_from_function(zend_function* func TSRMLS_DC) { } NR_PHP_WRAPPER(nr_wordpress_wrap_hook) { +#if ZEND_MODULE_API_NO < ZEND_7_4_X_API_NO zend_function* func = NULL; +#endif char* plugin = NULL; NR_UNUSED_SPECIALFN; @@ -312,8 +314,12 @@ NR_PHP_WRAPPER(nr_wordpress_wrap_hook) { if ((0 == NRINI(wordpress_hooks)) || (NULL == NRPRG(wordpress_tag))) { NR_PHP_WRAPPER_LEAVE; } +#if ZEND_MODULE_API_NO < ZEND_7_4_X_API_NO func = nr_php_execute_function(NR_EXECUTE_ORIG_ARGS TSRMLS_CC); plugin = nr_wordpress_plugin_from_function(func TSRMLS_CC); +#else + plugin = wraprec->wordpress_plugin_theme; +#endif NR_PHP_WRAPPER_CALL; @@ -601,10 +607,23 @@ NR_PHP_WRAPPER(nr_wordpress_add_filter) { } if (true == wrap_hook) { + nruserfn_t* callback_wraprec; zval* callback = nr_php_arg_get(2, NR_EXECUTE_ORIG_ARGS TSRMLS_CC); /* the callback here can be any PHP callable. nr_php_wrap_generic_callable * checks that a valid callable is passed */ - nr_php_wrap_generic_callable(callback, nr_wordpress_wrap_hook); + callback_wraprec = nr_php_wrap_generic_callable(callback, nr_wordpress_wrap_hook); + + // We can cheat here: wraprecs on callables are always transient, so if + // there's a wordpress_plugin_theme set we know it's from this transaction, + // and we don't have any issues around a possible multi-tenant setup. + if (callback_wraprec && NULL == callback_wraprec->wordpress_plugin_theme) { + // Unlike Drupal, we don't free the wordpress_plugin_theme, since we know + // it's transient anyway, and we only set the field if it was previously + // NULL. + zend_function* fn = nr_php_zval_to_function(callback); + callback_wraprec->wordpress_plugin_theme + = nr_wordpress_plugin_from_function(fn); + } nr_php_arg_release(&callback); } } diff --git a/agent/php_user_instrument.h b/agent/php_user_instrument.h index a945fd416..0ba0b2336 100644 --- a/agent/php_user_instrument.h +++ b/agent/php_user_instrument.h @@ -95,6 +95,9 @@ typedef struct _nruserfn_t { nr_string_len_t drupal_module_len; char* drupal_hook; nr_string_len_t drupal_hook_len; +#if ZEND_MODULE_API_NO >= ZEND_7_4_X_API_NO + char* wordpress_plugin_theme; +#endif } nruserfn_t; extern nruserfn_t* nr_wrapped_user_functions; /* a singly linked list */