]> granicus.if.org Git - php/commitdiff
Better trace_buffer packing
authorDmitry Stogov <dmitry@zend.com>
Wed, 13 May 2020 12:45:42 +0000 (15:45 +0300)
committerDmitry Stogov <dmitry@zend.com>
Wed, 13 May 2020 12:45:42 +0000 (15:45 +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 da68b0ba90ffc70660051fc306e748bfff1ad7e7..bf730d1fda80e816af25ea74256499452aa640e5 100644 (file)
@@ -254,34 +254,47 @@ typedef enum _zend_jit_trace_op {
        ZEND_JIT_TRACE_DO_ICALL,
        ZEND_JIT_TRACE_ENTER,
        ZEND_JIT_TRACE_BACK,
-       ZEND_JIT_TRACE_START,
        ZEND_JIT_TRACE_END,
+       ZEND_JIT_TRACE_START,
 } 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)
 
+#define ZEND_JIT_TRACE_FAKE_INIT_CALL    0x00000100
+#define ZEND_JIT_TRACE_RETRUN_VALUE_USED 0x00000100
+
+#define ZEND_JIT_TRACE_MAX_SSA_VAR       0x7ffffe
+#define ZEND_JIT_TRACE_SSA_VAR_SHIFT     9
+
+#define ZEND_JIT_TRACE_SET_FIRST_SSA_VAR(_info, var) do { \
+               _info |= (var << ZEND_JIT_TRACE_SSA_VAR_SHIFT); \
+       } while (0)
+#define ZEND_JIT_TRACE_GET_FIRST_SSA_VAR(_info) \
+       (_info >> ZEND_JIT_TRACE_SSA_VAR_SHIFT)
+
 typedef struct _zend_jit_trace_rec {
-       uint8_t   op;    /* zend_jit_trace_op */
        union {
-               struct {
-                       uint8_t op1_type;/* recorded zval op1_type for ZEND_JIT_TRACE_VM */
-                       uint8_t op2_type;/* recorded zval op2_type for ZEND_JIT_TRACE_VM */
-                       uint8_t op3_type;/* recorded zval for op_data.op1_type for ZEND_JIT_TRACE_VM */
-               };
-               struct {
+               struct { ZEND_ENDIAN_LOHI(
+                       uint8_t   op,    /* zend_jit_trace_op */
                        union {
-                               int8_t    return_value_used; /* for ZEND_JIT_TRACE_ENTER */
-                               uint8_t   fake; /* for ZEND_JIT_TRACE_INIT_CALL */
-                       };
-                       uint8_t first_ssa_var; /* may be used for ZEND_JIT_TRACE_ENTER and ZEND_JIT_TRACE_BACK */
-               };
-               struct {
-                       uint8_t  start;  /* ZEND_JIT_TRACE_START_MASK for ZEND_JIT_TRACE_START/END */
-                       uint8_t  stop;   /* zend_jit_trace_stop for ZEND_JIT_TRACE_START/END */
-                       uint8_t  level;  /* recursive return level for ZEND_JIT_TRACE_START */
+                               struct {
+                                       uint8_t op1_type;/* recorded zval op1_type for ZEND_JIT_TRACE_VM */
+                                       uint8_t op2_type;/* recorded zval op2_type for ZEND_JIT_TRACE_VM */
+                                       uint8_t op3_type;/* recorded zval for op_data.op1_type for ZEND_JIT_TRACE_VM */
+                               };
+                               struct {
+                                       uint8_t  start;  /* ZEND_JIT_TRACE_START_MASK for ZEND_JIT_TRACE_START/END */
+                                       uint8_t  stop;   /* zend_jit_trace_stop for ZEND_JIT_TRACE_START/END */
+                                       uint8_t  level;  /* recursive return level for ZEND_JIT_TRACE_START */
+                               };
+                       })
                };
+               uint32_t last;
+               uint32_t info; /* "first_ssa_var" for ZEND_JIT_TRACE_ENTER and ZEND_JIT_TRACE_BACK,
+                               * "return_value_used" for ZEND_JIT_TRACE_ENTER,
+                               * "fake" for ZEND_JIT_TRACE_INIT_CALL */
        };
        union {
                const void             *ptr;
@@ -292,15 +305,6 @@ typedef struct _zend_jit_trace_rec {
        };
 } zend_jit_trace_rec;
 
-typedef struct _zend_jit_trace_start_rec {
-       uint8_t  op;     /* zend_jit_trace_op */
-       uint8_t  start;  /* ZEND_JIT_TRACE_START_MASK for ZEND_JIT_TRACE_START/END */
-       uint8_t  stop;   /* zend_jit_trace_stop for ZEND_JIT_TRACE_START/END */
-       uint8_t  level;  /* recursive return level for ZEND_JIT_TRACE_START */
-       const zend_op_array *op_array;
-       const zend_op *opline;
-} zend_jit_trace_start_rec;
-
 #define ZEND_JIT_TRACE_START_REC_SIZE 2
 
 typedef struct _zend_jit_trace_exit_info {
index e6fc46d067fbf0bb966daec53c322dcd23ed54cd..ea1da28c31a5730ed9adcd00456d5ff1611f790f 100644 (file)
@@ -761,7 +761,7 @@ static int find_return_ssa_var(zend_jit_trace_rec *p, zend_ssa_op *ssa_op)
 
 static const zend_op *zend_jit_trace_find_init_fcall_op(zend_jit_trace_rec *p, const zend_op_array *op_array)
 {
-       if (!p->fake) {
+       if (!(p->info & ZEND_JIT_TRACE_FAKE_INIT_CALL)) {
                p--;
                while (1) {
                        if (p->op == ZEND_JIT_TRACE_VM) {
@@ -1058,11 +1058,10 @@ static zend_ssa *zend_jit_trace_build_tssa(zend_jit_trace_rec *trace_buffer, uin
                        stack = frame->stack;
                        op_array = p->op_array;
                        level++;
-                       // TODO: remove this restriction ???
-                       if (ssa_vars_count >= 0xff) {
+                       if (ssa_vars_count >= ZEND_JIT_TRACE_MAX_SSA_VAR) {
                                return NULL;
                        }
-                       p->first_ssa_var = ssa_vars_count;
+                       ZEND_JIT_TRACE_SET_FIRST_SSA_VAR(p->info, ssa_vars_count);
                        for (i = 0; i < op_array->last_var; i++) {
                                SET_STACK_VAR(stack, i, ssa_vars_count++);
                        }
@@ -1071,11 +1070,10 @@ static zend_ssa *zend_jit_trace_build_tssa(zend_jit_trace_rec *trace_buffer, uin
                        frame = zend_jit_trace_ret_frame(frame, op_array);
                        stack = frame->stack;
                        if (level == 0) {
-                               // TODO: remove this restriction ???
-                               if (ssa_vars_count >= 0xff) {
+                               if (ssa_vars_count >= ZEND_JIT_TRACE_MAX_SSA_VAR) {
                                        return NULL;
                                }
-                               p->first_ssa_var = ssa_vars_count;
+                               ZEND_JIT_TRACE_SET_FIRST_SSA_VAR(p->info, ssa_vars_count);
                                for (i = 0; i < op_array->last_var + op_array->T; i++) {
                                        SET_STACK_VAR(stack, i, ssa_vars_count++);
                                }
@@ -1561,7 +1559,7 @@ static zend_ssa *zend_jit_trace_build_tssa(zend_jit_trace_rec *trace_buffer, uin
 
                        level++;
                        i = 0;
-                       v = p->first_ssa_var;
+                       v = ZEND_JIT_TRACE_GET_FIRST_SSA_VAR(p->info);
                        while (i < op_array->last_var) {
                                ssa_vars[v].var = i;
                                if (i < op_array->num_args) {
@@ -1601,7 +1599,7 @@ static zend_ssa *zend_jit_trace_build_tssa(zend_jit_trace_rec *trace_buffer, uin
                        ssa = &jit_extension->func_info.ssa;
                        if (level == 0) {
                                i = 0;
-                               v = p->first_ssa_var;
+                               v = ZEND_JIT_TRACE_GET_FIRST_SSA_VAR(p->info);
                                while (i < op_array->last_var) {
                                        ssa_vars[v].var = i;
                                        if (!ssa->var_info
@@ -1629,7 +1627,7 @@ static zend_ssa *zend_jit_trace_build_tssa(zend_jit_trace_rec *trace_buffer, uin
                                                const zend_op *opline = q->opline - 1;
                                                if (opline->result_type != IS_UNUSED) {
                                                        ssa_var_info[
-                                                               p->first_ssa_var +
+                                                               ZEND_JIT_TRACE_GET_FIRST_SSA_VAR(p->info) +
                                                                EX_VAR_TO_NUM(opline->result.var)] = return_value_info;
                                                }
                                        }
@@ -1729,7 +1727,7 @@ static zend_ssa *zend_jit_trace_build_tssa(zend_jit_trace_rec *trace_buffer, uin
                                trace_buffer->op_array->function_name ?
                                        ZSTR_VAL(trace_buffer->op_array->function_name) : "$main",
                                ZSTR_VAL(trace_buffer->op_array->filename),
-                               ((zend_jit_trace_start_rec*)trace_buffer)->opline->lineno);
+                               trace_buffer[1].opline->lineno);
                } else {
                        fprintf(stderr, "---- TRACE %d TSSA start (%s) %s() %s:%d\n",
                                ZEND_JIT_TRACE_NUM,
@@ -1737,11 +1735,12 @@ static zend_ssa *zend_jit_trace_build_tssa(zend_jit_trace_rec *trace_buffer, uin
                                trace_buffer->op_array->function_name ?
                                        ZSTR_VAL(trace_buffer->op_array->function_name) : "$main",
                                ZSTR_VAL(trace_buffer->op_array->filename),
-                               ((zend_jit_trace_start_rec*)trace_buffer)->opline->lineno);
+                               trace_buffer[1].opline->lineno);
                }
                zend_jit_dump_trace(trace_buffer, tssa);
                if (trace_buffer->stop == ZEND_JIT_TRACE_STOP_LINK) {
-                       uint32_t link_to = zend_jit_find_trace(EG(current_execute_data)->opline->handler);;
+                       uint32_t idx = trace_buffer[1].last;
+                       uint32_t link_to = zend_jit_find_trace(trace_buffer[idx].opline->handler);
                        fprintf(stderr, "---- TRACE %d TSSA stop (link to %d)\n",
                                ZEND_JIT_TRACE_NUM,
                                link_to);
@@ -2062,7 +2061,7 @@ static zend_lifetime_interval** zend_jit_trace_allocate_registers(zend_jit_trace
                        jit_extension =
                                (zend_jit_op_array_trace_extension*)ZEND_FUNC_INFO(op_array);
                        op_array_ssa = &jit_extension->func_info.ssa;
-                       j = p->first_ssa_var;
+                       j = ZEND_JIT_TRACE_GET_FIRST_SSA_VAR(p->info);
                        for (i = 0; i < op_array->last_var; i++) {
                                SET_STACK_VAR(stack, i, j);
                                vars_op_array[j] = op_array;
@@ -2091,7 +2090,7 @@ static zend_lifetime_interval** zend_jit_trace_allocate_registers(zend_jit_trace
                        stack = frame->stack;
                        if (level == 0) {
                                /* New return frames */
-                               j = p->first_ssa_var;
+                               j = ZEND_JIT_TRACE_GET_FIRST_SSA_VAR(p->info);
                                for (i = 0; i < op_array->last_var + op_array->T; i++) {
                                        SET_STACK_VAR(stack, i, j);
                                        vars_op_array[j] = op_array;
@@ -2481,7 +2480,7 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par
        TRACE_FRAME_INIT(frame, op_array, TRACE_FRAME_MASK_UNKNOWN_RETURN, -1);
        stack = frame->stack;
 
-       opline = ((zend_jit_trace_start_rec*)p)->opline;
+       opline = p[1].opline;
        name = zend_jit_trace_name(op_array, opline->lineno);
        p += ZEND_JIT_TRACE_START_REC_SIZE;
 
@@ -3809,17 +3808,20 @@ done:
                        op_array_ssa = &jit_extension->func_info.ssa;
                        call = frame->call;
                        if (!call) {
+                               uint32_t v;
+
                                assert(0); // This should be handled by "fake" ZEND_JIT_TRACE_INIT_CALL
                                /* Trace missed INIT_FCALL opcode */
                                call = top;
                                TRACE_FRAME_INIT(call, op_array, 0, -1); // TODO: should be possible to get the real number af arguments ???
                                top = zend_jit_trace_call_frame(top, op_array);
                                i = 0;
+                               v = ZEND_JIT_TRACE_GET_FIRST_SSA_VAR(p->info);
                                while (i < p->op_array->num_args) {
                                        /* Initialize abstract stack using SSA */
-                                       if (!(ssa->var_info[p->first_ssa_var + i].type & MAY_BE_GUARD)
-                                        && has_concrete_type(ssa->var_info[p->first_ssa_var + i].type)) {
-                                               SET_STACK_TYPE(call->stack, i, concrete_type(ssa->var_info[p->first_ssa_var + i].type));
+                                       if (!(ssa->var_info[v + i].type & MAY_BE_GUARD)
+                                        && has_concrete_type(ssa->var_info[v + i].type)) {
+                                               SET_STACK_TYPE(call->stack, i, concrete_type(ssa->var_info[v + i].type));
                                        } else {
                                                SET_STACK_TYPE(call->stack, i, IS_UNKNOWN);
                                        }
@@ -3838,7 +3840,7 @@ done:
                        }
                        frame->call = call->prev;
                        call->prev = frame;
-                       if (p->return_value_used) {
+                       if (p->info & ZEND_JIT_TRACE_RETRUN_VALUE_USED) {
                                TRACE_FRAME_SET_RETURN_VALUE_USED(call);
                        } else {
                                TRACE_FRAME_SET_RETURN_VALUE_UNUSED(call);
@@ -3846,9 +3848,9 @@ done:
                        JIT_G(current_frame) = frame = call;
                        stack = frame->stack;
                        if (ra) {
-                               for (i = 0; i < op_array->last_var; i++) {
-                                       int j = p->first_ssa_var + i;
+                               int j = ZEND_JIT_TRACE_GET_FIRST_SSA_VAR(p->info);
 
+                               for (i = 0; i < op_array->last_var; i++,j++) {
                                        if (ra[j] && (ra[j]->flags & ZREG_LOAD) != 0) {
                                                //SET_STACK_REG(stack, i, ra[j]->reg);
                                                if (!zend_jit_load_var(&dasm_state, ssa->var_info[j].type, i, ra[j]->reg)) {
@@ -3869,22 +3871,23 @@ done:
                                stack = frame->stack;
                                ZEND_ASSERT(&frame->func->op_array == op_array);
                        } else {
+                               uint32_t j = ZEND_JIT_TRACE_GET_FIRST_SSA_VAR(p->info);
+
                                frame = zend_jit_trace_ret_frame(frame, op_array);
                                TRACE_FRAME_INIT(frame, op_array, TRACE_FRAME_MASK_UNKNOWN_RETURN, -1);
                                stack = frame->stack;
-                               for (i = 0; i < op_array->last_var + op_array->T; i++) {
+                               for (i = 0; i < op_array->last_var + op_array->T; i++, j++) {
                                        /* Initialize abstract stack using SSA */
-                                       if (!(ssa->var_info[p->first_ssa_var + i].type & MAY_BE_GUARD)
-                                        && has_concrete_type(ssa->var_info[p->first_ssa_var + i].type)) {
-                                               SET_STACK_TYPE(stack, i, concrete_type(ssa->var_info[p->first_ssa_var + i].type));
+                                       if (!(ssa->var_info[j].type & MAY_BE_GUARD)
+                                        && has_concrete_type(ssa->var_info[j].type)) {
+                                               SET_STACK_TYPE(stack, i, concrete_type(ssa->var_info[j].type));
                                        } else {
                                                SET_STACK_TYPE(stack, i, IS_UNKNOWN);
                                        }
                                }
                                if (ra) {
-                                       for (i = 0; i < op_array->last_var + op_array->T; i++) {
-                                               int j = p->first_ssa_var + i;
-
+                                       j = ZEND_JIT_TRACE_GET_FIRST_SSA_VAR(p->info);
+                                       for (i = 0; i < op_array->last_var + op_array->T; i++, j++) {
                                                if (ra[j] && (ra[j]->flags & ZREG_LOAD) != 0) {
                                                        //SET_STACK_REG(stack, i, ra[j]->reg);
                                                        if (!zend_jit_load_var(&dasm_state, ssa->var_info[j].type, i, ra[j]->reg)) {
@@ -3917,7 +3920,7 @@ done:
                        call = top;
                        TRACE_FRAME_INIT(call, p->func, TRACE_FRAME_MASK_NESTED, num_args);
                        call->prev = frame->call;
-                       if (!p->fake) {
+                       if (!(p->info & ZEND_JIT_TRACE_FAKE_INIT_CALL)) {
                                TRACE_FRAME_SET_LAST_SEND_BY_VAL(call);
                        }
                        frame->call = call;
@@ -3938,7 +3941,7 @@ done:
                                        i++;
                                }
                        }
-                       if (p->fake) {
+                       if (p->info & ZEND_JIT_TRACE_FAKE_INIT_CALL) {
                                int skip_guard = 0;
 
                                if (init_opline) {
@@ -3952,7 +3955,7 @@ done:
                                                call_info = call_info->next_callee;
                                        }
                                }
-                               if (!skip_guard && !zend_jit_init_fcall_guard(&dasm_state, NULL, p->func, ((zend_jit_trace_start_rec*)trace_buffer)->opline)) {
+                               if (!skip_guard && !zend_jit_init_fcall_guard(&dasm_state, NULL, p->func, trace_buffer[1].opline)) {
                                        goto jit_failure;
                                }
                                frame->call_level++;
@@ -4143,7 +4146,7 @@ static zend_jit_trace_stop zend_jit_compile_root_trace(zend_jit_trace_rec *trace
                t->child_count = 0;
                t->stack_map_size = 0;
                t->flags = 0;
-               t->opline = ((zend_jit_trace_start_rec*)trace_buffer)->opline;
+               t->opline = trace_buffer[1].opline;
                t->exit_info = exit_info;
                t->stack_map = NULL;
 
@@ -4400,7 +4403,7 @@ static void zend_jit_dump_trace(zend_jit_trace_rec *trace_buffer, zend_ssa *tssa
                        level++;
                        if (tssa && tssa->var_info) {
                                call_level++;
-                               v = p->first_ssa_var;
+                               v = ZEND_JIT_TRACE_GET_FIRST_SSA_VAR(p->info);
                                vars_count = op_array->last_var;
                                for (i = 0; i < vars_count; i++, v++) {
                                        if (tssa->vars[v].use_chain >= 0 || tssa->vars[v].phi_use_chain) {
@@ -4422,7 +4425,7 @@ static void zend_jit_dump_trace(zend_jit_trace_rec *trace_buffer, zend_ssa *tssa
                                        ZSTR_VAL(op_array->filename));
                        if (tssa && tssa->var_info) {
                                if (call_level == 0) {
-                                       v = p->first_ssa_var;
+                                       v = ZEND_JIT_TRACE_GET_FIRST_SSA_VAR(p->info);
                                        vars_count = op_array->last_var + op_array->T;
                                        for (i = 0; i < vars_count; i++, v++) {
                                                if (tssa->vars[v].use_chain >= 0 || tssa->vars[v].phi_use_chain) {
@@ -4437,7 +4440,7 @@ static void zend_jit_dump_trace(zend_jit_trace_rec *trace_buffer, zend_ssa *tssa
                        }
                } else if (p->op == ZEND_JIT_TRACE_INIT_CALL) {
                        if (p->func != (zend_function*)&zend_pass_function) {
-                               fprintf(stderr, p->fake ? "    %*c>fake_init %s%s%s\n" : "    %*c>init %s%s%s\n",
+                               fprintf(stderr, (p->info & ZEND_JIT_TRACE_FAKE_INIT_CALL) ? "    %*c>fake_init %s%s%s\n" : "    %*c>init %s%s%s\n",
                                        level, ' ',
                                        p->func->common.scope ? ZSTR_VAL(p->func->common.scope->name) : "",
                                        p->func->common.scope ? "::" : "",
@@ -4571,7 +4574,8 @@ repeat:
        if (ZEND_JIT_TRACE_STOP_OK(stop)) {
                if (ZCG(accel_directives).jit_debug & ZEND_JIT_DEBUG_TRACE_STOP) {
                        if (stop == ZEND_JIT_TRACE_STOP_LINK) {
-                               uint32_t link_to = zend_jit_find_trace(EG(current_execute_data)->opline->handler);;
+                               uint32_t idx = trace_buffer[1].last;
+                               uint32_t link_to = zend_jit_find_trace(trace_buffer[idx].opline->handler);
                                fprintf(stderr, "---- TRACE %d stop (link to %d)\n",
                                        trace_num,
                                        link_to);
@@ -4840,7 +4844,8 @@ int ZEND_FASTCALL zend_jit_trace_hot_side(zend_execute_data *execute_data, uint3
        if (ZEND_JIT_TRACE_STOP_OK(stop)) {
                if (ZCG(accel_directives).jit_debug & ZEND_JIT_DEBUG_TRACE_STOP) {
                        if (stop == ZEND_JIT_TRACE_STOP_LINK) {
-                               uint32_t link_to = zend_jit_find_trace(EG(current_execute_data)->opline->handler);;
+                               uint32_t idx = trace_buffer[1].last;
+                               uint32_t link_to = zend_jit_find_trace(trace_buffer[idx].opline->handler);;
                                fprintf(stderr, "---- TRACE %d stop (link to %d)\n",
                                        trace_num,
                                        link_to);
index 6def59f9140fdaa8ae17c6d3ee72d58aa3c3a26c..c766aaaadda428d3d8d82208bb64ef1a943aab99 100644 (file)
@@ -326,8 +326,8 @@ ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_jit_loop_trace_helper(ZEND_OPCODE_HAN
        ZEND_OPCODE_TAIL_CALL_EX(zend_jit_trace_counter_helper, ZEND_JIT_TRACE_LOOP_COST);
 }
 
-#define TRACE_RECORD(_op, _ptr) \
-       trace_buffer[idx].op = _op; \
+#define TRACE_RECORD(_op, _info, _ptr) \
+       trace_buffer[idx].info = _op | (_info); \
        trace_buffer[idx].ptr = _ptr; \
        idx++; \
        if (idx >= ZEND_JIT_TRACE_MAX_LENGTH - 1) { \
@@ -347,52 +347,17 @@ ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_jit_loop_trace_helper(ZEND_OPCODE_HAN
                break; \
        }
 
-#define TRACE_RECORD_ENTER(_op, _return_value_used, _ptr) \
-       trace_buffer[idx].op = _op; \
-       trace_buffer[idx].return_value_used = _return_value_used; \
-       trace_buffer[idx].ptr = _ptr; \
-       idx++; \
-       if (idx >= ZEND_JIT_TRACE_MAX_LENGTH - 1) { \
-               stop = ZEND_JIT_TRACE_STOP_TOO_LONG; \
-               break; \
-       }
-
-#define TRACE_RECORD_INIT(_op, _fake, _ptr) \
-       trace_buffer[idx].op = _op; \
-       trace_buffer[idx].fake = _fake; \
-       trace_buffer[idx].ptr = _ptr; \
-       idx++; \
-       if (idx >= ZEND_JIT_TRACE_MAX_LENGTH - 1) { \
-               stop = ZEND_JIT_TRACE_STOP_TOO_LONG; \
-               break; \
-       }
-
-#define TRACE_RECORD_BACK(_op, _ptr) \
-       trace_buffer[idx].op = _op; \
-       trace_buffer[idx].ptr = _ptr; \
-       idx++; \
-       if (idx >= ZEND_JIT_TRACE_MAX_LENGTH - 1) { \
-               stop = ZEND_JIT_TRACE_STOP_TOO_LONG; \
-               break; \
-       }
-
-#define TRACE_RECORD_TYPE(_op, _ptr) \
-       trace_buffer[idx].op = _op; \
-       trace_buffer[idx].ptr = _ptr; \
-       idx++; \
-       if (idx >= ZEND_JIT_TRACE_MAX_LENGTH - 1) { \
-               stop = ZEND_JIT_TRACE_STOP_TOO_LONG; \
-               break; \
-       }
-
-#define TRACE_START(_op, _start, _ptr) \
+#define TRACE_START(_op, _start, _ptr1, _ptr2) \
        trace_buffer[0].op = _op; \
        trace_buffer[0].start = _start; \
        trace_buffer[0].level = 0; \
-       trace_buffer[0].ptr = _ptr; \
+       trace_buffer[0].ptr = _ptr1; \
+       trace_buffer[1].last = 0; \
+       trace_buffer[1].ptr = _ptr2; \
        idx = ZEND_JIT_TRACE_START_REC_SIZE;
 
 #define TRACE_END(_op, _stop, _ptr) \
+       trace_buffer[1].last = idx; \
        trace_buffer[idx].op   = _op; \
        trace_buffer[idx].start = trace_buffer[idx].start; \
        trace_buffer[idx].stop = trace_buffer[0].stop = _stop; \
@@ -503,7 +468,7 @@ static int zend_jit_trace_record_fake_init_call(zend_execute_data *call, zend_ji
                if (call->prev_execute_data) {
                        idx = zend_jit_trace_record_fake_init_call(call->prev_execute_data, trace_buffer, idx);
                }
-               TRACE_RECORD_INIT(ZEND_JIT_TRACE_INIT_CALL, 1, call->func);
+               TRACE_RECORD(ZEND_JIT_TRACE_INIT_CALL, ZEND_JIT_TRACE_FAKE_INIT_CALL, call->func);
        } while (0);
        return idx;
 }
@@ -581,8 +546,7 @@ zend_jit_trace_stop ZEND_FASTCALL zend_jit_trace_execute(zend_execute_data *ex,
                (zend_jit_op_array_trace_extension*)ZEND_FUNC_INFO(&EX(func)->op_array);
        offset = jit_extension->offset;
 
-       TRACE_START(ZEND_JIT_TRACE_START, start, &EX(func)->op_array);
-       ((zend_jit_trace_start_rec*)trace_buffer)->opline = opline;
+       TRACE_START(ZEND_JIT_TRACE_START, start, &EX(func)->op_array, opline);
        is_toplevel = EX(func)->op_array.function_name == NULL;
 
        if (prev_call) {
@@ -669,11 +633,11 @@ zend_jit_trace_stop ZEND_FASTCALL zend_jit_trace_execute(zend_execute_data *ex,
                TRACE_RECORD_VM(ZEND_JIT_TRACE_VM, opline, op1_type, op2_type, op3_type);
 
                if (ce1) {
-                       TRACE_RECORD_TYPE(ZEND_JIT_TRACE_OP1_TYPE, ce1);
+                       TRACE_RECORD(ZEND_JIT_TRACE_OP1_TYPE, 0, ce1);
                }
 
                if (ce2) {
-                       TRACE_RECORD_TYPE(ZEND_JIT_TRACE_OP2_TYPE, ce2);
+                       TRACE_RECORD(ZEND_JIT_TRACE_OP2_TYPE, 0, ce2);
                }
 
                switch (opline->opcode) {
@@ -682,7 +646,7 @@ zend_jit_trace_stop ZEND_FASTCALL zend_jit_trace_execute(zend_execute_data *ex,
                        case ZEND_DO_UCALL:
                        case ZEND_DO_FCALL_BY_NAME:
                                if (EX(call)->func->type == ZEND_INTERNAL_FUNCTION) {
-                                       TRACE_RECORD(ZEND_JIT_TRACE_DO_ICALL, EX(call)->func);
+                                       TRACE_RECORD(ZEND_JIT_TRACE_DO_ICALL, 0, EX(call)->func);
                                }
                                break;
                        default:
@@ -722,7 +686,9 @@ zend_jit_trace_stop ZEND_FASTCALL zend_jit_trace_execute(zend_execute_data *ex,
                                        break;
                                }
 
-                               TRACE_RECORD_ENTER(ZEND_JIT_TRACE_ENTER, EX(return_value) != NULL, &EX(func)->op_array);
+                               TRACE_RECORD(ZEND_JIT_TRACE_ENTER,
+                                       EX(return_value) != NULL ? ZEND_JIT_TRACE_RETRUN_VALUE_USED : 0,
+                                       &EX(func)->op_array);
 
                                count = zend_jit_trace_recursive_call_count(&EX(func)->op_array, unrolled_calls, ret_level, level);
 
@@ -756,7 +722,7 @@ zend_jit_trace_stop ZEND_FASTCALL zend_jit_trace_execute(zend_execute_data *ex,
                                                        stop = ZEND_JIT_TRACE_STOP_TOO_DEEP_RET;
                                                        break;
                                                }
-                                               TRACE_RECORD_BACK(ZEND_JIT_TRACE_BACK, &EX(func)->op_array);
+                                               TRACE_RECORD(ZEND_JIT_TRACE_BACK, 0, &EX(func)->op_array);
                                                count = zend_jit_trace_recursive_ret_count(&EX(func)->op_array, unrolled_calls, ret_level);
                                                if (opline == orig_opline) {
                                                        if (count + 1 >= ZEND_JIT_TRACE_MAX_RECURSION) {
@@ -790,7 +756,7 @@ zend_jit_trace_stop ZEND_FASTCALL zend_jit_trace_execute(zend_execute_data *ex,
                                        }
                                } else {
                                        level--;
-                                       TRACE_RECORD_BACK(ZEND_JIT_TRACE_BACK, &EX(func)->op_array);
+                                       TRACE_RECORD(ZEND_JIT_TRACE_BACK, 0, &EX(func)->op_array);
                                }
                        }
 #ifdef HAVE_GCC_GLOBAL_REGS
@@ -812,7 +778,7 @@ zend_jit_trace_stop ZEND_FASTCALL zend_jit_trace_execute(zend_execute_data *ex,
                                        stop = ZEND_JIT_TRACE_STOP_TRAMPOLINE;
                                        break;
                                }
-                               TRACE_RECORD_INIT(ZEND_JIT_TRACE_INIT_CALL, 0, EX(call)->func);
+                               TRACE_RECORD(ZEND_JIT_TRACE_INIT_CALL, 0, EX(call)->func);
                        }
                        prev_call = EX(call);
                }
@@ -869,7 +835,7 @@ zend_jit_trace_stop ZEND_FASTCALL zend_jit_trace_execute(zend_execute_data *ex,
                                        break;
                                }
                        } else if (trace_flags & ZEND_JIT_TRACE_UNSUPPORTED) {
-                               TRACE_RECORD(ZEND_JIT_TRACE_VM, opline);
+                               TRACE_RECORD(ZEND_JIT_TRACE_VM, 0, opline);
                                stop = ZEND_JIT_TRACE_STOP_NOT_SUPPORTED;
                                break;
                        }
@@ -892,7 +858,8 @@ zend_jit_trace_stop ZEND_FASTCALL zend_jit_trace_execute(zend_execute_data *ex,
 
        if (stop == ZEND_JIT_TRACE_STOP_LINK) {
                /* Shrink fake INIT_CALLs */
-               while (trace_buffer[idx-1].op == ZEND_JIT_TRACE_INIT_CALL && trace_buffer[idx-1].fake) {
+               while (trace_buffer[idx-1].op == ZEND_JIT_TRACE_INIT_CALL
+                               && (trace_buffer[idx-1].info & ZEND_JIT_TRACE_FAKE_INIT_CALL)) {
                        idx--;
                }
        }
index 9675791a78ef70c91cb6c84607cf407e61d8b41e..3d8e4bf300945428a5d1799c527d86276c6d713d 100644 (file)
@@ -11479,7 +11479,7 @@ static zend_regset zend_jit_get_scratch_regset(const zend_op *opline, const zend
        if (zend_jit_trigger == ZEND_JIT_ON_HOT_TRACE) {
                if (ssa_op == ssa->ops
                 && JIT_G(current_trace)[ZEND_JIT_TRACE_START_REC_SIZE].op == ZEND_JIT_TRACE_INIT_CALL
-                && JIT_G(current_trace)[ZEND_JIT_TRACE_START_REC_SIZE].fake) {
+                && (JIT_G(current_trace)[ZEND_JIT_TRACE_START_REC_SIZE].info & ZEND_JIT_TRACE_FAKE_INIT_CALL)) {
                        ZEND_REGSET_INCL(regset, ZREG_R0);
                        ZEND_REGSET_INCL(regset, ZREG_R1);
                }