Skip to content

Commit

Permalink
Merge pull request #1075 from sjinks/rvo
Browse files Browse the repository at this point in the history
Return Value Optimization
  • Loading branch information
Phalcon committed Aug 13, 2013
2 parents 0134f25 + 886940e commit ec5553a
Show file tree
Hide file tree
Showing 14 changed files with 253 additions and 239 deletions.
16 changes: 8 additions & 8 deletions ext/config.c
Original file line number Diff line number Diff line change
Expand Up @@ -396,20 +396,20 @@ void phalcon_config_construct_internal(zval* this_ptr, zval *array_config TSRMLS
* Internal implementation of non-recursive @c toArray(). Used as an alternative
* to @c get_object_properties().
*/
static void phalcon_config_toarray_internal(zval *return_value, zval *this_ptr TSRMLS_DC)
static void phalcon_config_toarray_internal(zval **return_value_ptr, zval *this_ptr TSRMLS_DC)
{
phalcon_config_object *obj = fetchPhalconConfigObject(this_ptr TSRMLS_CC);

if (likely(obj->obj.ce == phalcon_config_ce)) {
zval *tmp;
array_init_size(return_value, zend_hash_num_elements(obj->props));
zend_hash_copy(Z_ARRVAL_P(return_value), obj->props, (copy_ctor_func_t)zval_add_ref, (void*)&tmp, sizeof(zval*));
array_init_size(*return_value_ptr, zend_hash_num_elements(obj->props));
zend_hash_copy(Z_ARRVAL_PP(return_value_ptr), obj->props, (copy_ctor_func_t)zval_add_ref, (void*)&tmp, sizeof(zval*));
}
else if (phalcon_method_exists_ex(this_ptr, SS("toarray") TSRMLS_CC) == SUCCESS) {
phalcon_call_method_params(return_value, this_ptr, SL("toarray"), zend_inline_hash_func(SS("toarray")) TSRMLS_CC, 0);
phalcon_call_method_params(*return_value_ptr, return_value_ptr, this_ptr, SL("toarray"), zend_inline_hash_func(SS("toarray")) TSRMLS_CC, 0);
}
else {
phalcon_call_func_params(return_value, SL("get_object_vars") TSRMLS_CC, 1, this_ptr);
phalcon_call_func_params(*return_value_ptr, return_value_ptr, SL("get_object_vars") TSRMLS_CC, 1, this_ptr);
}
}

Expand Down Expand Up @@ -568,7 +568,7 @@ PHP_METHOD(Phalcon_Config, merge){

if (Z_TYPE_P(config) == IS_OBJECT) {
ALLOC_INIT_ZVAL(array_config);
phalcon_config_toarray_internal(array_config, config TSRMLS_CC);
phalcon_config_toarray_internal(&array_config, config TSRMLS_CC);
}
else {
array_config = config;
Expand All @@ -591,7 +591,7 @@ PHP_METHOD(Phalcon_Config, merge){
if (active_value) {
if ((Z_TYPE_PP(hd) == IS_OBJECT || Z_TYPE_PP(hd) == IS_ARRAY) && Z_TYPE_P(active_value) == IS_OBJECT) {
if (phalcon_method_exists_ex(active_value, SS("merge") TSRMLS_CC) == SUCCESS) { /* Path AAA in the test */
phalcon_call_method_params(NULL, active_value, SL("merge"), zend_inline_hash_func(SS("merge")) TSRMLS_CC, 1, *hd);
phalcon_call_method_params(NULL, NULL, active_value, SL("merge"), zend_inline_hash_func(SS("merge")) TSRMLS_CC, 1, *hd);
}
else { /* Path AAB in the test */
phalcon_config_write_internal(obj, &key, *hd TSRMLS_CC);
Expand Down Expand Up @@ -648,7 +648,7 @@ PHP_METHOD(Phalcon_Config, toArray){

if (Z_TYPE_PP(value) == IS_OBJECT && phalcon_method_exists_ex(*value, SS("toarray") TSRMLS_CC) == SUCCESS) {
ALLOC_INIT_ZVAL(array_value);
phalcon_call_method_params(array_value, *value, SL("toarray"), zend_inline_hash_func(SS("toarray")) TSRMLS_CC, 0);
phalcon_call_method_params(array_value, &array_value, *value, SL("toarray"), zend_inline_hash_func(SS("toarray")) TSRMLS_CC, 0);
phalcon_array_update_zval(&return_value, &key, &array_value, 0);
}
}
Expand Down
3 changes: 2 additions & 1 deletion ext/dispatcher.c
Original file line number Diff line number Diff line change
Expand Up @@ -445,7 +445,7 @@ static inline int phalcon_dispatcher_fire_event(zval *return_value, zval **mgr,
ALLOC_INIT_ZVAL(event_name);
ZVAL_STRING(event_name, event, 0);

status = phalcon_call_method_params(return_value, *mgr, SL("fire"), zend_inline_hash_func(SS("fire")) TSRMLS_CC, (data ? 3 : 2), event_name, source, data);
status = phalcon_call_method_params(return_value, return_value ? &return_value : NULL, *mgr, SL("fire"), zend_inline_hash_func(SS("fire")) TSRMLS_CC, (data ? 3 : 2), event_name, source, data);

ZVAL_NULL(event_name);
zval_ptr_dtor(&event_name);
Expand Down Expand Up @@ -702,6 +702,7 @@ PHP_METHOD(Phalcon_Dispatcher, dispatch){
* Call beforeNotFoundAction
*/
if (events_manager) {
PHALCON_INIT_NVAR(status);
if (FAILURE == phalcon_dispatcher_fire_event(status, events_manager, "dispatch:beforeNotFoundAction", this_ptr, NULL TSRMLS_CC)) {
RETURN_MM();
}
Expand Down
2 changes: 1 addition & 1 deletion ext/http/request.c
Original file line number Diff line number Diff line change
Expand Up @@ -1272,7 +1272,7 @@ static void phalcon_http_request_getuploadedfiles_helper(zval **return_value, zv
ALLOC_INIT_ZVAL(file);
object_init_ex(file, phalcon_http_request_file_ce);

res = phalcon_call_method_params(NULL, file, SL("__construct"), zend_inline_hash_func(SS("__construct")) TSRMLS_CC, 2, arr, key);
res = phalcon_call_method_params(NULL, NULL, file, SL("__construct"), zend_inline_hash_func(SS("__construct")) TSRMLS_CC, 2, arr, key);

zval_ptr_dtor(&arr);
zval_ptr_dtor(&key);
Expand Down
5 changes: 2 additions & 3 deletions ext/http/request/file.c
Original file line number Diff line number Diff line change
Expand Up @@ -217,14 +217,13 @@ PHP_METHOD(Phalcon_Http_Request_File, getKey){

PHP_METHOD(Phalcon_Http_Request_File, isUploadedFile) {

zval *tmp_name;
zval *tmp_name = NULL;

if (!SG(rfc1867_uploaded_files)) {
RETURN_FALSE;
}

PHALCON_ALLOC_ZVAL(tmp_name);
if (phalcon_call_method_params(tmp_name, getThis(), SL("gettempname"), zend_inline_hash_func(SS("gettempname")) TSRMLS_CC, 0) == SUCCESS) {
if (phalcon_call_method_params(tmp_name, &tmp_name, getThis(), SL("gettempname"), zend_inline_hash_func(SS("gettempname")) TSRMLS_CC, 0) == SUCCESS) {
if (Z_TYPE_P(tmp_name) == IS_STRING && zend_hash_exists(SG(rfc1867_uploaded_files), Z_STRVAL_P(tmp_name), Z_STRLEN_P(tmp_name) + 1)) {
RETVAL_TRUE;
}
Expand Down
2 changes: 1 addition & 1 deletion ext/http/response/cookies.c
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,7 @@ PHP_METHOD(Phalcon_Http_Response_Cookies, set){
PHALCON_INIT_VAR(cookie);
object_init_ex(cookie, phalcon_http_cookie_ce);

PHALCON_CALL_METHOD(NULL, cookie, "__construct", zend_inline_hash_func(SS("__construct")), 7, name, value, expire, path, secure, domain, http_only);
PHALCON_CALL_METHOD(NULL, NULL, cookie, "__construct", zend_inline_hash_func(SS("__construct")), 7, name, value, expire, path, secure, domain, http_only);

/**
* Pass the DI to created cookies
Expand Down
28 changes: 14 additions & 14 deletions ext/image/adapter/gd.c
Original file line number Diff line number Diff line change
Expand Up @@ -292,7 +292,7 @@ PHP_METHOD(Phalcon_Image_Adapter_GD, _resize) {
phalcon_call_method_p2(tmp_image, this_ptr, "_create", pre_width, pre_height);

PHALCON_INIT_NVAR(ret);
PHALCON_CALL_FUNCTION(ret, "imagecopyresized", 10, tmp_image, image, dst, dst, dst, dst, pre_width, pre_height, ori_width, ori_height);
PHALCON_CALL_FUNCTION(ret, &ret, "imagecopyresized", 10, tmp_image, image, dst, dst, dst, dst, pre_width, pre_height, ori_width, ori_height);

if (zend_is_true(ret)) {
phalcon_call_func_p1_noret("imagedestroy", image);
Expand All @@ -304,7 +304,7 @@ PHP_METHOD(Phalcon_Image_Adapter_GD, _resize) {
phalcon_call_method_p2(tmp_image, this_ptr, "_create", width, height);

PHALCON_INIT_NVAR(ret);
PHALCON_CALL_FUNCTION(ret, "imagecopyresampled", 10, tmp_image, image, dst, dst, dst, dst, width, height, pre_width, pre_height);
PHALCON_CALL_FUNCTION(ret, &ret, "imagecopyresampled", 10, tmp_image, image, dst, dst, dst, dst, width, height, pre_width, pre_height);

if (zend_is_true(ret)) {
phalcon_call_func_p1_noret("imagedestroy", image);
Expand Down Expand Up @@ -365,7 +365,7 @@ PHP_METHOD(Phalcon_Image_Adapter_GD, _crop) {
ZVAL_LONG(dst, 0);

PHALCON_INIT_NVAR(ret);
PHALCON_CALL_FUNCTION(ret, "imagecopyresampled", 10, tmp_image, image, dst, dst, offset_x, offset_y, width, height, width, height);
PHALCON_CALL_FUNCTION(ret, &ret, "imagecopyresampled", 10, tmp_image, image, dst, dst, offset_x, offset_y, width, height, width, height);

if (zend_is_true(ret)) {
phalcon_call_func_p1_noret("imagedestroy", image);
Expand Down Expand Up @@ -491,7 +491,7 @@ PHP_METHOD(Phalcon_Image_Adapter_GD, _flip) {
PHALCON_INIT_NVAR(src_x);
ZVAL_LONG(src_x, w - x - 1);

PHALCON_CALL_FUNCTION(NULL, "imagecopy", 8, flipped_image, image, dst_x, dst_y, src_x, src_y, src_width, src_height);
PHALCON_CALL_FUNCTION(NULL, NULL, "imagecopy", 8, flipped_image, image, dst_x, dst_y, src_x, src_y, src_width, src_height);
}
} else {
PHALCON_INIT_NVAR(dst_x);
Expand All @@ -514,7 +514,7 @@ PHP_METHOD(Phalcon_Image_Adapter_GD, _flip) {
PHALCON_INIT_NVAR(src_y);
ZVAL_LONG(src_y, h - y - 1);

PHALCON_CALL_FUNCTION(NULL, "imagecopy", 8, flipped_image, image, dst_x, dst_y, src_x, src_y, src_width, src_height);
PHALCON_CALL_FUNCTION(NULL, NULL, "imagecopy", 8, flipped_image, image, dst_x, dst_y, src_x, src_y, src_width, src_height);
}
}

Expand Down Expand Up @@ -688,7 +688,7 @@ PHP_METHOD(Phalcon_Image_Adapter_GD, _reflection) {
PHALCON_INIT_VAR(dst);
ZVAL_LONG(dst, 0);

PHALCON_CALL_FUNCTION(NULL, "imagecopy", 8, reflection, image, dst, dst, dst, dst, image_width, image_height);
PHALCON_CALL_FUNCTION(NULL, NULL, "imagecopy", 8, reflection, image, dst, dst, dst, dst, image_width, image_height);

PHALCON_INIT_NVAR(tmp);
ZVAL_LONG(tmp, 1);
Expand Down Expand Up @@ -716,10 +716,10 @@ PHP_METHOD(Phalcon_Image_Adapter_GD, _reflection) {
PHALCON_INIT_NVAR(line);
phalcon_call_method_p2(line, this_ptr, "_create", image_width, tmp);

PHALCON_CALL_FUNCTION(NULL, "imagecopy", 8, line, image, dst, dst, dst, src_y, image_width, tmp);
PHALCON_CALL_FUNCTION(NULL, "imagefilter", 6, line, filtertype, dst, dst, dst, dst_opacity);
phalcon_call_func_p8_noret("imagecopy", line, image, dst, dst, dst, src_y, image_width, tmp);
phalcon_call_func_p6_noret("imagefilter", line, filtertype, dst, dst, dst, dst_opacity);

PHALCON_CALL_FUNCTION(NULL, "imagecopy", 8, reflection, line, dst, dst_y, dst, dst, image_width, tmp);
phalcon_call_func_p8_noret("imagecopy", reflection, line, dst, dst_y, dst, dst, image_width, tmp);
}

phalcon_call_func_p1_noret("imagedestroy", image);
Expand Down Expand Up @@ -805,7 +805,7 @@ PHP_METHOD(Phalcon_Image_Adapter_GD, _watermark) {
PHALCON_INIT_NVAR(tmp);
ZVAL_LONG(tmp, 0);

PHALCON_CALL_FUNCTION(NULL, "imagefilledrectangle", 6, overlay, tmp, tmp, width, height, color);
phalcon_call_func_p6_noret("imagefilledrectangle", overlay, tmp, tmp, width, height, color);
}

PHALCON_INIT_NVAR(blendmode);
Expand All @@ -816,7 +816,7 @@ PHP_METHOD(Phalcon_Image_Adapter_GD, _watermark) {
ZVAL_LONG(tmp, 0);

PHALCON_INIT_VAR(ret);
PHALCON_CALL_FUNCTION(ret, "imagecopy", 8, image, overlay, offset_x, offset_y, tmp, tmp, width, height);
phalcon_call_func_p8(ret, "imagecopy", image, overlay, offset_x, offset_y, tmp, tmp, width, height);

if (zend_is_true(ret)) {
ZVAL_BOOL(return_value, 1);
Expand Down Expand Up @@ -888,7 +888,7 @@ PHP_METHOD(Phalcon_Image_Adapter_GD, _mask){
PHALCON_INIT_VAR(temp_image);
phalcon_call_func_p2(temp_image, "imagecreatetruecolor", image_width, image_height);

PHALCON_CALL_FUNCTION(NULL, "imagecopyresampled", 10, temp_image, mask_image, c, c, c, c, image_width, image_height, mask_image_width, mask_image_height);
PHALCON_CALL_FUNCTION(NULL, NULL, "imagecopyresampled", 10, temp_image, mask_image, c, c, c, c, image_width, image_height, mask_image_width, mask_image_height);

phalcon_call_func_p1_noret("imagedestroy", mask_image);
PHALCON_CPY_WRT(mask_image, temp_image);
Expand Down Expand Up @@ -1007,15 +1007,15 @@ PHP_METHOD(Phalcon_Image_Adapter_GD, _background) {
PHALCON_INIT_VAR(tmp);
ZVAL_LONG(tmp, 0);

PHALCON_CALL_FUNCTION(NULL, "imagefilledrectangle", 6, background, tmp, tmp, width, height, color);
phalcon_call_func_p6_noret("imagefilledrectangle", background, tmp, tmp, width, height, color);

PHALCON_INIT_VAR(blendmode);
ZVAL_BOOL(blendmode, 1);

phalcon_call_func_p2_noret("imagealphablending", background, blendmode);

PHALCON_INIT_VAR(ret);
PHALCON_CALL_FUNCTION(ret, "imagecopy", 8, background, image, tmp, tmp, tmp, tmp, width, height);
phalcon_call_func_p8(ret, "imagecopy", background, image, tmp, tmp, tmp, tmp, width, height);

if (zend_is_true(ret)) {
phalcon_call_func_p1_noret("imagedestroy", image);
Expand Down
44 changes: 26 additions & 18 deletions ext/kernel/alternative/fcall.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@
#include "php.h"
#include "php_phalcon.h"

#include "ext/standard/php_smart_str.h"

#include "Zend/zend_API.h"
#include "Zend/zend_exceptions.h"
#include "Zend/zend_execute.h"
Expand Down Expand Up @@ -551,6 +553,7 @@ int phalcon_alt_call_method(zend_fcall_info *fci, zend_class_entry *ce, unsigned

fci_cache = &fci_local;

assert(*fci->retval_ptr_ptr == NULL);
*fci->retval_ptr_ptr = NULL;

/* Initialize execute_data */
Expand Down Expand Up @@ -875,6 +878,7 @@ int phalcon_alt_call_method(zend_fcall_info *fci, zend_class_entry *ce, unsigned
if (executor_globals_ptr->exception) {
phalcon_throw_exception_internal(NULL TSRMLS_CC);
}

return SUCCESS;
}

Expand All @@ -883,15 +887,15 @@ int phalcon_alt_call_method(zend_fcall_info *fci, zend_class_entry *ce, unsigned
/**
* Calls a method caching its function handler
*/
int phalcon_alt_call_user_method(zend_class_entry *ce, zval **object_pp, char *method_name, unsigned int method_len, zval *retval_ptr, zend_uint param_count, zval *params[], unsigned long method_key TSRMLS_DC)
int phalcon_alt_call_user_method(zend_class_entry *ce, zval **object_pp, char *method_name, unsigned int method_len, zval *retval_ptr, zval **retval_ptr_ptr, zend_uint param_count, zval *params[], unsigned long method_key TSRMLS_DC)
{
zend_phalcon_globals *phalcon_globals_ptr = PHALCON_VGLOBAL;
zval ***params_array = NULL;
zval **static_params_array[5];
zend_uint i;
int ex_retval;
zval *local_retval_ptr = NULL;
zend_fcall_info *fci, fci_local;
zend_fcall_info fci;
unsigned long hash_key = 0;

phalcon_globals_ptr->recursive_lock++;
Expand Down Expand Up @@ -929,34 +933,38 @@ int phalcon_alt_call_user_method(zend_class_entry *ce, zval **object_pp, char *m

}

fci = &fci_local;
fci->size = sizeof(fci);
fci->no_separation = 1;
fci->symbol_table = NULL;
fci->function_table = &ce->function_table;
fci->object_ptr = *object_pp;
fci->function_name = NULL;
fci->retval_ptr_ptr = &local_retval_ptr;
fci->param_count = param_count;
if (retval_ptr_ptr && *retval_ptr_ptr) {
zval_ptr_dtor(retval_ptr_ptr);
*retval_ptr_ptr = NULL;
}

fci.size = sizeof(fci);
fci.no_separation = 1;
fci.symbol_table = NULL;
fci.function_table = &ce->function_table;
fci.object_ptr = *object_pp;
fci.function_name = NULL;
fci.retval_ptr_ptr = retval_ptr_ptr ? retval_ptr_ptr : &local_retval_ptr;
fci.param_count = param_count;
if (param_count > 5) {
fci->params = params_array;
fci.params = params_array;
} else{
fci->params = static_params_array;
fci.params = static_params_array;
}

ex_retval = phalcon_alt_call_method(fci, ce, hash_key, method_name, method_len, method_key TSRMLS_CC);
ex_retval = phalcon_alt_call_method(&fci, ce, hash_key, method_name, method_len, method_key TSRMLS_CC);

if (fci->function_name) {
ZVAL_NULL(fci->function_name);
zval_ptr_dtor(&fci->function_name);
if (fci.function_name) {
ZVAL_NULL(fci.function_name);
zval_ptr_dtor(&fci.function_name);
}
}

phalcon_globals_ptr->recursive_lock--;

if (local_retval_ptr) {
COPY_PZVAL_TO_ZVAL(*retval_ptr, local_retval_ptr);
} else {
} else if (!retval_ptr_ptr) {
INIT_ZVAL(*retval_ptr);
}

Expand Down
2 changes: 1 addition & 1 deletion ext/kernel/alternative/fcall.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,5 +26,5 @@
# define PHALCON_VEG (&executor_globals)
#endif

int phalcon_alt_call_user_method(zend_class_entry *ce, zval **object_pp, char *method_name, unsigned int method_len, zval *retval_ptr, zend_uint param_count, zval *params[], unsigned long method_key TSRMLS_DC);
int phalcon_alt_call_user_method(zend_class_entry *ce, zval **object_pp, char *method_name, unsigned int method_len, zval *retval_ptr, zval **retval_ptr_ptr, zend_uint param_count, zval *params[], unsigned long method_key TSRMLS_DC);
int phalcon_alt_call_method(zend_fcall_info *fci, zend_class_entry *ce, unsigned long hash_key, char *method_name, unsigned int method_len, unsigned long method_key TSRMLS_DC);
Loading

0 comments on commit ec5553a

Please sign in to comment.