diff options
author | Dmitry Stogov <dmitry@zend.com> | 2021-02-17 11:51:50 +0300 |
---|---|---|
committer | Dmitry Stogov <dmitry@zend.com> | 2021-02-17 11:51:50 +0300 |
commit | 5c78e8739996c9dbedbe024cc1ee9ab0443fa69f (patch) | |
tree | 8158cdce861961a7afef744c0b6295bb86bb03af | |
parent | bbb86ba7e2fe8ae365294d1834c6a392570a9dcd (diff) | |
parent | 7f68a7afe625ffdc485a05d417197bc30cbb1513 (diff) | |
download | php-git-5c78e8739996c9dbedbe024cc1ee9ab0443fa69f.tar.gz |
Merge branch 'PHP-8.0'
* PHP-8.0:
Fixed bug #80745 (JIT produces Assert failure and UNKNOWN:0 var_dumps in code involving bitshifts)
-rw-r--r-- | ext/opcache/jit/zend_jit.c | 36 | ||||
-rw-r--r-- | ext/opcache/jit/zend_jit_trace.c | 33 | ||||
-rw-r--r-- | ext/opcache/tests/jit/bug80745.phpt | 43 |
3 files changed, 100 insertions, 12 deletions
diff --git a/ext/opcache/jit/zend_jit.c b/ext/opcache/jit/zend_jit.c index f5ba9f06b6..097f4f6acc 100644 --- a/ext/opcache/jit/zend_jit.c +++ b/ext/opcache/jit/zend_jit.c @@ -2303,7 +2303,17 @@ static int zend_jit(const zend_op_array *op_array, zend_ssa *ssa, const zend_op break; } if (opline->result_type != IS_UNUSED) { - res_use_info = RES_USE_INFO(); + res_use_info = -1; + + if (opline->result_type == IS_CV) { + zend_jit_addr res_use_addr = RES_USE_REG_ADDR(); + + if (Z_MODE(res_use_addr) != IS_REG + || Z_LOAD(res_use_addr) + || Z_STORE(res_use_addr)) { + res_use_info = RES_USE_INFO(); + } + } res_info = RES_INFO(); res_addr = RES_REG_ADDR(); } else { @@ -2354,7 +2364,17 @@ static int zend_jit(const zend_op_array *op_array, zend_ssa *ssa, const zend_op goto jit_failure; } } else { - res_use_info = RES_USE_INFO(); + res_use_info = -1; + + if (opline->result_type == IS_CV) { + zend_jit_addr res_use_addr = RES_USE_REG_ADDR(); + + if (Z_MODE(res_use_addr) != IS_REG + || Z_LOAD(res_use_addr) + || Z_STORE(res_use_addr)) { + res_use_info = RES_USE_INFO(); + } + } } if (!zend_jit_long_math(&dasm_state, opline, op1_info, OP1_RANGE(), OP1_REG_ADDR(), @@ -2398,7 +2418,17 @@ static int zend_jit(const zend_op_array *op_array, zend_ssa *ssa, const zend_op goto jit_failure; } } else { - res_use_info = RES_USE_INFO(); + res_use_info = -1; + + if (opline->result_type == IS_CV) { + zend_jit_addr res_use_addr = RES_USE_REG_ADDR(); + + if (Z_MODE(res_use_addr) != IS_REG + || Z_LOAD(res_use_addr) + || Z_STORE(res_use_addr)) { + res_use_info = RES_USE_INFO(); + } + } } res_info = RES_INFO(); if (opline->opcode == ZEND_ADD && diff --git a/ext/opcache/jit/zend_jit_trace.c b/ext/opcache/jit/zend_jit_trace.c index 754340eda4..bc7038731a 100644 --- a/ext/opcache/jit/zend_jit_trace.c +++ b/ext/opcache/jit/zend_jit_trace.c @@ -3879,10 +3879,15 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par STACK_MEM_TYPE(stack, EX_VAR_TO_NUM(opline->result.var))) & (MAY_BE_UNDEF|MAY_BE_NULL|MAY_BE_FALSE|MAY_BE_TRUE|MAY_BE_LONG|MAY_BE_DOUBLE); #else + res_use_info = -1; if (opline->result_type == IS_CV) { - res_use_info = RES_USE_INFO(); - } else { - res_use_info = MAY_BE_UNDEF|MAY_BE_NULL|MAY_BE_FALSE|MAY_BE_TRUE|MAY_BE_LONG|MAY_BE_DOUBLE; + zend_jit_addr res_use_addr = RES_USE_REG_ADDR(); + + if (Z_MODE(res_use_addr) != IS_REG + || Z_LOAD(res_use_addr) + || Z_STORE(res_use_addr)) { + res_use_info = RES_USE_INFO(); + } } #endif res_info = RES_INFO(); @@ -3974,10 +3979,15 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par STACK_MEM_TYPE(stack, EX_VAR_TO_NUM(opline->result.var))) & (MAY_BE_UNDEF|MAY_BE_NULL|MAY_BE_FALSE|MAY_BE_TRUE|MAY_BE_LONG|MAY_BE_DOUBLE); #else + res_use_info = -1; if (opline->result_type == IS_CV) { - res_use_info = RES_USE_INFO(); - } else { - res_use_info = MAY_BE_UNDEF|MAY_BE_NULL|MAY_BE_FALSE|MAY_BE_TRUE|MAY_BE_LONG|MAY_BE_DOUBLE; + zend_jit_addr res_use_addr = RES_USE_REG_ADDR(); + + if (Z_MODE(res_use_addr) != IS_REG + || Z_LOAD(res_use_addr) + || Z_STORE(res_use_addr)) { + res_use_info = RES_USE_INFO(); + } } #endif } @@ -4051,10 +4061,15 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par STACK_MEM_TYPE(stack, EX_VAR_TO_NUM(opline->result.var))) & (MAY_BE_UNDEF|MAY_BE_NULL|MAY_BE_FALSE|MAY_BE_TRUE|MAY_BE_LONG|MAY_BE_DOUBLE); #else + res_use_info = -1; if (opline->result_type == IS_CV) { - res_use_info = RES_USE_INFO(); - } else { - res_use_info = MAY_BE_UNDEF|MAY_BE_NULL|MAY_BE_FALSE|MAY_BE_TRUE|MAY_BE_LONG|MAY_BE_DOUBLE; + zend_jit_addr res_use_addr = RES_USE_REG_ADDR(); + + if (Z_MODE(res_use_addr) != IS_REG + || Z_LOAD(res_use_addr) + || Z_STORE(res_use_addr)) { + res_use_info = RES_USE_INFO(); + } } #endif } diff --git a/ext/opcache/tests/jit/bug80745.phpt b/ext/opcache/tests/jit/bug80745.phpt new file mode 100644 index 0000000000..66956f4139 --- /dev/null +++ b/ext/opcache/tests/jit/bug80745.phpt @@ -0,0 +1,43 @@ +--TEST-- +Bug #80745 (JIT produces Assert failure and UNKNOWN:0 var_dumps in code involving bitshifts) +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.file_update_protection=0 +opcache.jit=function +opcache.jit_buffer_size=1M +opcache.protect_memory=1 +--SKIPIF-- +<?php require_once('skipif.inc'); ?> +--FILE-- +<?php + +final class Message +{ + public $qr = false; + + public $opcode = 0; + + public $aa = false; +} + +echo "Starting...\n"; + +function headerToBinary(Message $message) +{ + $flags = 0; + $flags = ($flags << 1) | ($message->qr ? 1 : 0); + $flags = ($flags << 4) | $message->opcode; + var_dump($flags); + $flags = ($flags << 1) | ($message->aa ? 1 : 0); +} + +headerToBinary(new Message()); + +echo "PROBLEM NOT REPRODUCED !\n"; +?> +--EXPECT-- +Starting... +int(0) +PROBLEM NOT REPRODUCED ! + |