mirror of
https://github.com/php/php-src.git
synced 2024-09-22 18:37:25 +00:00
Better trace_buffer packing
This commit is contained in:
parent
555489dd83
commit
98d8bcc13a
@ -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 {
|
||||
|
@ -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);
|
||||
|
@ -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--;
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user