From: Dmitry Stogov Date: Wed, 6 May 2020 19:27:38 +0000 (+0300) Subject: Initial support for IS_INDIRECT. Avoid type guards for IS_INDIRECT. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=b63eff17ffcc1041fed752a0ea7902759329af63;p=php Initial support for IS_INDIRECT. Avoid type guards for IS_INDIRECT. --- diff --git a/ext/opcache/jit/zend_jit_internal.h b/ext/opcache/jit/zend_jit_internal.h index b5f8428689..7c9e834ad4 100644 --- a/ext/opcache/jit/zend_jit_internal.h +++ b/ext/opcache/jit/zend_jit_internal.h @@ -258,6 +258,7 @@ typedef enum _zend_jit_trace_op { #define IS_UNKNOWN 255 /* may be used for zend_jit_trace_rec.op?_type */ #define IS_TRACE_REFERENCE (1<<5) +#define IS_TRACE_INDIRECT (1<<6) typedef struct _zend_jit_trace_rec { uint8_t op; /* zend_jit_trace_op */ diff --git a/ext/opcache/jit/zend_jit_trace.c b/ext/opcache/jit/zend_jit_trace.c index 996408229f..614f9c0dff 100644 --- a/ext/opcache/jit/zend_jit_trace.c +++ b/ext/opcache/jit/zend_jit_trace.c @@ -1263,13 +1263,13 @@ static zend_ssa *zend_jit_trace_build_tssa(zend_jit_trace_rec *trace_buffer, uin op1_type = p->op1_type; op2_type = p->op2_type; op3_type = p->op3_type; - if (op1_type & IS_TRACE_REFERENCE) { + if (op1_type & (IS_TRACE_REFERENCE|IS_TRACE_INDIRECT)) { op1_type = IS_UNKNOWN; } - if (op2_type & IS_TRACE_REFERENCE) { + if (op2_type & (IS_TRACE_REFERENCE|IS_TRACE_INDIRECT)) { op2_type = IS_UNKNOWN; } - if (op3_type & IS_TRACE_REFERENCE) { + if (op3_type & (IS_TRACE_REFERENCE|IS_TRACE_INDIRECT)) { op3_type = IS_UNKNOWN; } @@ -2666,13 +2666,13 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par uint8_t op3_type = p->op3_type; opline = p->opline; - if (op1_type & IS_TRACE_REFERENCE) { + if (op1_type & (IS_TRACE_REFERENCE|IS_TRACE_INDIRECT)) { op1_type = IS_UNKNOWN; } - if (op2_type & IS_TRACE_REFERENCE) { + if (op2_type & (IS_TRACE_REFERENCE|IS_TRACE_INDIRECT)) { op2_type = IS_UNKNOWN; } - if (op3_type & IS_TRACE_REFERENCE) { + if (op3_type & (IS_TRACE_REFERENCE|IS_TRACE_INDIRECT)) { op3_type = IS_UNKNOWN; } @@ -4339,30 +4339,36 @@ static void zend_jit_dump_trace(zend_jit_trace_rec *trace_buffer, zend_ssa *tssa if (op1_type != IS_UNKNOWN || op2_type != IS_UNKNOWN || op3_type != IS_UNKNOWN) { fprintf(stderr, " ;"); if (op1_type != IS_UNKNOWN) { - const char *ref = (op1_type & IS_TRACE_REFERENCE) ? "&" : ""; + const char *ref = (op1_type & IS_TRACE_INDIRECT) ? + ((op1_type & IS_TRACE_REFERENCE) ? "*&" : "*") : + ((op1_type & IS_TRACE_REFERENCE) ? "&" : ""); if ((p+1)->op == ZEND_JIT_TRACE_OP1_TYPE) { p++; 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); + 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); } } if (op2_type != IS_UNKNOWN) { - const char *ref = (op2_type & IS_TRACE_REFERENCE) ? "&" : ""; + const char *ref = (op2_type & IS_TRACE_INDIRECT) ? + ((op2_type & IS_TRACE_REFERENCE) ? "*&" : "*") : + ((op2_type & IS_TRACE_REFERENCE) ? "&" : ""); if ((p+1)->op == ZEND_JIT_TRACE_OP2_TYPE) { p++; fprintf(stderr, " op2(%sobject of class %s)", ref, ZSTR_VAL(p->ce->name)); } else { - const char *type = (op2_type == 0) ? "undef" : zend_get_type_by_const(op2_type & ~IS_TRACE_REFERENCE); + const char *type = (op2_type == 0) ? "undef" : zend_get_type_by_const(op2_type & ~(IS_TRACE_REFERENCE|IS_TRACE_INDIRECT)); fprintf(stderr, " op2(%s%s)", ref, type); } } if (op3_type != IS_UNKNOWN) { - const char *ref = (op3_type & IS_TRACE_REFERENCE) ? "&" : ""; - const char *type = (op3_type == 0) ? "undef" : zend_get_type_by_const(op3_type & ~IS_TRACE_REFERENCE); + const char *ref = (op3_type & IS_TRACE_INDIRECT) ? + ((op3_type & IS_TRACE_REFERENCE) ? "*&" : "*") : + ((op3_type & IS_TRACE_REFERENCE) ? "&" : ""); + const char *type = (op3_type == 0) ? "undef" : zend_get_type_by_const(op3_type & ~(IS_TRACE_REFERENCE|IS_TRACE_INDIRECT)); fprintf(stderr, " op3(%s%s)", ref, type); } } diff --git a/ext/opcache/jit/zend_jit_vm_helpers.c b/ext/opcache/jit/zend_jit_vm_helpers.c index f8559378c6..2cfb79dbb6 100644 --- a/ext/opcache/jit/zend_jit_vm_helpers.c +++ b/ext/opcache/jit/zend_jit_vm_helpers.c @@ -603,31 +603,41 @@ zend_jit_trace_stop ZEND_FASTCALL zend_jit_trace_execute(zend_execute_data *ex, && (opline->opcode != ZEND_ROPE_ADD && opline->opcode != ZEND_ROPE_END)) { zval *zv = EX_VAR(opline->op1.var); op1_type = Z_TYPE_P(zv); + uint8_t flags = 0; + if (op1_type == IS_INDIRECT) { zv = Z_INDIRECT_P(zv); op1_type = Z_TYPE_P(zv); + flags |= IS_TRACE_INDIRECT; } if (op1_type == IS_REFERENCE) { zv = Z_REFVAL_P(zv); - op1_type = Z_TYPE_P(zv) | IS_TRACE_REFERENCE; + 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); + ce1 = Z_OBJCE_P(zv); } } if (opline->op2_type & (IS_TMP_VAR|IS_VAR|IS_CV)) { zval *zv = EX_VAR(opline->op2.var); + uint8_t flags = 0; + op2_type = Z_TYPE_P(zv); if (op2_type == IS_INDIRECT) { zv = Z_INDIRECT_P(zv); op2_type = Z_TYPE_P(zv); + flags |= IS_TRACE_INDIRECT; } if (op2_type == IS_REFERENCE) { zv = Z_REFVAL_P(zv); - op2_type = Z_TYPE_P(zv) | IS_TRACE_REFERENCE; + 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); + ce2 = Z_OBJCE_P(zv); } } if (opline->opcode == ZEND_ASSIGN_DIM || @@ -640,15 +650,20 @@ zend_jit_trace_stop ZEND_FASTCALL zend_jit_trace_execute(zend_execute_data *ex, opline->opcode == ZEND_ASSIGN_STATIC_PROP_REF) { if ((opline+1)->op1_type & (IS_TMP_VAR|IS_VAR|IS_CV)) { zval *zv = EX_VAR((opline+1)->op1.var); + uint8_t flags = 0; + op3_type = Z_TYPE_P(zv); if (op3_type == IS_INDIRECT) { zv = Z_INDIRECT_P(zv); op3_type = Z_TYPE_P(zv); + flags |= IS_TRACE_INDIRECT; } if (op3_type == IS_REFERENCE) { zv = Z_REFVAL_P(zv); - op3_type = Z_TYPE_P(zv) | IS_TRACE_REFERENCE; + op3_type = Z_TYPE_P(zv); + flags |= IS_TRACE_REFERENCE; } + op3_type |= flags; } }