]> granicus.if.org Git - php/commitdiff
Initial support for IS_INDIRECT. Avoid type guards for IS_INDIRECT.
authorDmitry Stogov <dmitry@zend.com>
Wed, 6 May 2020 19:27:38 +0000 (22:27 +0300)
committerDmitry Stogov <dmitry@zend.com>
Wed, 6 May 2020 19:27:38 +0000 (22:27 +0300)
ext/opcache/jit/zend_jit_internal.h
ext/opcache/jit/zend_jit_trace.c
ext/opcache/jit/zend_jit_vm_helpers.c

index b5f8428689aa5ebbace23684dd5c5a0c89f39dde..7c9e834ad4f5ccb2ec853b093e029ecd5799ad81 100644 (file)
@@ -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 */
index 996408229fadd974d39eda8a3ee14580c124bcad..614f9c0dfff15b7d82048d02ff0e4ae70b7668de 100644 (file)
@@ -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);
                                }
                        }
index f8559378c68a688e65f242842214ac22f5a07b00..2cfb79dbb6411cb1f9d6691a714788eec7d7bdfe 100644 (file)
@@ -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;
                        }
                }