]> granicus.if.org Git - php/commitdiff
Fixed JIT for DEFINED opcode
authorDmitry Stogov <dmitry@zend.com>
Mon, 22 Apr 2019 17:19:34 +0000 (20:19 +0300)
committerDmitry Stogov <dmitry@zend.com>
Mon, 22 Apr 2019 17:19:34 +0000 (20:19 +0300)
ext/opcache/jit/zend_jit_vm_helpers.c
ext/opcache/jit/zend_jit_x86.dasc
ext/opcache/tests/jit/defined_001.phpt [new file with mode: 0644]

index 0ddab1d84eb7439f66762e5e172e452060d05ffd..9681f1f2c443cbc1b684eb6f6053c2ba9e877371 100644 (file)
@@ -238,8 +238,8 @@ static zend_always_inline int _zend_quick_get_constant(
 {
 #ifndef HAVE_GCC_GLOBAL_REGS
        zend_execute_data *execute_data = EG(current_execute_data);
-       const zend_op *opline = EX(opline);
 #endif
+       const zend_op *opline = EX(opline);
        zval *zv;
        zend_constant *c = NULL;
 
@@ -260,6 +260,7 @@ static zend_always_inline int _zend_quick_get_constant(
                        zend_throw_error(NULL, "Undefined constant '%s'", Z_STRVAL_P(RT_CONSTANT(opline, opline->op2)));
                        ZVAL_UNDEF(EX_VAR(opline->result.var));
                }
+               CACHE_PTR(opline->extended_value, ENCODE_SPECIAL_CACHE_NUM(zend_hash_num_elements(EG(zend_constants))));
                return FAILURE;
        }
 
index 9b47d8ffb774616dfb62ac7df9f8de305b0c0916..fc618051f6ebf1f21b79c9592547d3e488e5abaf 100644 (file)
@@ -8237,8 +8237,24 @@ static int zend_jit_defined(dasm_State **Dst, const zend_op *opline, int b, int
        |       mov r0, aword [r0 + opline->extended_value]
        |       test r0, r0
        |       jz >1
+       |       test r0, 0x1
+       |       jnz >4
        |.cold_code
+       |4:
+       |       MEM_OP2_2_ZTS mov, FCARG1a, aword, executor_globals, zend_constants, FCARG1a
+       |       shl     r0, 1
+       |       cmp dword [FCARG1a + offsetof(HashTable, nNumOfElements)], eax
+       if (smart_branch) {
+               if (undefined_label != (uint32_t)-1) {
+                       |       jz =>undefined_label
+               } else {
+                       |       jz >3
+               }
+       } else {
+               |       jz >2
+       }
        |1:
+       |       SAVE_VALID_OPLINE opline
        |       LOAD_ADDR FCARG1a, zv
        |       EXT_CALL zend_jit_check_constant, r0
        |       test r0, r0
@@ -8255,9 +8271,7 @@ static int zend_jit_defined(dasm_State **Dst, const zend_op *opline, int b, int
                }
        } else {
                res_addr = zend_jit_decode_op(op_array, opline->result_type, opline->result, opline, NULL, -1);
-               |       jnz >2
-               |       SET_ZVAL_TYPE_INFO res_addr, IS_TRUE
-               |       jmp >3
+               |       jz >1
                |2:
                |       SET_ZVAL_TYPE_INFO res_addr, IS_FALSE
                |       jmp >3
@@ -8268,6 +8282,7 @@ static int zend_jit_defined(dasm_State **Dst, const zend_op *opline, int b, int
                        |       jmp =>defined_label
                }
        } else {
+               |1:
                |       SET_ZVAL_TYPE_INFO res_addr, IS_TRUE
        }
        |3:
diff --git a/ext/opcache/tests/jit/defined_001.phpt b/ext/opcache/tests/jit/defined_001.phpt
new file mode 100644 (file)
index 0000000..45946db
--- /dev/null
@@ -0,0 +1,38 @@
+--TEST--
+JIT DEFINED: 001
+--INI--
+opcache.enable=1
+opcache.enable_cli=1
+opcache.file_update_protection=0
+opcache.jit_buffer_size=1M
+opcache.jit=1235
+--SKIPIF--
+<?php require_once('../skipif.inc'); ?>
+--FILE--
+<?php
+function foo($i) {
+       $a = defined("X");
+       $b = defined("X");
+       if (defined("X")) {
+               $c = 1;
+       } else {        
+               $c = 0;
+       }
+       if (!defined("X")) {
+               $d = 0;
+       } else {
+               $d = 1;
+       }               
+       if ($a || $b || $c || $d) {
+
+               die("Error on $i-th iteration\n");
+       }               
+
+}
+for ($i = 0; $i < 10000; $i++) {
+       foo($i);
+}
+echo "ok\n";
+?>
+--EXPECT--
+ok