From 9dc00e436b52c56b8351de0cd4c0689f3c7eb0f2 Mon Sep 17 00:00:00 2001 From: Vladimir Kolesnikov Date: Sat, 10 Aug 2013 04:12:59 +0300 Subject: [PATCH 1/4] Return value optimization --- ext/kernel/object.c | 21 +++++++++++++++++++-- ext/phalcon.c | 24 ++++++++++++++++++++++++ 2 files changed, 43 insertions(+), 2 deletions(-) diff --git a/ext/kernel/object.c b/ext/kernel/object.c index 44d0de0f740..76df0a4dd05 100644 --- a/ext/kernel/object.c +++ b/ext/kernel/object.c @@ -622,7 +622,15 @@ int phalcon_return_property_quick(zval *return_value, zval *object, char *proper EG(scope) = old_scope; - ZVAL_ZVAL(return_value, *zv, 1, 0); + if (EG(return_value_ptr_ptr)) { + zval_ptr_dtor(EG(return_value_ptr_ptr)); + Z_ADDREF_PP(zv); + *EG(return_value_ptr_ptr) = *zv; + } + else { + ZVAL_ZVAL(return_value, *zv, 1, 0); + } + return SUCCESS; } @@ -656,7 +664,16 @@ int phalcon_return_property_quick(zval *return_value, zval *object, char *proper if (likely(!flag)) { EG(scope) = old_scope; - ZVAL_ZVAL(return_value, *zv, 1, 0); + + if (EG(return_value_ptr_ptr)) { + zval_ptr_dtor(EG(return_value_ptr_ptr)); + Z_ADDREF_PP(zv); + *EG(return_value_ptr_ptr) = *zv; + } + else { + ZVAL_ZVAL(return_value, *zv, 1, 0); + } + return SUCCESS; } diff --git a/ext/phalcon.c b/ext/phalcon.c index d5cfac3979a..392536d0cd2 100644 --- a/ext/phalcon.c +++ b/ext/phalcon.c @@ -353,6 +353,7 @@ zend_class_entry *phalcon_image_adapter_imagick_ce; ZEND_DECLARE_MODULE_GLOBALS(phalcon) +static void (*orig_execute_internal)(zend_execute_data *, int TSRMLS_DC) = NULL; static void (*old_error_cb)(int, const char *, const uint, const char *, va_list) = NULL; static void phalcon_error_cb(int type, const char *error_filename, const uint error_lineno, const char *format, va_list args) @@ -385,6 +386,22 @@ static void phalcon_error_cb(int type, const char *error_filename, const uint er } } +static void phalcon_execute_internal(zend_execute_data *execute_data_ptr, int return_value_used TSRMLS_DC) +{ + zval **original_return_value = EG(return_value_ptr_ptr); +#if PHP_VERSION_ID < 50400 + zval **return_value_ptr = &(*(temp_variable *)((char *) execute_data_ptr->Ts + execute_data_ptr->opline->result.u.var)).var.ptr; +#elif PHP_VERSION_ID < 50500 + zval **return_value_ptr = &(*(temp_variable *)((char *) execute_data_ptr->Ts + execute_data_ptr->opline->result.var)).var.ptr; +#else + zval **return_value_ptr = &EX_TMP_VAR(execute_data_ptr, execute_data_ptr->opline->result.var)->var.ptr; +#endif + + EG(return_value_ptr_ptr) = return_value_ptr; + ((zend_internal_function *) execute_data_ptr->function_state.function)->handler(execute_data_ptr->opline->extended_value, *return_value_ptr, return_value_ptr, execute_data_ptr->object, return_value_used TSRMLS_CC); + EG(return_value_ptr_ptr) = original_return_value; +} + static PHP_MINIT_FUNCTION(phalcon){ if (!spl_ce_Countable) { @@ -724,6 +741,12 @@ static PHP_MINIT_FUNCTION(phalcon){ old_error_cb = zend_error_cb; zend_error_cb = phalcon_error_cb; + + orig_execute_internal = zend_execute_internal; + if (!zend_execute_internal) { + zend_execute_internal = phalcon_execute_internal; + } + return SUCCESS; } @@ -731,6 +754,7 @@ static PHP_MINIT_FUNCTION(phalcon){ static PHP_MSHUTDOWN_FUNCTION(phalcon){ zend_error_cb = old_error_cb; + zend_execute_internal = orig_execute_internal; assert(PHALCON_GLOBAL(function_cache) == NULL); assert(PHALCON_GLOBAL(orm).parser_cache == NULL); From a0427e1404fe78f82ecc87e4c67f6e709812868f Mon Sep 17 00:00:00 2001 From: Vladimir Kolesnikov Date: Sat, 10 Aug 2013 04:30:08 +0300 Subject: [PATCH 2/4] Bug fixes --- ext/kernel/main.h | 4 ++-- ext/kernel/object.c | 18 +++++++++--------- ext/kernel/object.h | 4 ++-- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/ext/kernel/main.h b/ext/kernel/main.h index f7a502adcc1..4029f64559c 100644 --- a/ext/kernel/main.h +++ b/ext/kernel/main.h @@ -193,14 +193,14 @@ extern int phalcon_fetch_parameters(int num_args TSRMLS_DC, int required_args, i * Returns a zval in an object member */ #define RETURN_MEMBER(object, member_name) \ - phalcon_return_property_quick(return_value, object, SL(member_name), zend_inline_hash_func(SS(member_name)) TSRMLS_CC); \ + phalcon_return_property_quick(return_value, return_value_ptr, object, SL(member_name), zend_inline_hash_func(SS(member_name)) TSRMLS_CC); \ return; /** * Returns a zval in an object member (quick) */ #define RETURN_MEMBER_QUICK(object, member_name, key) \ - phalcon_return_property_quick(return_value, object, SL(member_name), key TSRMLS_CC); \ + phalcon_return_property_quick(return_value, return_value_ptr, object, SL(member_name), key TSRMLS_CC); \ return; /** Return without change return_value */ diff --git a/ext/kernel/object.c b/ext/kernel/object.c index 76df0a4dd05..cd1fc488a97 100644 --- a/ext/kernel/object.c +++ b/ext/kernel/object.c @@ -595,7 +595,7 @@ zval** phalcon_fetch_property_this_quick(zval *object, char *property_name, unsi /** * Returns an object's member */ -int phalcon_return_property_quick(zval *return_value, zval *object, char *property_name, unsigned int property_length, unsigned long key TSRMLS_DC) { +int phalcon_return_property_quick(zval *return_value, zval **return_value_ptr, zval *object, char *property_name, unsigned int property_length, unsigned long key TSRMLS_DC) { zval **zv; zend_object *zobj; @@ -622,10 +622,10 @@ int phalcon_return_property_quick(zval *return_value, zval *object, char *proper EG(scope) = old_scope; - if (EG(return_value_ptr_ptr)) { - zval_ptr_dtor(EG(return_value_ptr_ptr)); + if (return_value_ptr) { + zval_ptr_dtor(return_value_ptr); Z_ADDREF_PP(zv); - *EG(return_value_ptr_ptr) = *zv; + *return_value_ptr = *zv; } else { ZVAL_ZVAL(return_value, *zv, 1, 0); @@ -665,10 +665,10 @@ int phalcon_return_property_quick(zval *return_value, zval *object, char *proper if (likely(!flag)) { EG(scope) = old_scope; - if (EG(return_value_ptr_ptr)) { - zval_ptr_dtor(EG(return_value_ptr_ptr)); + if (return_value_ptr) { + zval_ptr_dtor(return_value_ptr); Z_ADDREF_PP(zv); - *EG(return_value_ptr_ptr) = *zv; + *return_value_ptr = *zv; } else { ZVAL_ZVAL(return_value, *zv, 1, 0); @@ -694,9 +694,9 @@ int phalcon_return_property_quick(zval *return_value, zval *object, char *proper /** * Returns an object's member */ -int phalcon_return_property(zval *return_value, zval *object, char *property_name, unsigned int property_length TSRMLS_DC) { +int phalcon_return_property(zval *return_value, zval **return_value_ptr, zval *object, char *property_name, unsigned int property_length TSRMLS_DC) { - return phalcon_return_property_quick(return_value, object, property_name, property_length, zend_inline_hash_func(property_name, property_length + 1) TSRMLS_CC); + return phalcon_return_property_quick(return_value, return_value_ptr, object, property_name, property_length, zend_inline_hash_func(property_name, property_length + 1) TSRMLS_CC); } /** diff --git a/ext/kernel/object.h b/ext/kernel/object.h index e870dded8c5..5a135506fbd 100644 --- a/ext/kernel/object.h +++ b/ext/kernel/object.h @@ -63,8 +63,8 @@ zval** phalcon_fetch_property_this(zval *object, char *property_name, unsigned i zval** phalcon_fetch_property_this_quick(zval *object, char *property_name, unsigned int property_length, unsigned long key, int silent TSRMLS_DC); int phalcon_read_property(zval **result, zval *object, char *property_name, unsigned int property_length, int silent TSRMLS_DC); int phalcon_read_property_zval(zval **result, zval *object, zval *property, int silent TSRMLS_DC); -int phalcon_return_property(zval *return_value, zval *object, char *property_name, unsigned int property_length TSRMLS_DC); -int phalcon_return_property_quick(zval *return_value, zval *object, char *property_name, unsigned int property_length, unsigned long key TSRMLS_DC); +int phalcon_return_property(zval *return_value, zval **return_value_ptr, zval *object, char *property_name, unsigned int property_length TSRMLS_DC); +int phalcon_return_property_quick(zval *return_value, zval **return_value_ptr, zval *object, char *property_name, unsigned int property_length, unsigned long key TSRMLS_DC); /** Updating properties */ extern int phalcon_update_property_this(zval *object, char *property_name, unsigned int property_length, zval *value TSRMLS_DC); From ececa61cbc54c307e2ecce4c5fa0932de4fc3dcc Mon Sep 17 00:00:00 2001 From: Vladimir Kolesnikov Date: Sat, 10 Aug 2013 04:30:39 +0300 Subject: [PATCH 3/4] Optimize --- ext/phalcon.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/ext/phalcon.c b/ext/phalcon.c index 392536d0cd2..be1d28eff05 100644 --- a/ext/phalcon.c +++ b/ext/phalcon.c @@ -388,7 +388,6 @@ static void phalcon_error_cb(int type, const char *error_filename, const uint er static void phalcon_execute_internal(zend_execute_data *execute_data_ptr, int return_value_used TSRMLS_DC) { - zval **original_return_value = EG(return_value_ptr_ptr); #if PHP_VERSION_ID < 50400 zval **return_value_ptr = &(*(temp_variable *)((char *) execute_data_ptr->Ts + execute_data_ptr->opline->result.u.var)).var.ptr; #elif PHP_VERSION_ID < 50500 @@ -397,9 +396,7 @@ static void phalcon_execute_internal(zend_execute_data *execute_data_ptr, int re zval **return_value_ptr = &EX_TMP_VAR(execute_data_ptr, execute_data_ptr->opline->result.var)->var.ptr; #endif - EG(return_value_ptr_ptr) = return_value_ptr; ((zend_internal_function *) execute_data_ptr->function_state.function)->handler(execute_data_ptr->opline->extended_value, *return_value_ptr, return_value_ptr, execute_data_ptr->object, return_value_used TSRMLS_CC); - EG(return_value_ptr_ptr) = original_return_value; } static PHP_MINIT_FUNCTION(phalcon){ From e9589048d6906e51be54f4dbdc615aef1fe097bd Mon Sep 17 00:00:00 2001 From: Vladimir Kolesnikov Date: Sat, 10 Aug 2013 05:00:29 +0300 Subject: [PATCH 4/4] Bug fix for PHP 5.5 --- ext/phalcon.c | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/ext/phalcon.c b/ext/phalcon.c index be1d28eff05..92bdd5e0f5f 100644 --- a/ext/phalcon.c +++ b/ext/phalcon.c @@ -385,20 +385,32 @@ static void phalcon_error_cb(int type, const char *error_filename, const uint er exit(255); } } +#if PHP_VERSION_ID >= 50500 +static void phalcon_execute_internal(zend_execute_data *execute_data_ptr, zend_fcall_info *fci, int return_value_used TSRMLS_DC) +{ + if (fci) { + ((zend_internal_function *) execute_data_ptr->function_state.function)->handler(fci->param_count, *fci->retval_ptr_ptr, fci->retval_ptr_ptr, fci->object_ptr, return_value_used TSRMLS_CC); + } + else { + zval **return_value_ptr = &EX_TMP_VAR(execute_data_ptr, execute_data_ptr->opline->result.var)->var.ptr; + ((zend_internal_function *) execute_data_ptr->function_state.function)->handler(execute_data_ptr->opline->extended_value, *return_value_ptr, return_value_ptr, execute_data_ptr->object, return_value_used TSRMLS_CC); + } +} +#else static void phalcon_execute_internal(zend_execute_data *execute_data_ptr, int return_value_used TSRMLS_DC) { #if PHP_VERSION_ID < 50400 zval **return_value_ptr = &(*(temp_variable *)((char *) execute_data_ptr->Ts + execute_data_ptr->opline->result.u.var)).var.ptr; -#elif PHP_VERSION_ID < 50500 - zval **return_value_ptr = &(*(temp_variable *)((char *) execute_data_ptr->Ts + execute_data_ptr->opline->result.var)).var.ptr; #else - zval **return_value_ptr = &EX_TMP_VAR(execute_data_ptr, execute_data_ptr->opline->result.var)->var.ptr; + zval **return_value_ptr = &(*(temp_variable *)((char *) execute_data_ptr->Ts + execute_data_ptr->opline->result.var)).var.ptr; #endif ((zend_internal_function *) execute_data_ptr->function_state.function)->handler(execute_data_ptr->opline->extended_value, *return_value_ptr, return_value_ptr, execute_data_ptr->object, return_value_used TSRMLS_CC); } +#endif + static PHP_MINIT_FUNCTION(phalcon){ if (!spl_ce_Countable) {