Skip to content

Commit a3503f0

Browse files
committed
Most opcodes that don't consume their OP1 operand, must be terminated with real consumer, and don't have to be checked.
These checks are replaced by ZEND_ASSERT.
1 parent 8cb1ae9 commit a3503f0

File tree

1 file changed

+21
-16
lines changed

1 file changed

+21
-16
lines changed

Zend/zend_opcode.c

Lines changed: 21 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -657,16 +657,19 @@ static zend_bool is_fake_def(zend_op *opline) {
657657
static zend_bool keeps_op1_alive(zend_op *opline) {
658658
/* These opcodes don't consume their OP1 operand,
659659
* it is later freed by something else. */
660-
return opline->opcode == ZEND_CASE
661-
|| opline->opcode == ZEND_SWITCH_LONG
662-
|| opline->opcode == ZEND_SWITCH_STRING
663-
|| opline->opcode == ZEND_FE_FETCH_R
664-
|| opline->opcode == ZEND_FE_FETCH_RW
665-
|| opline->opcode == ZEND_FETCH_LIST_R
666-
|| opline->opcode == ZEND_FETCH_LIST_W
667-
|| opline->opcode == ZEND_VERIFY_RETURN_TYPE
668-
|| opline->opcode == ZEND_BIND_LEXICAL
669-
|| opline->opcode == ZEND_ROPE_ADD;
660+
if (opline->opcode == ZEND_CASE
661+
|| opline->opcode == ZEND_SWITCH_LONG
662+
|| opline->opcode == ZEND_FETCH_LIST_R) {
663+
return 1;
664+
}
665+
ZEND_ASSERT(opline->opcode != ZEND_SWITCH_STRING
666+
&& opline->opcode != ZEND_FE_FETCH_R
667+
&& opline->opcode != ZEND_FE_FETCH_RW
668+
&& opline->opcode != ZEND_FETCH_LIST_W
669+
&& opline->opcode != ZEND_VERIFY_RETURN_TYPE
670+
&& opline->opcode != ZEND_BIND_LEXICAL
671+
&& opline->opcode != ZEND_ROPE_ADD);
672+
return 0;
670673
}
671674

672675
/* Live ranges must be sorted by increasing start opline */
@@ -707,7 +710,7 @@ static void zend_calc_live_ranges(
707710
* because there are multiple defining opcodes (e.g. JMPZ_EX and QM_ASSIGN), in
708711
* which case the last one starts the live range. As such, we can simply ignore
709712
* missing uses here. */
710-
if (last_use[var_num] != (uint32_t) -1) {
713+
if (EXPECTED(last_use[var_num] != (uint32_t) -1)) {
711714
/* Skip trivial live-range */
712715
if (opnum + 1 != last_use[var_num]) {
713716
uint32_t num;
@@ -726,16 +729,18 @@ static void zend_calc_live_ranges(
726729
}
727730
}
728731

729-
if ((opline->op1_type & (IS_TMP_VAR|IS_VAR)) && !keeps_op1_alive(opline)) {
732+
if ((opline->op1_type & (IS_TMP_VAR|IS_VAR))) {
730733
uint32_t var_num = EX_VAR_TO_NUM(opline->op1.var) - var_offset;
731-
if (last_use[var_num] == (uint32_t) -1) {
732-
/* OP_DATA is really part of the previous opcode. */
733-
last_use[var_num] = opnum - (opline->opcode == ZEND_OP_DATA);
734+
if (EXPECTED(last_use[var_num] == (uint32_t) -1)) {
735+
if (EXPECTED(!keeps_op1_alive(opline))) {
736+
/* OP_DATA is really part of the previous opcode. */
737+
last_use[var_num] = opnum - (opline->opcode == ZEND_OP_DATA);
738+
}
734739
}
735740
}
736741
if (opline->op2_type & (IS_TMP_VAR|IS_VAR)) {
737742
uint32_t var_num = EX_VAR_TO_NUM(opline->op2.var) - var_offset;
738-
if (last_use[var_num] == (uint32_t) -1) {
743+
if (EXPECTED(last_use[var_num] == (uint32_t) -1)) {
739744
#if 1
740745
/* OP_DATA uses only op1 operand */
741746
ZEND_ASSERT(opline->opcode != ZEND_OP_DATA);

0 commit comments

Comments
 (0)