Skip to content

Commit 07ad243

Browse files
committed
Simplify frameless jit handler and fix wordpress issue
1 parent 91873ac commit 07ad243

File tree

1 file changed

+26
-34
lines changed

1 file changed

+26
-34
lines changed

ext/opcache/jit/zend_jit_ir.c

Lines changed: 26 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -16762,38 +16762,37 @@ static bool zend_jit_may_be_in_reg(const zend_op_array *op_array, zend_ssa *ssa,
1676216762
return 1;
1676316763
}
1676416764

16765-
struct jit_frameless_observer_data {
16766-
ir_ref if_unobserved;
16767-
ir_ref reused_jit_ip;
16768-
};
16769-
16770-
static struct jit_frameless_observer_data jit_frameless_observer_begin(zend_jit_ctx *jit, int checked_stack, 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) {
16771-
struct jit_frameless_observer_data data;
16765+
static ir_ref jit_frameless_observer(zend_jit_ctx *jit, int checked_stack, 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, zend_jit_addr res_addr) {
1677216766
// JIT: zend_observer_handler_is_unobserved(ZEND_OBSERVER_DATA(fbc))
1677316767
ir_ref observer_handler;
1677416768
zend_function *fbc = ZEND_FLF_FUNC(opline);
1677516769
// Not need for runtime cache or generator checks here, we just need if_unobserved
16776-
data.if_unobserved = jit_observer_fcall_is_unobserved_start(jit, fbc, &observer_handler, IR_UNUSED, IR_UNUSED).if_unobserved;
16770+
ir_ref if_unobserved = jit_observer_fcall_is_unobserved_start(jit, fbc, &observer_handler, IR_UNUSED, IR_UNUSED).if_unobserved;
1677716771

16778-
// push args to a valid call frame, without copying
16772+
// push args to a valid call frame, without copying (flf call takes care of freeing args)
1677916773
bool track_last_valid_opline = jit->track_last_valid_opline;
16774+
bool use_last_valid_opline = jit->use_last_valid_opline;
1678016775
const zend_op *last_valid_opline = jit->last_valid_opline;
1678116776
bool reuse_ip = jit->reuse_ip;
1678216777
if (reuse_ip) {
16783-
data.reused_jit_ip = jit_IP(jit);
16778+
ir_ref call = jit_CALL(jit_FP(jit), call);
16779+
ir_STORE(jit_CALL(jit_IP(jit), prev_execute_data), call);
16780+
ir_STORE(call, jit_IP(jit));
1678416781
}
1678516782
zend_jit_push_call_frame(jit, opline, NULL, fbc, 0, 0, checked_stack, ir_CONST_ADDR(fbc), IR_NULL);
16786-
// yes, we'll temporarily reuse the IP, but we don't want to handle this via the reuse_ip mechanism for simiplicity - we just reset IP to original in end
16783+
// yes, we'll temporarily reuse the IP, but we must not handle this via the reuse_ip mechanism - we just reset IP to original in end
16784+
// the primary issue here is that this code is just executed conditionally while the reuse mechanisms are meant to be global
1678716785
jit->track_last_valid_opline = track_last_valid_opline;
16786+
jit->use_last_valid_opline = use_last_valid_opline;
1678816787
jit->last_valid_opline = last_valid_opline;
1678916788
jit->reuse_ip = reuse_ip;
1679016789

1679116790
// push all args
1679216791
uint32_t call_num_args = ZEND_FLF_NUM_ARGS(opline->opcode);
1679316792
switch (call_num_args) {
16794-
case 3: jit_ZVAL_COPY(jit, ZEND_ADDR_MEM_ZVAL(ZREG_RX, EX_NUM_TO_VAR(3)), MAY_BE_ANY & ~MAY_BE_REF, ZEND_ADDR_REF_ZVAL(op1_data_ref), op1_data_info, 0); ZEND_FALLTHROUGH;
16795-
case 2: jit_ZVAL_COPY(jit, ZEND_ADDR_MEM_ZVAL(ZREG_RX, EX_NUM_TO_VAR(2)), MAY_BE_ANY & ~MAY_BE_REF, ZEND_ADDR_REF_ZVAL(op2_ref), op2_info, 0); ZEND_FALLTHROUGH;
16796-
case 1: jit_ZVAL_COPY(jit, ZEND_ADDR_MEM_ZVAL(ZREG_RX, EX_NUM_TO_VAR(1)), MAY_BE_ANY & ~MAY_BE_REF, ZEND_ADDR_REF_ZVAL(op1_ref), op1_info, 0);
16793+
case 3: jit_ZVAL_COPY(jit, ZEND_ADDR_MEM_ZVAL(ZREG_RX, EX_NUM_TO_VAR(2)), MAY_BE_ANY & ~MAY_BE_REF, ZEND_ADDR_REF_ZVAL(op1_data_ref), op1_data_info, 0); ZEND_FALLTHROUGH;
16794+
case 2: jit_ZVAL_COPY(jit, ZEND_ADDR_MEM_ZVAL(ZREG_RX, EX_NUM_TO_VAR(1)), MAY_BE_ANY & ~MAY_BE_REF, ZEND_ADDR_REF_ZVAL(op2_ref), op2_info, 0); ZEND_FALLTHROUGH;
16795+
case 1: jit_ZVAL_COPY(jit, ZEND_ADDR_MEM_ZVAL(ZREG_RX, EX_NUM_TO_VAR(0)), MAY_BE_ANY & ~MAY_BE_REF, ZEND_ADDR_REF_ZVAL(op1_ref), op1_info, 0);
1679716796
}
1679816797

1679916798
// Make call frame externally visible
@@ -16803,11 +16802,10 @@ static struct jit_frameless_observer_data jit_frameless_observer_begin(zend_jit_
1680316802

1680416803
jit_observer_fcall_begin(jit, rx, observer_handler);
1680516804

16806-
return data;
16807-
}
16805+
// JIT: fbc->internal_function.handler(new_frame, return_value)
16806+
ir_ref res_ref = jit_ZVAL_ADDR(jit, res_addr);
16807+
ir_CALL_2(IR_VOID, ir_CONST_ADDR((size_t)fbc->internal_function.handler), rx, res_ref);
1680816808

16809-
static ir_ref jit_frameless_observer_end(zend_jit_ctx *jit, struct jit_frameless_observer_data *data, const zend_op *opline, zend_jit_addr res_addr) {
16810-
ir_ref rx = jit_IP(jit);
1681116809
jit_observer_fcall_end(jit, rx, res_addr);
1681216810

1681316811
ir_STORE(jit_EG(current_execute_data), ir_LOAD_A(jit_CALL(rx, prev_execute_data)));
@@ -16837,14 +16835,16 @@ static ir_ref jit_frameless_observer_end(zend_jit_ctx *jit, struct jit_frameless
1683716835
ir_MERGE_WITH(allocated_path);
1683816836
}
1683916837

16840-
if (jit->reuse_ip) {
16841-
jit_STORE_IP(jit, data->reused_jit_ip);
16838+
if (reuse_ip) {
16839+
jit_STORE_IP(jit, ir_LOAD_A(jit_CALL(jit_FP(jit), call)));
16840+
ir_STORE(jit_CALL(jit_FP(jit), call), jit_CALL(jit_IP(jit), prev_execute_data));
1684216841
} else {
16843-
jit_SET_EX_OPLINE(jit, opline);
16842+
// Note: conditional (if_unobserved) opline, zend_jit_set_last_valid_opline() may only be called if the opline is actually unconditionally updated
16843+
jit_STORE_IP(jit, ir_CONST_ADDR(jit->last_valid_opline ? jit->last_valid_opline : opline));
1684416844
}
1684516845

1684616846
ir_ref skip = ir_END();
16847-
ir_IF_TRUE(data->if_unobserved);
16847+
ir_IF_TRUE(if_unobserved);
1684816848
return skip;
1684916849
}
1685016850

@@ -16859,9 +16859,7 @@ static void jit_frameless_icall0(zend_jit_ctx *jit, int checked_stack, const zen
1685916859

1686016860
ir_ref skip_observer = IR_UNUSED;
1686116861
if (ZEND_OBSERVER_ENABLED) {
16862-
struct jit_frameless_observer_data observer_data = jit_frameless_observer_begin(jit, checked_stack, opline, IR_UNUSED, 0, IR_UNUSED, 0, IR_UNUSED, 0);
16863-
ir_CALL_1(IR_VOID, ir_CONST_ADDR((size_t)function), res_ref);
16864-
skip_observer = jit_frameless_observer_end(jit, &observer_data, opline, res_addr);
16862+
skip_observer = jit_frameless_observer(jit, checked_stack, opline, IR_UNUSED, 0, IR_UNUSED, 0, IR_UNUSED, 0, res_addr);
1686516863
}
1686616864
ir_CALL_1(IR_VOID, ir_CONST_ADDR((size_t)function), res_ref);
1686716865
if (skip_observer != IR_UNUSED) {
@@ -16895,9 +16893,7 @@ static void jit_frameless_icall1(zend_jit_ctx *jit, int checked_stack, const zen
1689516893

1689616894
ir_ref skip_observer = IR_UNUSED;
1689716895
if (ZEND_OBSERVER_ENABLED) {
16898-
struct jit_frameless_observer_data observer_data = jit_frameless_observer_begin(jit, checked_stack, opline, op1_ref, op1_info, IR_UNUSED, 0, IR_UNUSED, 0);
16899-
ir_CALL_2(IR_VOID, ir_CONST_ADDR((size_t)function), res_ref, op1_ref);
16900-
skip_observer = jit_frameless_observer_end(jit, &observer_data, opline, res_addr);
16896+
skip_observer = jit_frameless_observer(jit, checked_stack, opline, op1_ref, op1_info, IR_UNUSED, 0, IR_UNUSED, 0, res_addr);
1690116897
}
1690216898
ir_CALL_2(IR_VOID, ir_CONST_ADDR((size_t)function), res_ref, op1_ref);
1690316899
if (skip_observer != IR_UNUSED) {
@@ -16944,9 +16940,7 @@ static void jit_frameless_icall2(zend_jit_ctx *jit, int checked_stack, const zen
1694416940

1694516941
ir_ref skip_observer = IR_UNUSED;
1694616942
if (ZEND_OBSERVER_ENABLED) {
16947-
struct jit_frameless_observer_data observer_data = jit_frameless_observer_begin(jit, checked_stack, opline, op1_ref, op1_info, op2_ref, op2_info, IR_UNUSED, 0);
16948-
ir_CALL_3(IR_VOID, ir_CONST_ADDR((size_t)function), res_ref, op1_ref, op2_ref);
16949-
skip_observer = jit_frameless_observer_end(jit, &observer_data, opline, res_addr);
16943+
skip_observer = jit_frameless_observer(jit, checked_stack, opline, op1_ref, op1_info, op2_ref, op2_info, IR_UNUSED, 0, res_addr);
1695016944
}
1695116945
ir_CALL_3(IR_VOID, ir_CONST_ADDR((size_t)function), res_ref, op1_ref, op2_ref);
1695216946
if (skip_observer != IR_UNUSED) {
@@ -17011,9 +17005,7 @@ static void jit_frameless_icall3(zend_jit_ctx *jit, int checked_stack, const zen
1701117005

1701217006
ir_ref skip_observer = IR_UNUSED;
1701317007
if (ZEND_OBSERVER_ENABLED) {
17014-
struct jit_frameless_observer_data observer_data = jit_frameless_observer_begin(jit, checked_stack, opline, op1_ref, op1_info, op2_ref, op2_info, op3_ref, op1_data_info);
17015-
ir_CALL_4(IR_VOID, ir_CONST_ADDR((size_t)function), res_ref, op1_ref, op2_ref, op3_ref);
17016-
skip_observer = jit_frameless_observer_end(jit, &observer_data, opline, res_addr);
17008+
skip_observer = jit_frameless_observer(jit, checked_stack, opline, op1_ref, op1_info, op2_ref, op2_info, op3_ref, op1_data_info, res_addr);
1701717009
}
1701817010
ir_CALL_4(IR_VOID, ir_CONST_ADDR((size_t)function), res_ref, op1_ref, op2_ref, op3_ref);
1701917011
if (skip_observer != IR_UNUSED) {

0 commit comments

Comments
 (0)