]> granicus.if.org Git - php/commitdiff
Record information about packed arrays
authorDmitry Stogov <dmitry@zend.com>
Tue, 25 Aug 2020 16:39:42 +0000 (19:39 +0300)
committerDmitry Stogov <dmitry@zend.com>
Tue, 25 Aug 2020 16:39:42 +0000 (19:39 +0300)
ext/opcache/jit/zend_jit_internal.h
ext/opcache/jit/zend_jit_trace.c
ext/opcache/jit/zend_jit_vm_helpers.c
ext/opcache/jit/zend_jit_x86.dasc

index b40553b03dbde9ba662e517fc3581c83ea28f35a..975a218e8063f9a1ba38dd4291587de99d82c8b1 100644 (file)
@@ -245,6 +245,7 @@ typedef enum _zend_jit_trace_op {
 } zend_jit_trace_op;
 
 #define IS_UNKNOWN 255 /* may be used for zend_jit_trace_rec.op?_type */
+#define IS_TRACE_PACKED    (1<<4)
 #define IS_TRACE_REFERENCE (1<<5)
 #define IS_TRACE_INDIRECT  (1<<6)
 
index 9e40661b0c61777a5164eb9af95c59adc44e091b..46d84bfa4e25d6c62d53bd6aac6101a555445a1a 100644 (file)
@@ -1368,6 +1368,9 @@ static zend_ssa *zend_jit_trace_build_tssa(zend_jit_trace_rec *trace_buffer, uin
                        if (op1_type & (IS_TRACE_REFERENCE|IS_TRACE_INDIRECT)) {
                                op1_type = IS_UNKNOWN;
                        }
+                       if (op1_type != IS_UNKNOWN) {
+                               op1_type &= ~IS_TRACE_PACKED;
+                       }
                        if (op2_type & (IS_TRACE_REFERENCE|IS_TRACE_INDIRECT)) {
                                op2_type = IS_UNKNOWN;
                        }
@@ -3122,6 +3125,9 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par
                        if (op1_type & (IS_TRACE_REFERENCE|IS_TRACE_INDIRECT)) {
                                op1_type = IS_UNKNOWN;
                        }
+                       if (op1_type != IS_UNKNOWN) {
+                               op1_type &= ~IS_TRACE_PACKED;
+                       }
                        if (op2_type & (IS_TRACE_REFERENCE|IS_TRACE_INDIRECT)) {
                                op2_type = IS_UNKNOWN;
                        }
@@ -5134,8 +5140,8 @@ static void zend_jit_dump_trace(zend_jit_trace_rec *trace_buffer, zend_ssa *tssa
                                                fprintf(stderr, " op1(%sobject of class %s)", ref,
                                                        ZSTR_VAL(p->ce->name));
                                        } else {
-                                               const char *type = (op1_type == 0) ? "undef" : zend_get_type_by_const(op1_type & ~(IS_TRACE_REFERENCE|IS_TRACE_INDIRECT));
-                                               fprintf(stderr, " op1(%s%s)", ref, type);
+                                               const char *type = (op1_type == 0) ? "undef" : zend_get_type_by_const(op1_type & ~(IS_TRACE_REFERENCE|IS_TRACE_INDIRECT|IS_TRACE_PACKED));
+                                               fprintf(stderr, " op1(%s%s%s)", ref, (op1_type & IS_TRACE_PACKED) ? "packed " : "", type);
                                        }
                                }
                                if (op2_type != IS_UNKNOWN) {
index f7704b72a40ffd0bb6a8942cf27353e92dadd6ab..dca5f97f04b4217acf1c8ecd67024f4ca99e6027 100644 (file)
@@ -659,10 +659,14 @@ zend_jit_trace_stop ZEND_FASTCALL zend_jit_trace_execute(zend_execute_data *ex,
                                op1_type = Z_TYPE_P(zv);
                                flags |= IS_TRACE_REFERENCE;
                        }
-                       op1_type |= flags;
                        if (Z_TYPE_P(zv) == IS_OBJECT) {
                                ce1 = Z_OBJCE_P(zv);
+                       } else if (Z_TYPE_P(zv) == IS_ARRAY) {
+                               if (HT_IS_PACKED(Z_ARRVAL_P(zv))) {
+                                       flags |= IS_TRACE_PACKED;
+                               }
                        }
+                       op1_type |= flags;
                }
                if (opline->op2_type & (IS_TMP_VAR|IS_VAR|IS_CV)
                 && opline->opcode != ZEND_INSTANCEOF
@@ -684,10 +688,10 @@ zend_jit_trace_stop ZEND_FASTCALL zend_jit_trace_execute(zend_execute_data *ex,
                                op2_type = Z_TYPE_P(zv);
                                flags |= IS_TRACE_REFERENCE;
                        }
-                       op2_type |= flags;
                        if (Z_TYPE_P(zv) == IS_OBJECT) {
                                ce2 = Z_OBJCE_P(zv);
                        }
+                       op2_type |= flags;
                }
                if (opline->opcode == ZEND_ASSIGN_DIM ||
                        opline->opcode == ZEND_ASSIGN_OBJ ||
index f761c851bf6a389655860611a1044bfbb5cb9fcb..6fc18bdd3d3931ab8296599fe0166256a35997be 100644 (file)
@@ -12354,7 +12354,9 @@ static zend_bool zend_jit_fetch_reference(dasm_State **Dst, const zend_op *oplin
        var_addr = ZEND_ADDR_MEM_ZVAL(ZREG_FCARG1a, offsetof(zend_reference, val));
        *var_addr_ptr = var_addr;
 
-       var_type &= ~(IS_TRACE_REFERENCE|IS_TRACE_INDIRECT);
+       if (var_type != IS_UNKNOWN) {
+               var_type &= ~(IS_TRACE_REFERENCE|IS_TRACE_INDIRECT|IS_TRACE_PACKED);
+       }
        if (add_type_guard
         && var_type != IS_UNKNOWN
         && (var_info & (MAY_BE_ANY|MAY_BE_UNDEF)) != (1 << var_type)) {
@@ -12394,7 +12396,9 @@ static zend_bool zend_jit_fetch_indirect_var(dasm_State **Dst, const zend_op *op
        var_addr = ZEND_ADDR_MEM_ZVAL(ZREG_FCARG1a, 0);
        *var_addr_ptr = var_addr;
 
-       var_type &= ~IS_TRACE_INDIRECT;
+       if (var_type != IS_UNKNOWN) {
+               var_type &= ~(IS_TRACE_INDIRECT|IS_TRACE_PACKED);
+       }
        if (!(var_type & IS_TRACE_REFERENCE)
         && var_type != IS_UNKNOWN
         && (var_info & (MAY_BE_ANY|MAY_BE_UNDEF)) != (1 << var_type)) {
@@ -12514,7 +12518,7 @@ static zend_bool zend_jit_opline_supports_reg(const zend_op_array *op_array, zen
                        op2_info = OP2_INFO();
                        if (trace
                         && trace->op1_type != IS_UNKNOWN
-                        && (trace->op1_type & ~(IS_TRACE_REFERENCE|IS_TRACE_INDIRECT)) == IS_ARRAY) {
+                        && (trace->op1_type & ~(IS_TRACE_REFERENCE|IS_TRACE_INDIRECT|IS_TRACE_PACKED)) == IS_ARRAY) {
                                op1_info &= ~((MAY_BE_ANY|MAY_BE_UNDEF) - MAY_BE_ARRAY);
                        }
                        return ((op1_info & (MAY_BE_ANY|MAY_BE_UNDEF)) == MAY_BE_ARRAY) &&