Skip to content

Commit

Permalink
Merge pull request #1046 from sjinks/rvo
Browse files Browse the repository at this point in the history
Return Value Optimization
  • Loading branch information
Phalcon committed Aug 10, 2013
2 parents be4c68b + e958904 commit c07b881
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 9 deletions.
4 changes: 2 additions & 2 deletions ext/kernel/main.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand Down
27 changes: 22 additions & 5 deletions ext/kernel/object.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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 (return_value_ptr) {
zval_ptr_dtor(return_value_ptr);
Z_ADDREF_PP(zv);
*return_value_ptr = *zv;
}
else {
ZVAL_ZVAL(return_value, *zv, 1, 0);
}

return SUCCESS;
}

Expand Down Expand Up @@ -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 (return_value_ptr) {
zval_ptr_dtor(return_value_ptr);
Z_ADDREF_PP(zv);
*return_value_ptr = *zv;
}
else {
ZVAL_ZVAL(return_value, *zv, 1, 0);
}

return SUCCESS;
}

Expand All @@ -677,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);
}

/**
Expand Down
4 changes: 2 additions & 2 deletions ext/kernel/object.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
33 changes: 33 additions & 0 deletions ext/phalcon.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -384,6 +385,31 @@ 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;
#else
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){

Expand Down Expand Up @@ -724,13 +750,20 @@ 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;
}


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);
Expand Down

0 comments on commit c07b881

Please sign in to comment.