From: Dmitry Stogov Date: Tue, 25 Aug 2020 16:39:42 +0000 (+0300) Subject: Record information about packed arrays X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=e86b5c872d02bff543f5ab3324282a72d4d8cd28;p=php Record information about packed arrays --- diff --git a/ext/opcache/jit/zend_jit_internal.h b/ext/opcache/jit/zend_jit_internal.h index b40553b03d..975a218e80 100644 --- a/ext/opcache/jit/zend_jit_internal.h +++ b/ext/opcache/jit/zend_jit_internal.h @@ -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) diff --git a/ext/opcache/jit/zend_jit_trace.c b/ext/opcache/jit/zend_jit_trace.c index 9e40661b0c..46d84bfa4e 100644 --- a/ext/opcache/jit/zend_jit_trace.c +++ b/ext/opcache/jit/zend_jit_trace.c @@ -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) { diff --git a/ext/opcache/jit/zend_jit_vm_helpers.c b/ext/opcache/jit/zend_jit_vm_helpers.c index f7704b72a4..dca5f97f04 100644 --- a/ext/opcache/jit/zend_jit_vm_helpers.c +++ b/ext/opcache/jit/zend_jit_vm_helpers.c @@ -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 || diff --git a/ext/opcache/jit/zend_jit_x86.dasc b/ext/opcache/jit/zend_jit_x86.dasc index f761c851bf..6fc18bdd3d 100644 --- a/ext/opcache/jit/zend_jit_x86.dasc +++ b/ext/opcache/jit/zend_jit_x86.dasc @@ -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) &&