Skip to content

Commit eef56d3

Browse files
author
test@test.test
committed
Revert JIT changes
1 parent 71b16ee commit eef56d3

File tree

4 files changed

+110
-85
lines changed

4 files changed

+110
-85
lines changed

Zend/zend_execute.c

Lines changed: 1 addition & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1540,55 +1540,14 @@ static zend_never_inline void zend_assign_to_object_dim(zend_object *obj, zval *
15401540
}
15411541
}
15421542

1543-
static void zend_frameless_observed_call_push(zend_execute_data *call, uint8_t arg, zval *zv, uint8_t op_type) {
1543+
static zend_always_inline void zend_frameless_observed_call_push(zend_execute_data *call, uint8_t arg, zval *zv, uint8_t op_type) {
15441544
ZVAL_COPY(ZEND_CALL_VAR_NUM(call, arg), zv);
15451545
if (op_type & (IS_TMP_VAR|IS_VAR)) {
15461546
zval_ptr_dtor_nogc(zv);
15471547
ZVAL_UNDEF(zv);
15481548
}
15491549
}
15501550

1551-
ZEND_API void zend_frameless_observed_call(EXECUTE_DATA_D OPLINE_DC)
1552-
{
1553-
uint8_t num_args = ZEND_FLF_NUM_ARGS(opline->opcode);
1554-
zend_function *fbc = ZEND_FLF_FUNC(opline);
1555-
1556-
zval *result = EX_VAR(opline->result.var);
1557-
ZVAL_NULL(result);
1558-
1559-
zend_execute_data *call = zend_vm_stack_push_call_frame_ex(zend_vm_calc_used_stack(num_args, fbc), ZEND_CALL_NESTED_FUNCTION, fbc, num_args, NULL);
1560-
call->prev_execute_data = execute_data;
1561-
1562-
switch (num_args) {
1563-
case 3: zend_frameless_observed_call_push(call, 2, get_op_data_zval_ptr_deref_r((opline+1)->op1_type, (opline+1)->op1), (opline+1)->op1_type); ZEND_FALLTHROUGH;
1564-
case 2: zend_frameless_observed_call_push(call, 1, get_zval_ptr_deref(opline->op2_type, opline->op2, BP_VAR_R), opline->op2_type); ZEND_FALLTHROUGH;
1565-
case 1: zend_frameless_observed_call_push(call, 0, get_zval_ptr_deref(opline->op1_type, opline->op1, BP_VAR_R), opline->op1_type);
1566-
1567-
if (EG(exception)) {
1568-
goto free_args;
1569-
}
1570-
}
1571-
1572-
EG(current_execute_data) = call;
1573-
1574-
zend_observer_fcall_begin_prechecked(call, ZEND_OBSERVER_DATA(fbc));
1575-
fbc->internal_function.handler(call, result);
1576-
zend_observer_fcall_end(call, result);
1577-
1578-
EG(current_execute_data) = execute_data;
1579-
1580-
free_args: ;
1581-
zend_vm_stack_free_args(call);
1582-
1583-
uint32_t call_info = ZEND_CALL_INFO(call);
1584-
if (UNEXPECTED(call_info & ZEND_CALL_ALLOCATED)) {
1585-
zend_vm_stack_free_call_frame_ex(call_info, call);
1586-
} else {
1587-
EG(vm_stack_top) = (zval*)call;
1588-
}
1589-
}
1590-
1591-
15921551
static zend_always_inline int zend_binary_op(zval *ret, zval *op1, zval *op2 OPLINE_DC)
15931552
{
15941553
static const binary_op_type zend_binary_ops[] = {

Zend/zend_vm_def.h

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9603,7 +9603,42 @@ ZEND_VM_HELPER(zend_frameless_observed_call, ANY, ANY)
96039603
{
96049604
USE_OPLINE
96059605

9606-
zend_frameless_observed_call(EXECUTE_DATA_C OPLINE_CC);
9606+
uint8_t num_args = ZEND_FLF_NUM_ARGS(opline->opcode);
9607+
zend_function *fbc = ZEND_FLF_FUNC(opline);
9608+
9609+
zval *result = EX_VAR(opline->result.var);
9610+
ZVAL_NULL(result);
9611+
9612+
zend_execute_data *call = zend_vm_stack_push_call_frame_ex(zend_vm_calc_used_stack(num_args, fbc), ZEND_CALL_NESTED_FUNCTION, fbc, num_args, NULL);
9613+
call->prev_execute_data = execute_data;
9614+
9615+
switch (num_args) {
9616+
case 3: zend_frameless_observed_call_push(call, 2, get_op_data_zval_ptr_deref_r((opline+1)->op1_type, (opline+1)->op1), (opline+1)->op1_type); ZEND_FALLTHROUGH;
9617+
case 2: zend_frameless_observed_call_push(call, 1, get_zval_ptr_deref(opline->op2_type, opline->op2, BP_VAR_R), opline->op2_type); ZEND_FALLTHROUGH;
9618+
case 1: zend_frameless_observed_call_push(call, 0, get_zval_ptr_deref(opline->op1_type, opline->op1, BP_VAR_R), opline->op1_type);
9619+
9620+
if (EG(exception)) {
9621+
goto free_args;
9622+
}
9623+
}
9624+
9625+
EG(current_execute_data) = call;
9626+
9627+
zend_observer_fcall_begin_prechecked(call, ZEND_OBSERVER_DATA(fbc));
9628+
fbc->internal_function.handler(call, result);
9629+
zend_observer_fcall_end(call, result);
9630+
9631+
EG(current_execute_data) = execute_data;
9632+
9633+
free_args: ;
9634+
zend_vm_stack_free_args(call);
9635+
9636+
uint32_t call_info = ZEND_CALL_INFO(call);
9637+
if (UNEXPECTED(call_info & ZEND_CALL_ALLOCATED)) {
9638+
zend_vm_stack_free_call_frame_ex(call_info, call);
9639+
} else {
9640+
EG(vm_stack_top) = (zval*)call;
9641+
}
96079642

96089643
if (UNEXPECTED(EG(exception) != NULL)) {
96099644
zend_rethrow_exception(execute_data);

ext/opcache/jit/zend_jit_helpers.c

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3279,3 +3279,29 @@ static zend_string* ZEND_FASTCALL zend_jit_rope_end(zend_string **rope, uint32_t
32793279
return ret;
32803280
}
32813281

3282+
static zend_execute_data* ZEND_FASTCALL zend_jit_observed_frameless_helper_push(zend_execute_data *execute_data, uint32_t stack_size, zend_function *fbc, uint32_t args)
3283+
{
3284+
zend_execute_data *call = zend_vm_stack_push_call_frame_ex(stack_size, ZEND_CALL_NESTED_FUNCTION, fbc, args, NULL);
3285+
call->prev_execute_data = execute_data;
3286+
EG(current_execute_data) = call;
3287+
3288+
return call;
3289+
}
3290+
3291+
static void ZEND_FASTCALL zend_jit_observed_frameless_helper_call(zend_execute_data *call, zif_handler handler, void *observer_handler, zval *result)
3292+
{
3293+
zend_observer_fcall_begin_prechecked(call, observer_handler);
3294+
handler(call, result);
3295+
zend_observer_fcall_end(call, result);
3296+
3297+
EG(current_execute_data) = call->prev_execute_data;
3298+
zend_vm_stack_free_args(call);
3299+
3300+
uint32_t call_info = ZEND_CALL_INFO(call);
3301+
if (UNEXPECTED(call_info & ZEND_CALL_ALLOCATED)) {
3302+
zend_vm_stack_free_call_frame_ex(call_info, call);
3303+
} else {
3304+
EG(vm_stack_top) = (zval*)call;
3305+
}
3306+
}
3307+

ext/opcache/jit/zend_jit_ir.c

Lines changed: 47 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -3069,6 +3069,8 @@ static void zend_jit_setup_disasm(void)
30693069
REGISTER_HELPER(zend_jit_pre_dec_obj_helper);
30703070
REGISTER_HELPER(zend_jit_post_dec_obj_helper);
30713071
REGISTER_HELPER(zend_jit_rope_end);
3072+
REGISTER_HELPER(zend_jit_observed_frameless_helper_push);
3073+
REGISTER_HELPER(zend_jit_observed_frameless_helper_call);
30723074

30733075
#ifndef ZTS
30743076
REGISTER_DATA(EG(current_execute_data));
@@ -17050,25 +17052,36 @@ static bool zend_jit_may_be_in_reg(const zend_op_array *op_array, zend_ssa *ssa,
1705017052
return 1;
1705117053
}
1705217054

17053-
void zend_frameless_observed_call(void); // we just care about the symbol to use it here, IP and FP may need to be passed depending on global regs
17054-
static ir_ref jit_frameless_observer(zend_jit_ctx *jit, const zend_op *opline) {
17055+
static ir_ref jit_frameless_observer(zend_jit_ctx *jit, const zend_op *opline, ir_ref op1_ref, uint32_t op1_info, ir_ref op2_ref, uint32_t op2_info, ir_ref op1_data_ref, uint32_t op1_data_info, ir_ref res_ref) {
1705517056
// JIT: zend_observer_handler_is_unobserved(ZEND_OBSERVER_DATA(fbc))
1705617057
ir_ref observer_handler;
1705717058
zend_function *fbc = ZEND_FLF_FUNC(opline);
1705817059
// Not need for runtime cache or generator checks here, we just need if_unobserved
1705917060
ir_ref if_unobserved = jit_observer_fcall_is_unobserved_start(jit, fbc, &observer_handler, IR_UNUSED, IR_UNUSED).if_unobserved;
1706017061

17062+
uint32_t call_num_args = ZEND_FLF_NUM_ARGS(opline->opcode);
17063+
1706117064
// push call frame
17062-
if (GCC_GLOBAL_REGS) {
17063-
// FP register will point to the right place, but zend_frameless_observed_call needs IP to be also pointing to the precise opline.
17064-
ir_ref old_ip = ir_HARD_COPY_A(ir_RLOAD_A(ZREG_IP));
17065-
ir_RSTORE(ZREG_IP, ir_CONST_ADDR(opline));
17066-
ir_CALL(IR_VOID, ir_CONST_ADDR((size_t)zend_frameless_observed_call));
17067-
ir_RSTORE(ZREG_IP, old_ip); // restore it so that further offset calculations are not wrong
17068-
} else {
17069-
ir_CALL_2(IR_VOID, ir_CONST_ADDR((size_t)zend_frameless_observed_call), jit_FP(jit), ir_CONST_ADDR(opline));
17065+
ir_ref call_ref = ir_CALL_4(IR_ADDR, ir_CONST_FC_FUNC(zend_jit_observed_frameless_helper_push),
17066+
jit_FP(jit),
17067+
ir_CONST_U32(zend_vm_calc_used_stack(call_num_args, fbc)),
17068+
ir_CONST_ADDR(fbc),
17069+
ir_CONST_U32(call_num_args));
17070+
17071+
// push all args
17072+
switch (call_num_args) {
17073+
case 3: jit_ZVAL_COPY(jit, ZEND_ADDR_REF_ZVAL(ir_ADD_OFFSET(call_ref, EX_NUM_TO_VAR(2))), MAY_BE_ANY & ~MAY_BE_REF, ZEND_ADDR_REF_ZVAL(op1_data_ref), op1_data_info, 1); ZEND_FALLTHROUGH;
17074+
case 2: jit_ZVAL_COPY(jit, ZEND_ADDR_REF_ZVAL(ir_ADD_OFFSET(call_ref, EX_NUM_TO_VAR(1))), MAY_BE_ANY & ~MAY_BE_REF, ZEND_ADDR_REF_ZVAL(op2_ref), op2_info, 1); ZEND_FALLTHROUGH;
17075+
case 1: jit_ZVAL_COPY(jit, ZEND_ADDR_REF_ZVAL(ir_ADD_OFFSET(call_ref, EX_NUM_TO_VAR(0))), MAY_BE_ANY & ~MAY_BE_REF, ZEND_ADDR_REF_ZVAL(op1_ref), op1_info, 1);
1707017076
}
1707117077

17078+
// call and free args
17079+
ir_CALL_4(IR_VOID, ir_CONST_FC_FUNC(zend_jit_observed_frameless_helper_call),
17080+
call_ref,
17081+
ir_CONST_FC_FUNC(fbc->internal_function.handler),
17082+
observer_handler,
17083+
res_ref);
17084+
1707217085
ir_ref skip = ir_END();
1707317086
ir_IF_TRUE(if_unobserved);
1707417087
return skip;
@@ -17078,18 +17091,16 @@ static void jit_frameless_icall0(zend_jit_ctx *jit, const zend_op *opline)
1707817091
{
1707917092
jit_SET_EX_OPLINE(jit, opline);
1708017093

17081-
ir_ref skip_observer = IR_UNUSED;
17082-
if (ZEND_OBSERVER_ENABLED) {
17083-
skip_observer = jit_frameless_observer(jit, opline);
17084-
}
17085-
1708617094
void *function = ZEND_FLF_HANDLER(opline);
1708717095
zend_jit_addr res_addr = RES_ADDR();
1708817096
ir_ref res_ref = jit_ZVAL_ADDR(jit, res_addr);
1708917097
jit_set_Z_TYPE_INFO(jit, res_addr, IS_NULL);
1709017098

17099+
ir_ref skip_observer = IR_UNUSED;
17100+
if (ZEND_OBSERVER_ENABLED) {
17101+
skip_observer = jit_frameless_observer(jit, opline, IR_UNUSED, 0, IR_UNUSED, 0, IR_UNUSED, 0, res_ref);
17102+
}
1709117103
ir_CALL_1(IR_VOID, ir_CONST_ADDR((size_t)function), res_ref);
17092-
1709317104
if (skip_observer != IR_UNUSED) {
1709417105
ir_MERGE_WITH(skip_observer);
1709517106
}
@@ -17101,11 +17112,6 @@ static void jit_frameless_icall1(zend_jit_ctx *jit, const zend_op *opline, uint3
1710117112
{
1710217113
jit_SET_EX_OPLINE(jit, opline);
1710317114

17104-
ir_ref skip_observer = IR_UNUSED;
17105-
if (ZEND_OBSERVER_ENABLED) {
17106-
skip_observer = jit_frameless_observer(jit, opline);
17107-
}
17108-
1710917115
/* Avoid dropping RC check in case op escapes. */
1711017116
if (op1_info & MAY_BE_RC1) {
1711117117
op1_info |= MAY_BE_RCN;
@@ -17124,26 +17130,24 @@ static void jit_frameless_icall1(zend_jit_ctx *jit, const zend_op *opline, uint3
1712417130
op1_ref = jit_ZVAL_DEREF_ref(jit, op1_ref);
1712517131
}
1712617132

17133+
ir_ref skip_observer = IR_UNUSED;
17134+
if (ZEND_OBSERVER_ENABLED) {
17135+
skip_observer = jit_frameless_observer(jit, opline, op1_ref, op1_info, IR_UNUSED, 0, IR_UNUSED, 0, res_ref);
17136+
}
1712717137
ir_CALL_2(IR_VOID, ir_CONST_ADDR((size_t)function), res_ref, op1_ref);
17128-
17129-
jit_FREE_OP(jit, opline->op1_type, opline->op1, op1_info, NULL);
17130-
1713117138
if (skip_observer != IR_UNUSED) {
1713217139
ir_MERGE_WITH(skip_observer);
1713317140
}
1713417141

17142+
jit_FREE_OP(jit, opline->op1_type, opline->op1, op1_info, NULL);
17143+
1713517144
zend_jit_check_exception(jit);
1713617145
}
1713717146

1713817147
static void jit_frameless_icall2(zend_jit_ctx *jit, const zend_op *opline, uint32_t op1_info, uint32_t op2_info)
1713917148
{
1714017149
jit_SET_EX_OPLINE(jit, opline);
1714117150

17142-
ir_ref skip_observer = IR_UNUSED;
17143-
if (ZEND_OBSERVER_ENABLED) {
17144-
skip_observer = jit_frameless_observer(jit, opline);
17145-
}
17146-
1714717151
/* Avoid dropping RC check in case op escapes. */
1714817152
if (op1_info & MAY_BE_RC1) {
1714917153
op1_info |= MAY_BE_RCN;
@@ -17174,7 +17178,14 @@ static void jit_frameless_icall2(zend_jit_ctx *jit, const zend_op *opline, uint3
1717417178
op2_ref = jit_ZVAL_DEREF_ref(jit, op2_ref);
1717517179
}
1717617180

17181+
ir_ref skip_observer = IR_UNUSED;
17182+
if (ZEND_OBSERVER_ENABLED) {
17183+
skip_observer = jit_frameless_observer(jit, opline, op1_ref, op1_info, op2_ref, op2_info, IR_UNUSED, 0, res_ref);
17184+
}
1717717185
ir_CALL_3(IR_VOID, ir_CONST_ADDR((size_t)function), res_ref, op1_ref, op2_ref);
17186+
if (skip_observer != IR_UNUSED) {
17187+
ir_MERGE_WITH(skip_observer);
17188+
}
1717817189

1717917190
jit_FREE_OP(jit, opline->op1_type, opline->op1, op1_info, NULL);
1718017191
/* Set OP1 to UNDEF in case FREE_OP2() throws. */
@@ -17184,22 +17195,13 @@ static void jit_frameless_icall2(zend_jit_ctx *jit, const zend_op *opline, uint3
1718417195
}
1718517196
jit_FREE_OP(jit, opline->op2_type, opline->op2, op2_info, NULL);
1718617197

17187-
if (skip_observer != IR_UNUSED) {
17188-
ir_MERGE_WITH(skip_observer);
17189-
}
17190-
1719117198
zend_jit_check_exception(jit);
1719217199
}
1719317200

1719417201
static void jit_frameless_icall3(zend_jit_ctx *jit, const zend_op *opline, uint32_t op1_info, uint32_t op2_info, uint32_t op1_data_info)
1719517202
{
1719617203
jit_SET_EX_OPLINE(jit, opline);
1719717204

17198-
ir_ref skip_observer = IR_UNUSED;
17199-
if (ZEND_OBSERVER_ENABLED) {
17200-
skip_observer = jit_frameless_observer(jit, opline);
17201-
}
17202-
1720317205
/* Avoid dropping RC check in case op escapes. */
1720417206
if (op1_info & MAY_BE_RC1) {
1720517207
op1_info |= MAY_BE_RCN;
@@ -17242,7 +17244,14 @@ static void jit_frameless_icall3(zend_jit_ctx *jit, const zend_op *opline, uint3
1724217244
op3_ref = jit_ZVAL_DEREF_ref(jit, op3_ref);
1724317245
}
1724417246

17247+
ir_ref skip_observer = IR_UNUSED;
17248+
if (ZEND_OBSERVER_ENABLED) {
17249+
skip_observer = jit_frameless_observer(jit, opline, op1_ref, op1_info, op2_ref, op2_info, op3_ref, op1_data_info, res_ref);
17250+
}
1724517251
ir_CALL_4(IR_VOID, ir_CONST_ADDR((size_t)function), res_ref, op1_ref, op2_ref, op3_ref);
17252+
if (skip_observer != IR_UNUSED) {
17253+
ir_MERGE_WITH(skip_observer);
17254+
}
1724617255

1724717256
jit_FREE_OP(jit, opline->op1_type, opline->op1, op1_info, NULL);
1724817257
/* Set OP1 to UNDEF in case FREE_OP2() throws. */
@@ -17261,10 +17270,6 @@ static void jit_frameless_icall3(zend_jit_ctx *jit, const zend_op *opline, uint3
1726117270
}
1726217271
jit_FREE_OP(jit, (opline+1)->op1_type, (opline+1)->op1, op1_data_info, NULL);
1726317272

17264-
if (skip_observer != IR_UNUSED) {
17265-
ir_MERGE_WITH(skip_observer);
17266-
}
17267-
1726817273
zend_jit_check_exception(jit);
1726917274
}
1727017275

0 commit comments

Comments
 (0)