summaryrefslogtreecommitdiff
path: root/ext/opcache/Optimizer/zend_optimizer.c
diff options
context:
space:
mode:
authorXinchen Hui <laruence@gmail.com>2019-01-08 19:19:44 +0800
committerXinchen Hui <laruence@gmail.com>2019-01-08 19:19:44 +0800
commitdd61845cf82ee0540a86ffb90aae0e0c968a0172 (patch)
tree06b68e09cb1bf5f66c591341e8d4e2b5627b5ab6 /ext/opcache/Optimizer/zend_optimizer.c
parent579c7d0412f81bb8796287f6ed4d2fcf1f08c19d (diff)
parentcd49db9d47fa979c308ef25b43123b08be0a5ab0 (diff)
downloadphp-git-dd61845cf82ee0540a86ffb90aae0e0c968a0172.tar.gz
Merge branch 'PHP-7.3'
* PHP-7.3: Fixed bug #77266 (Assertion failed in dce_live_ranges)
Diffstat (limited to 'ext/opcache/Optimizer/zend_optimizer.c')
-rw-r--r--ext/opcache/Optimizer/zend_optimizer.c40
1 files changed, 39 insertions, 1 deletions
diff --git a/ext/opcache/Optimizer/zend_optimizer.c b/ext/opcache/Optimizer/zend_optimizer.c
index e70696c26b..c2e076e0fc 100644
--- a/ext/opcache/Optimizer/zend_optimizer.c
+++ b/ext/opcache/Optimizer/zend_optimizer.c
@@ -614,6 +614,39 @@ void zend_optimizer_remove_live_range(zend_op_array *op_array, uint32_t var)
}
}
+static uint32_t zend_determine_constructor_call(zend_op_array *op_array, uint32_t start) {
+ int call = 0;
+ while (start++ < op_array->last) {
+ switch (op_array->opcodes[start].opcode) {
+ case ZEND_INIT_FCALL_BY_NAME:
+ case ZEND_INIT_NS_FCALL_BY_NAME:
+ case ZEND_INIT_STATIC_METHOD_CALL:
+ case ZEND_INIT_METHOD_CALL:
+ case ZEND_INIT_FCALL:
+ case ZEND_NEW:
+ case ZEND_INIT_DYNAMIC_CALL:
+ case ZEND_INIT_USER_CALL:
+ call++;
+ break;
+ case ZEND_DO_FCALL:
+ if (call == 0) {
+ return start;
+ }
+ /* break missing intentionally */
+ case ZEND_DO_ICALL:
+ case ZEND_DO_UCALL:
+ case ZEND_DO_FCALL_BY_NAME:
+ call--;
+ break;
+ default:
+ break;
+ }
+ }
+
+ ZEND_ASSERT(0);
+ return -1;
+}
+
void zend_optimizer_remove_live_range_ex(zend_op_array *op_array, uint32_t var, uint32_t start)
{
uint32_t i = 0;
@@ -631,7 +664,12 @@ void zend_optimizer_remove_live_range_ex(zend_op_array *op_array, uint32_t var,
case ZEND_FE_RESET_R:
case ZEND_FE_RESET_RW:
var |= ZEND_LIVE_LOOP;
- /* break missing intentionally */
+ start++;
+ break;
+ case ZEND_NEW:
+ start = zend_determine_constructor_call(op_array, start);
+ start++;
+ break;
default:
start++;
}