]> granicus.if.org Git - php/commitdiff
JIT for array merging
authorDmitry Stogov <dmitry@zend.com>
Mon, 13 Jul 2020 09:04:08 +0000 (12:04 +0300)
committerDmitry Stogov <dmitry@zend.com>
Mon, 13 Jul 2020 09:04:08 +0000 (12:04 +0300)
ext/opcache/jit/zend_jit.c
ext/opcache/jit/zend_jit_disasm_x86.c
ext/opcache/jit/zend_jit_helpers.c
ext/opcache/jit/zend_jit_trace.c
ext/opcache/jit/zend_jit_x86.dasc

index d0c1178d695f21ad8adf090828dfd6dda443869e..e8c82f3886e696f83eaeb8169cf098796dfdce7f 100644 (file)
@@ -2274,6 +2274,14 @@ static int zend_jit(const zend_op_array *op_array, zend_ssa *ssa, const zend_op
                                                if ((op1_info & MAY_BE_UNDEF) || (op2_info & MAY_BE_UNDEF)) {
                                                        break;
                                                }
+                                               if (opline->opcode == ZEND_ADD &&
+                                                   (op1_info & (MAY_BE_ANY|MAY_BE_UNDEF)) == MAY_BE_ARRAY &&
+                                                   (op2_info & (MAY_BE_ANY|MAY_BE_UNDEF)) == MAY_BE_ARRAY) {
+                                                       if (!zend_jit_add_arrays(&dasm_state, opline, op_array, op1_info, op2_info)) {
+                                                               goto jit_failure;
+                                                       }
+                                                       goto done;
+                                               }
                                                if (!(op1_info & (MAY_BE_LONG|MAY_BE_DOUBLE)) ||
                                                    !(op2_info & (MAY_BE_LONG|MAY_BE_DOUBLE))) {
                                                        break;
index 039efa5f8c8288209b867301474612c61d59d63c..47292f675dff8972395cf457ce6ba78dc35e3caa 100644 (file)
@@ -460,6 +460,7 @@ static int zend_jit_disasm_init(void)
        REGISTER_HELPER(zend_jit_check_constant);
        REGISTER_HELPER(zend_jit_array_free);
        REGISTER_HELPER(zend_jit_zval_array_dup);
+       REGISTER_HELPER(zend_jit_add_arrays_helper);
 #undef  REGISTER_HELPER
 
 #ifndef _WIN32
index ad26607fd68ad7500e30a883e161550302796848..681b095a18f0fa91053ce62d5456484ce7c087a4 100644 (file)
@@ -1858,3 +1858,11 @@ static HashTable *ZEND_FASTCALL zend_jit_zval_array_dup(zval *arr)
        ZVAL_ARR(arr, ht);
        return ht;
 }
+
+static zend_array *ZEND_FASTCALL zend_jit_add_arrays_helper(zend_array *op1, zend_array *op2)
+{
+       zend_array *res;
+       res = zend_array_dup(op1);
+       zend_hash_merge(res, op2, zval_add_ref, 0);
+       return res;
+}
index 278b3e61515fd7f66e848bc8088ea8260284fd15..7109c690324021bbf458a843ab7bbe63dad1f01e 100644 (file)
@@ -3077,6 +3077,14 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par
                                                if ((op1_info & MAY_BE_UNDEF) || (op2_info & MAY_BE_UNDEF)) {
                                                        break;
                                                }
+                                               if (opline->opcode == ZEND_ADD &&
+                                                   (op1_info & (MAY_BE_ANY|MAY_BE_UNDEF)) == MAY_BE_ARRAY &&
+                                                   (op2_info & (MAY_BE_ANY|MAY_BE_UNDEF)) == MAY_BE_ARRAY) {
+                                                       if (!zend_jit_add_arrays(&dasm_state, opline, op_array, op1_info, op2_info)) {
+                                                               goto jit_failure;
+                                                       }
+                                                       goto done;
+                                               }
                                                if (!(op1_info & (MAY_BE_LONG|MAY_BE_DOUBLE)) ||
                                                    !(op2_info & (MAY_BE_LONG|MAY_BE_DOUBLE))) {
                                                        break;
index 00a29f5ee50c019ea5253892ea2a3ff394ba6d34..ffc85b1f023e3a252d16e1ddcb6a1b72c32a8d63 100644 (file)
@@ -4357,6 +4357,22 @@ static int zend_jit_math(dasm_State **Dst, const zend_op *opline, const zend_op_
        return 1;
 }
 
+static int zend_jit_add_arrays(dasm_State **Dst, const zend_op *opline, const zend_op_array *op_array, uint32_t op1_info, uint32_t op2_info)
+{
+       zend_jit_addr op1_addr = OP1_ADDR();
+       zend_jit_addr op2_addr = OP2_ADDR();
+       zend_jit_addr res_addr = ZEND_ADDR_MEM_ZVAL(ZREG_FP, opline->result.var);
+
+       |       GET_ZVAL_LVAL ZREG_FCARG1a, op1_addr
+       |       GET_ZVAL_LVAL ZREG_FCARG2a, op2_addr
+       |       EXT_CALL zend_jit_add_arrays_helper, r0
+       |       SET_ZVAL_PTR res_addr, r0
+       |       SET_ZVAL_TYPE_INFO res_addr, IS_ARRAY_EX
+       |       FREE_OP opline->op1_type, opline->op1, op1_info, 0, op_array, opline
+       |       FREE_OP opline->op2_type, opline->op2, op2_info, 0, op_array, opline
+       return 1;
+}
+
 static int zend_jit_long_math_helper(dasm_State    **Dst,
                                      const zend_op  *opline,
                                      zend_uchar      opcode,