com php-src: Add assertion in liveliness computation: Zend/zend_opcode.c
| From: | Anatol Belski | Date: | Thu, 09 Jul 2015 15:25:42 +0000 |
| Subject: | com php-src: Add assertion in liveliness computation: Zend/zend_opcode.c | ||
| Groups: | php.cvs | ||
| Request: | Send a blank email to php-cvs+get-87864@lists.php.net to get a copy of this message | ||
Commit: 62062dcd0e3228830c7a6af5c689747151828f11
Author: Nikita Popov <nikic@php.net> Wed, 8 Jul 2015 11:54:38 +0200
Committer: Anatol Belski <ab@php.net> Thu, 9 Jul 2015 17:25:42 +0200
Parents: dfe6fdaa727bd9ac4a9b68c5fe521e0f1991ca46
Branches: PHP-7.0.0
Link: http://git.php.net/?p=php-src.git;a=commitdiff;h=62062dcd0e3228830c7a6af5c689747151828f11
Log:
Add assertion in liveliness computation
Assert that a live-range does not start, while one for the same
variable is already active.
To satisfy this constraint, explicitly exclude writes from JMP_SET
and COALESCE. They were previously also handled correctly, because
their result variable was only killed after the second write to it
after the false branch. This just makes it more explicit.
Changed paths:
M Zend/zend_opcode.c
Diff:
diff --git a/Zend/zend_opcode.c b/Zend/zend_opcode.c
index f8d0404..ae2b4bf 100644
--- a/Zend/zend_opcode.c
+++ b/Zend/zend_opcode.c
@@ -941,9 +941,12 @@ static zend_always_inline uint32_t
*generate_var_liveliness_info_ex(zend_op_arra
&& opline->opcode != ZEND_BOOL
&& opline->opcode != ZEND_JMPZ_EX
&& opline->opcode != ZEND_JMPNZ_EX
- /* these two consecutive ops appear on ternary,
- * the result of true branch is undefined for false branch */
+ /* These opcodes write the result of the true branch of a ternary, short
+ * ternary or coalesce and are immediately followed by the instructions
+ * for the false branch (where this result is not live) */
&& (opline->opcode != ZEND_QM_ASSIGN || (opline + 1)->opcode != ZEND_JMP)
+ && opline->opcode != ZEND_JMP_SET
+ && opline->opcode != ZEND_COALESCE
/* exception for opcache, it might nowhere use the temporary
* (anyway bool, so no need to free) */
&& opline->opcode != ZEND_CASE
@@ -959,14 +962,17 @@ static zend_always_inline uint32_t
*generate_var_liveliness_info_ex(zend_op_arra
&& opline->opcode != ZEND_DECLARE_INHERITED_CLASS
&& opline->opcode != ZEND_DECLARE_INHERITED_CLASS_DELAYED
&& opline->opcode != ZEND_DECLARE_ANON_CLASS
- && opline->opcode != ZEND_DECLARE_ANON_INHERITED_CLASS) {
+ && opline->opcode != ZEND_DECLARE_ANON_INHERITED_CLASS
+ ) {
if (done_pass_two) {
var = EX_VAR_TO_NUM(opline->result.var) - op_array->last_var;
} else {
var = opline->result.var;
}
- /* Objects created via ZEND_NEW are only fully initialized after the DO_FCALL (constructor call)
*/
+ ZEND_ASSERT(Tstart[var] == (unsigned) -1);
if (opline->opcode == ZEND_NEW) {
+ /* Objects created via ZEND_NEW are only fully initialized
+ * after the DO_FCALL (constructor call) */
Tstart[var] = opline->op2.opline_num - 1;
} else {
Tstart[var] = opline - op_array->opcodes;