Skip to content

Commit 73af6b4

Browse files
author
test@test.test
committed
Revert "Revert JIT changes"
This reverts commit 97cc381.
1 parent 97cc381 commit 73af6b4

File tree

5 files changed

+86
-146
lines changed

5 files changed

+86
-146
lines changed

Zend/zend_execute.c

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

1543-
static zend_always_inline void zend_frameless_observed_call_push(zend_execute_data *call, uint8_t arg, zval *zv, uint8_t op_type) {
1543+
static 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+
15511592
static zend_always_inline int zend_binary_op(zval *ret, zval *op1, zval *op2 OPLINE_DC)
15521593
{
15531594
static const binary_op_type zend_binary_ops[] = {

Zend/zend_vm_def.h

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

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-
}
9606+
zend_frameless_observed_call(EXECUTE_DATA_C OPLINE_CC);
96429607

96439608
if (UNEXPECTED(EG(exception) != NULL)) {
96449609
zend_rethrow_exception(execute_data);

Zend/zend_vm_execute.h

Lines changed: 1 addition & 36 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

ext/opcache/jit/zend_jit_helpers.c

Lines changed: 0 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -3279,29 +3279,3 @@ 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: 42 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -3069,8 +3069,6 @@ 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);
30743072

30753073
#ifndef ZTS
30763074
REGISTER_DATA(EG(current_execute_data));
@@ -17052,36 +17050,25 @@ static bool zend_jit_may_be_in_reg(const zend_op_array *op_array, zend_ssa *ssa,
1705217050
return 1;
1705317051
}
1705417052

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) {
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) {
1705617055
// JIT: zend_observer_handler_is_unobserved(ZEND_OBSERVER_DATA(fbc))
1705717056
ir_ref observer_handler;
1705817057
zend_function *fbc = ZEND_FLF_FUNC(opline);
1705917058
// Not need for runtime cache or generator checks here, we just need if_unobserved
1706017059
ir_ref if_unobserved = jit_observer_fcall_is_unobserved_start(jit, fbc, &observer_handler, IR_UNUSED, IR_UNUSED).if_unobserved;
1706117060

17062-
uint32_t call_num_args = ZEND_FLF_NUM_ARGS(opline->opcode);
17063-
1706417061
// push call frame
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);
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));
1707617070
}
1707717071

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-
1708517072
ir_ref skip = ir_END();
1708617073
ir_IF_TRUE(if_unobserved);
1708717074
return skip;
@@ -17091,16 +17078,18 @@ static void jit_frameless_icall0(zend_jit_ctx *jit, const zend_op *opline)
1709117078
{
1709217079
jit_SET_EX_OPLINE(jit, opline);
1709317080

17081+
ir_ref skip_observer = IR_UNUSED;
17082+
if (ZEND_OBSERVER_ENABLED) {
17083+
skip_observer = jit_frameless_observer(jit, opline);
17084+
}
17085+
1709417086
void *function = ZEND_FLF_HANDLER(opline);
1709517087
zend_jit_addr res_addr = RES_ADDR();
1709617088
ir_ref res_ref = jit_ZVAL_ADDR(jit, res_addr);
1709717089
jit_set_Z_TYPE_INFO(jit, res_addr, IS_NULL);
1709817090

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-
}
1710317091
ir_CALL_1(IR_VOID, ir_CONST_ADDR((size_t)function), res_ref);
17092+
1710417093
if (skip_observer != IR_UNUSED) {
1710517094
ir_MERGE_WITH(skip_observer);
1710617095
}
@@ -17112,6 +17101,11 @@ static void jit_frameless_icall1(zend_jit_ctx *jit, const zend_op *opline, uint3
1711217101
{
1711317102
jit_SET_EX_OPLINE(jit, opline);
1711417103

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

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-
}
1713717127
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+
1713817131
if (skip_observer != IR_UNUSED) {
1713917132
ir_MERGE_WITH(skip_observer);
1714017133
}
1714117134

17142-
jit_FREE_OP(jit, opline->op1_type, opline->op1, op1_info, NULL);
17143-
1714417135
zend_jit_check_exception(jit);
1714517136
}
1714617137

1714717138
static void jit_frameless_icall2(zend_jit_ctx *jit, const zend_op *opline, uint32_t op1_info, uint32_t op2_info)
1714817139
{
1714917140
jit_SET_EX_OPLINE(jit, opline);
1715017141

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

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-
}
1718517177
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-
}
1718917178

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

17187+
if (skip_observer != IR_UNUSED) {
17188+
ir_MERGE_WITH(skip_observer);
17189+
}
17190+
1719817191
zend_jit_check_exception(jit);
1719917192
}
1720017193

1720117194
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)
1720217195
{
1720317196
jit_SET_EX_OPLINE(jit, opline);
1720417197

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

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-
}
1725117245
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-
}
1725517246

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

17264+
if (skip_observer != IR_UNUSED) {
17265+
ir_MERGE_WITH(skip_observer);
17266+
}
17267+
1727317268
zend_jit_check_exception(jit);
1727417269
}
1727517270

0 commit comments

Comments
 (0)