From 473b209f0de37831910db0df5e671781ed384918 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Wed, 24 Aug 2022 08:29:45 +0300 Subject: [PATCH 1/3] Reduce observer overhead when restoring script from opcache --- ext/opcache/zend_accelerator_util_funcs.c | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/ext/opcache/zend_accelerator_util_funcs.c b/ext/opcache/zend_accelerator_util_funcs.c index 8363fe247d80..b73a1b433621 100644 --- a/ext/opcache/zend_accelerator_util_funcs.c +++ b/ext/opcache/zend_accelerator_util_funcs.c @@ -140,14 +140,25 @@ void zend_accel_move_user_classes(HashTable *src, uint32_t count, zend_script *s src->pDestructor = orig_dtor; } +static zend_never_inline void zend_accel_functions_declared_nitify(HashTable *ht) +{ + Bucket *p, *end; + + p = ht->arData; + end = p + ht->nNumUsed; + for (; p != end; p++) { + if (*ZSTR_VAL(p->key)) { // if not rtd key + _zend_observer_function_declared_notify(Z_PTR(p->val), p->key); + } + } +} + static void zend_accel_function_hash_copy(HashTable *target, HashTable *source) { zend_function *function1, *function2; Bucket *p, *end; zval *t; - bool call_observers = zend_observer_function_declared_observed; - zend_hash_extend(target, target->nNumUsed + source->nNumUsed, 0); p = source->arData; end = p + source->nNumUsed; @@ -159,11 +170,13 @@ static void zend_accel_function_hash_copy(HashTable *target, HashTable *source) goto failure; } _zend_hash_append_ptr_ex(target, p->key, Z_PTR(p->val), 1); - if (UNEXPECTED(call_observers) && *ZSTR_VAL(p->key)) { // if not rtd key - _zend_observer_function_declared_notify(Z_PTR(p->val), p->key); - } } target->nInternalPointer = 0; + + if (zend_observer_function_declared_observed) { + zend_accel_functions_declared_nitify(source); + } + return; failure: From a6a5e3a088e5d86ff7e0d4e32a1f68965de41e5d Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Wed, 24 Aug 2022 09:15:17 +0300 Subject: [PATCH 2/3] typo --- ext/opcache/zend_accelerator_util_funcs.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ext/opcache/zend_accelerator_util_funcs.c b/ext/opcache/zend_accelerator_util_funcs.c index b73a1b433621..302cce222839 100644 --- a/ext/opcache/zend_accelerator_util_funcs.c +++ b/ext/opcache/zend_accelerator_util_funcs.c @@ -140,7 +140,7 @@ void zend_accel_move_user_classes(HashTable *src, uint32_t count, zend_script *s src->pDestructor = orig_dtor; } -static zend_never_inline void zend_accel_functions_declared_nitify(HashTable *ht) +static zend_never_inline void zend_accel_functions_declared_notify(HashTable *ht) { Bucket *p, *end; @@ -174,7 +174,7 @@ static void zend_accel_function_hash_copy(HashTable *target, HashTable *source) target->nInternalPointer = 0; if (zend_observer_function_declared_observed) { - zend_accel_functions_declared_nitify(source); + zend_accel_functions_declared_notify(source); } return; From d0ee0b54a7b4160a082305fe80a7a7a000e8e1db Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Thu, 25 Aug 2022 09:38:07 +0300 Subject: [PATCH 3/3] Split loops to keep notifications in case of redeclaration errors --- ext/opcache/zend_accelerator_util_funcs.c | 58 ++++++++++++++--------- 1 file changed, 35 insertions(+), 23 deletions(-) diff --git a/ext/opcache/zend_accelerator_util_funcs.c b/ext/opcache/zend_accelerator_util_funcs.c index 302cce222839..aab83bce4ecf 100644 --- a/ext/opcache/zend_accelerator_util_funcs.c +++ b/ext/opcache/zend_accelerator_util_funcs.c @@ -140,20 +140,7 @@ void zend_accel_move_user_classes(HashTable *src, uint32_t count, zend_script *s src->pDestructor = orig_dtor; } -static zend_never_inline void zend_accel_functions_declared_notify(HashTable *ht) -{ - Bucket *p, *end; - - p = ht->arData; - end = p + ht->nNumUsed; - for (; p != end; p++) { - if (*ZSTR_VAL(p->key)) { // if not rtd key - _zend_observer_function_declared_notify(Z_PTR(p->val), p->key); - } - } -} - -static void zend_accel_function_hash_copy(HashTable *target, HashTable *source) +static zend_always_inline void _zend_accel_function_hash_copy(HashTable *target, HashTable *source, bool call_observers) { zend_function *function1, *function2; Bucket *p, *end; @@ -170,13 +157,12 @@ static void zend_accel_function_hash_copy(HashTable *target, HashTable *source) goto failure; } _zend_hash_append_ptr_ex(target, p->key, Z_PTR(p->val), 1); + if (UNEXPECTED(call_observers) && *ZSTR_VAL(p->key)) { // if not rtd key + _zend_observer_function_declared_notify(Z_PTR(p->val), p->key); + } } target->nInternalPointer = 0; - if (zend_observer_function_declared_observed) { - zend_accel_functions_declared_notify(source); - } - return; failure: @@ -196,13 +182,21 @@ static void zend_accel_function_hash_copy(HashTable *target, HashTable *source) } } -static void zend_accel_class_hash_copy(HashTable *target, HashTable *source) +static zend_always_inline void zend_accel_function_hash_copy(HashTable *target, HashTable *source) +{ + _zend_accel_function_hash_copy(target, source, 0); +} + +static zend_never_inline void zend_accel_function_hash_copy_notify(HashTable *target, HashTable *source) +{ + _zend_accel_function_hash_copy(target, source, 1); +} + +static zend_always_inline void _zend_accel_class_hash_copy(HashTable *target, HashTable *source, bool call_observers) { Bucket *p, *end; zval *t; - bool call_observers = zend_observer_class_linked_observed; - zend_hash_extend(target, target->nNumUsed + source->nNumUsed, 0); p = source->arData; end = p + source->nNumUsed; @@ -251,6 +245,16 @@ static void zend_accel_class_hash_copy(HashTable *target, HashTable *source) target->nInternalPointer = 0; } +static zend_always_inline void zend_accel_class_hash_copy(HashTable *target, HashTable *source) +{ + _zend_accel_class_hash_copy(target, source, 0); +} + +static zend_never_inline void zend_accel_class_hash_copy_notify(HashTable *target, HashTable *source) +{ + _zend_accel_class_hash_copy(target, source, 1); +} + void zend_accel_build_delayed_early_binding_list(zend_persistent_script *persistent_script) { zend_op_array *op_array = &persistent_script->script.main_op_array; @@ -390,11 +394,19 @@ zend_op_array* zend_accel_load_script(zend_persistent_script *persistent_script, } if (zend_hash_num_elements(&persistent_script->script.function_table) > 0) { - zend_accel_function_hash_copy(CG(function_table), &persistent_script->script.function_table); + if (EXPECTED(!zend_observer_function_declared_observed)) { + zend_accel_function_hash_copy(CG(function_table), &persistent_script->script.function_table); + } else { + zend_accel_function_hash_copy_notify(CG(function_table), &persistent_script->script.function_table); + } } if (zend_hash_num_elements(&persistent_script->script.class_table) > 0) { - zend_accel_class_hash_copy(CG(class_table), &persistent_script->script.class_table); + if (EXPECTED(!zend_observer_class_linked_observed)) { + zend_accel_class_hash_copy(CG(class_table), &persistent_script->script.class_table); + } else { + zend_accel_class_hash_copy_notify(CG(class_table), &persistent_script->script.class_table); + } } if (persistent_script->num_early_bindings) {