From: Dmitry Stogov Date: Wed, 11 Mar 2009 12:14:55 +0000 (+0000) Subject: Fixed speed degradation on gcc-4.3 because of less agressive inlining X-Git-Tag: php-5.4.0alpha1~191^2~4168 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=95066c10d26fae0dedffccc6af60087065a6e999;p=php Fixed speed degradation on gcc-4.3 because of less agressive inlining --- diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c index 7789e02163..fecc46ac21 100644 --- a/Zend/zend_execute.c +++ b/Zend/zend_execute.c @@ -176,95 +176,110 @@ ZEND_API zval** zend_get_compiled_variable_value(const zend_execute_data *execut } /* }}} */ -static inline zval *_get_zval_ptr_tmp(const znode *node, const temp_variable *Ts, zend_free_op *should_free TSRMLS_DC) /* {{{ */ +static zend_always_inline zval *_get_zval_ptr_tmp(const znode *node, const temp_variable *Ts, zend_free_op *should_free TSRMLS_DC) /* {{{ */ { return should_free->var = &T(node->u.var).tmp_var; } /* }}} */ -static inline zval *_get_zval_ptr_var(const znode *node, const temp_variable *Ts, zend_free_op *should_free TSRMLS_DC) /* {{{ */ +static inline zval *_get_zval_ptr_var_string_offset(const znode *node, const temp_variable *Ts, zend_free_op *should_free TSRMLS_DC) /* {{{ */ { - if (T(node->u.var).var.ptr) { - PZVAL_UNLOCK(T(node->u.var).var.ptr, should_free); - return T(node->u.var).var.ptr; - } else { - temp_variable *T = &T(node->u.var); - zval *str = T->str_offset.str; - zval *ptr; + temp_variable *T = &T(node->u.var); + zval *str = T->str_offset.str; + zval *ptr; - /* string offset */ - ALLOC_ZVAL(ptr); - T->str_offset.ptr = ptr; - should_free->var = ptr; - - /* T->str_offset.str here is always IS_STRING or IS_UNICODE */ - if (Z_TYPE_P(T->str_offset.str) == IS_STRING) { - if (((int)T->str_offset.offset<0) - || (Z_STRLEN_P(T->str_offset.str) <= T->str_offset.offset)) { - Z_STRVAL_P(ptr) = STR_EMPTY_ALLOC(); - Z_STRLEN_P(ptr) = 0; - } else { - Z_STRVAL_P(ptr) = estrndup( Z_STRVAL_P(str) + T->str_offset.offset, 1); - Z_STRLEN_P(ptr) = 1; - } - Z_TYPE_P(ptr) = IS_STRING; + /* string offset */ + ALLOC_ZVAL(ptr); + T->str_offset.ptr = ptr; + should_free->var = ptr; + + /* T->str_offset.str here is always IS_STRING or IS_UNICODE */ + if (Z_TYPE_P(T->str_offset.str) == IS_STRING) { + if (((int)T->str_offset.offset<0) + || (Z_STRLEN_P(T->str_offset.str) <= T->str_offset.offset)) { + Z_STRVAL_P(ptr) = STR_EMPTY_ALLOC(); + Z_STRLEN_P(ptr) = 0; } else { - if (((int)T->str_offset.offset<0) - || (Z_USTRCPLEN_P(T->str_offset.str) <= T->str_offset.offset)) { - Z_USTRVAL_P(ptr) = USTR_MAKE(""); - Z_USTRLEN_P(ptr) = 0; - } else { - UChar32 c = zend_get_codepoint_at(Z_USTRVAL_P(str), Z_USTRLEN_P(str), T->str_offset.offset); - int32_t i = 0; + Z_STRVAL_P(ptr) = estrndup( Z_STRVAL_P(str) + T->str_offset.offset, 1); + Z_STRLEN_P(ptr) = 1; + } + Z_TYPE_P(ptr) = IS_STRING; + } else { + if (((int)T->str_offset.offset<0) + || (Z_USTRCPLEN_P(T->str_offset.str) <= T->str_offset.offset)) { + Z_USTRVAL_P(ptr) = USTR_MAKE(""); + Z_USTRLEN_P(ptr) = 0; + } else { + UChar32 c = zend_get_codepoint_at(Z_USTRVAL_P(str), Z_USTRLEN_P(str), T->str_offset.offset); + int32_t i = 0; - Z_USTRVAL_P(ptr) = eumalloc(3); /* potentially 2 code units + null */ - U16_APPEND_UNSAFE(Z_USTRVAL_P(ptr), i, c); - Z_USTRVAL_P(ptr)[i] = 0; - Z_USTRLEN_P(ptr) = i; - } - Z_TYPE_P(ptr) = IS_UNICODE; + Z_USTRVAL_P(ptr) = eumalloc(3); /* potentially 2 code units + null */ + U16_APPEND_UNSAFE(Z_USTRVAL_P(ptr), i, c); + Z_USTRVAL_P(ptr)[i] = 0; + Z_USTRLEN_P(ptr) = i; } - PZVAL_UNLOCK_FREE(str); - Z_SET_REFCOUNT_P(ptr, 1); - Z_SET_ISREF_P(ptr); - return ptr; + Z_TYPE_P(ptr) = IS_UNICODE; } + PZVAL_UNLOCK_FREE(str); + Z_SET_REFCOUNT_P(ptr, 1); + Z_SET_ISREF_P(ptr); + return ptr; } /* }}} */ -static inline zval *_get_zval_ptr_cv(const znode *node, const temp_variable *Ts, int type TSRMLS_DC) /* {{{ */ +static zend_always_inline zval *_get_zval_ptr_var(const znode *node, const temp_variable *Ts, zend_free_op *should_free TSRMLS_DC) /* {{{ */ { - zval ***ptr = &CV_OF(node->u.var); + zval *ptr = T(node->u.var).var.ptr; - if (!*ptr) { - zend_compiled_variable *cv = &CV_DEF_OF(node->u.var); - zend_uchar utype = UG(unicode)?IS_UNICODE:IS_STRING; + if (EXPECTED(ptr != NULL)) { + PZVAL_UNLOCK(ptr, should_free); + return ptr; + } else { + return _get_zval_ptr_var_string_offset(node, Ts, should_free TSRMLS_CC); + } +} +/* }}} */ - if (!EG(active_symbol_table) || - zend_u_hash_quick_find(EG(active_symbol_table), utype, cv->name, cv->name_len+1, cv->hash_value, (void **)ptr)==FAILURE) { - switch (type) { - case BP_VAR_R: - case BP_VAR_UNSET: - zend_error(E_NOTICE, "Undefined variable: %v", cv->name); - /* break missing intentionally */ - case BP_VAR_IS: - return &EG(uninitialized_zval); - break; - case BP_VAR_RW: - zend_error(E_NOTICE, "Undefined variable: %v", cv->name); - /* break missing intentionally */ - case BP_VAR_W: - Z_ADDREF(EG(uninitialized_zval)); - if (!EG(active_symbol_table)) { - *ptr = (zval**)EG(current_execute_data)->CVs + (EG(active_op_array)->last_var + node->u.var); - **ptr = &EG(uninitialized_zval); - } else { - zend_u_hash_quick_update(EG(active_symbol_table), utype, cv->name, cv->name_len+1, cv->hash_value, &EG(uninitialized_zval_ptr), sizeof(zval *), (void **)ptr); - } - break; - } +static inline zval **_get_zval_cv_lookup(zval ***ptr, zend_uint var, int type TSRMLS_DC) /* {{{ */ +{ + zend_compiled_variable *cv = &CV_DEF_OF(var); + zend_uchar utype = UG(unicode)?IS_UNICODE:IS_STRING; + + if (!EG(active_symbol_table) || + zend_u_hash_quick_find(EG(active_symbol_table), utype, cv->name, cv->name_len+1, cv->hash_value, (void **)ptr)==FAILURE) { + switch (type) { + case BP_VAR_R: + case BP_VAR_UNSET: + zend_error(E_NOTICE, "Undefined variable: %v", cv->name); + /* break missing intentionally */ + case BP_VAR_IS: + return &EG(uninitialized_zval_ptr); + break; + case BP_VAR_RW: + zend_error(E_NOTICE, "Undefined variable: %v", cv->name); + /* break missing intentionally */ + case BP_VAR_W: + Z_ADDREF(EG(uninitialized_zval)); + if (!EG(active_symbol_table)) { + *ptr = (zval**)EG(current_execute_data)->CVs + (EG(active_op_array)->last_var + var); + **ptr = &EG(uninitialized_zval); + } else { + zend_u_hash_quick_update(EG(active_symbol_table), utype, cv->name, cv->name_len+1, cv->hash_value, &EG(uninitialized_zval_ptr), sizeof(zval *), (void **)ptr); + } + break; } } + return *ptr; +} +/* }}} */ + +static zend_always_inline zval *_get_zval_ptr_cv(const znode *node, const temp_variable *Ts, int type TSRMLS_DC) /* {{{ */ +{ + zval ***ptr = &CV_OF(node->u.var); + + if (UNEXPECTED(*ptr == NULL)) { + return *_get_zval_cv_lookup(ptr, node->u.var, type TSRMLS_CC); + } return **ptr; } /* }}} */ @@ -302,7 +317,7 @@ static inline zval **_get_zval_ptr_ptr_var(const znode *node, const temp_variabl { zval** ptr_ptr = T(node->u.var).var.ptr_ptr; - if (ptr_ptr) { + if (EXPECTED(ptr_ptr != NULL)) { PZVAL_UNLOCK(*ptr_ptr, should_free); } else { /* string offset */ @@ -312,38 +327,12 @@ static inline zval **_get_zval_ptr_ptr_var(const znode *node, const temp_variabl } /* }}} */ -static inline zval **_get_zval_ptr_ptr_cv(const znode *node, const temp_variable *Ts, int type TSRMLS_DC) /* {{{ */ +static zend_always_inline zval **_get_zval_ptr_ptr_cv(const znode *node, const temp_variable *Ts, int type TSRMLS_DC) /* {{{ */ { zval ***ptr = &CV_OF(node->u.var); - if (!*ptr) { - zend_compiled_variable *cv = &CV_DEF_OF(node->u.var); - zend_uchar utype = UG(unicode)?IS_UNICODE:IS_STRING; - - if (!EG(active_symbol_table) || - zend_u_hash_quick_find(EG(active_symbol_table), utype, cv->name, cv->name_len+1, cv->hash_value, (void **)ptr)==FAILURE) { - switch (type) { - case BP_VAR_R: - case BP_VAR_UNSET: - zend_error(E_NOTICE, "Undefined variable: %v", cv->name); - /* break missing intentionally */ - case BP_VAR_IS: - return &EG(uninitialized_zval_ptr); - break; - case BP_VAR_RW: - zend_error(E_NOTICE, "Undefined variable: %v", cv->name); - /* break missing intentionally */ - case BP_VAR_W: - Z_ADDREF(EG(uninitialized_zval)); - if (!EG(active_symbol_table)) { - *ptr = (zval**)EG(current_execute_data)->CVs + (EG(active_op_array)->last_var + node->u.var); - **ptr = &EG(uninitialized_zval); - } else { - zend_u_hash_quick_update(EG(active_symbol_table), utype, cv->name, cv->name_len+1, cv->hash_value, &EG(uninitialized_zval_ptr), sizeof(zval *), (void **)ptr); - } - break; - } - } + if (UNEXPECTED(*ptr == NULL)) { + return _get_zval_cv_lookup(ptr, node->u.var, type TSRMLS_CC); } return *ptr; }