On 10 December 2013 12:25, Dmitry Stogov <dmi...@zend.com> wrote: > What exactly are you fixing with this patch? > fast_add_function() is used only by VM and opcode operands can't alias (it's > guaranteed by compiler). > It's also used by array_sum(), but it also can't create aliases between > results and operands. > > What is the reason to slowdown each integer addition? >
The patch that was applied to fix https://bugs.php.net/bug.php?id=65304 uses calls fast_add_function() like this: fast_add_function(return_value, return_value, &entry_n TSRMLS_CC); so it does create aliases. If that is undesirable, perhaps we should fix array_sum() instead? However, I think the compiler will be smart enough to factor out the op1+op2 operation, so i don't expect any significant slowdown. -- Ard. > Thanks. Dmitry. > > > > On Tue, Dec 10, 2013 at 3:12 PM, Ard Biesheuvel <ardbiesheu...@php.net> > wrote: >> >> Commit: 60d2e70c062e436a6c6cd3c8a17469a083a38b46 >> Author: Ard Biesheuvel <ard.biesheu...@linaro.org> Tue, 10 Dec >> 2013 12:07:46 +0100 >> Parents: 5a87b7ff39bbf427807c46d1e51e2654259ad394 >> Branches: PHP-5.6 master >> >> Link: >> http://git.php.net/?p=php-src.git;a=commitdiff;h=60d2e70c062e436a6c6cd3c8a17469a083a38b46 >> >> Log: >> Zend: fix overflow handling bug in non-x86 fast_add_function() >> >> The 'result' argument of fast_add_function() may alias with either >> of its operands (or both). Take care not to write to 'result' before >> reading op1 and op2. >> >> Changed paths: >> M Zend/zend_operators.h >> >> >> Diff: >> diff --git a/Zend/zend_operators.h b/Zend/zend_operators.h >> index 0152e03..5c6fc86 100644 >> --- a/Zend/zend_operators.h >> +++ b/Zend/zend_operators.h >> @@ -643,13 +643,18 @@ static zend_always_inline int fast_add_function(zval >> *result, zval *op1, zval *o >> "n"(ZVAL_OFFSETOF_TYPE) >> : "rax","cc"); >> #else >> - Z_LVAL_P(result) = Z_LVAL_P(op1) + Z_LVAL_P(op2); >> + /* >> + * 'result' may alias with op1 or op2, so we need >> to >> + * ensure that 'result' is not updated until after >> we >> + * have read the values of op1 and op2. >> + */ >> >> if (UNEXPECTED((Z_LVAL_P(op1) & LONG_SIGN_MASK) == >> (Z_LVAL_P(op2) & LONG_SIGN_MASK) >> - && (Z_LVAL_P(op1) & LONG_SIGN_MASK) != >> (Z_LVAL_P(result) & LONG_SIGN_MASK))) { >> + && (Z_LVAL_P(op1) & LONG_SIGN_MASK) != >> ((Z_LVAL_P(op1) + Z_LVAL_P(op2)) & LONG_SIGN_MASK))) { >> Z_DVAL_P(result) = (double) Z_LVAL_P(op1) >> + (double) Z_LVAL_P(op2); >> Z_TYPE_P(result) = IS_DOUBLE; >> } else { >> + Z_LVAL_P(result) = Z_LVAL_P(op1) + >> Z_LVAL_P(op2); >> Z_TYPE_P(result) = IS_LONG; >> } >> #endif >> >> >> -- >> PHP CVS Mailing List (http://www.php.net/) >> To unsubscribe, visit: http://www.php.net/unsub.php >> > -- PHP CVS Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php