Skip to content

Commit 7676236

Browse files
shqkingdstogov
authored andcommitted
Support failed JIT test case: assign_dim_002.phpt
There are 6 user function calls in this test cases. The first 3 functions, i.e. foo(), foo1() and foo2(), can be supported already. In this patch, we mainly focus on foo3(). Note that based on my test, once foo3() gets supported, the remaining functions foo4() and foo5() can pass as well. Regarding function foo3(), we mainly focus on statement "$array = new ArrayObject();", and the following two opcodes are involved. 0009 V2 = NEW 0 string("ArrayObject") 0010 DO_FCALL Accordingly, functions zend_jit_handler(), zend_jit_cond_jmp() and zend_jit_do_fcall() are invoked to generate the machine code. See the handling process for case ZEND_NEW at file zend_jit.c. Hence, major changes in this patch are made to support this statement. Note that the updates at line 4840 in function zend_jit_do_fcall() are made to support the later internal function call, i.e. var_dump(). Note that another test "noval_001.phpt" would pass with this patch as well.
1 parent 5a39ff2 commit 7676236

File tree

1 file changed

+81
-11
lines changed

1 file changed

+81
-11
lines changed

ext/opcache/jit/zend_jit_arm64.dasc

Lines changed: 81 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -422,8 +422,14 @@ static void* dasm_labels[zend_lb_MAX];
422422
|| }
423423
|.endmacro
424424

425-
|.macro CMP_IP, addr
426-
| brk #0 // TODO
425+
|.macro CMP_IP, addr, tmp_reg1, tmp_reg2
426+
| LOAD_ADDR tmp_reg1, addr
427+
|| if (GCC_GLOBAL_REGS) {
428+
| cmp IP, tmp_reg1
429+
|| } else {
430+
| ldr tmp_reg2, EX->opline
431+
| cmp tmp_reg2, tmp_reg1
432+
|| }
427433
|.endmacro
428434

429435
|.macro LOAD_ZVAL_ADDR, reg, addr
@@ -1128,8 +1134,24 @@ static void* dasm_labels[zend_lb_MAX];
11281134
| brk #0 // TODO
11291135
|.endmacro
11301136

1131-
|.macro OBJ_RELEASE, reg, exit_label
1137+
|.macro OBJ_RELEASE, reg, exit_label, tmp_reg1, tmp_reg2
1138+
| GC_DELREF Rx(reg), Rw(tmp_reg1)
1139+
| bne >1
11321140
| brk #0 // TODO
1141+
| // zend_objects_store_del(obj);
1142+
|| if (reg != ZREG_FCARG1x) {
1143+
| mov FCARG1x, Rx(reg)
1144+
|| }
1145+
| EXT_CALL zend_objects_store_del, Rx(tmp_reg1)
1146+
| b exit_label
1147+
|1:
1148+
| IF_GC_MAY_NOT_LEAK Rx(reg), >1, Rw(tmp_reg1), Rw(tmp_reg2)
1149+
| // gc_possible_root(obj)
1150+
|| if (reg != ZREG_FCARG1x) {
1151+
| mov FCARG1x, Rx(reg)
1152+
|| }
1153+
| EXT_CALL gc_possible_root, Rx(tmp_reg1)
1154+
|1:
11331155
|.endmacro
11341156

11351157
|.macro UNDEFINED_OFFSET, opline
@@ -2068,7 +2090,6 @@ static int zend_jit_save_call_chain(dasm_State **Dst, uint32_t call_level)
20682090
if (call_level == 1) {
20692091
| str xzr, EX:RX->prev_execute_data
20702092
} else {
2071-
| brk #0 // TODO: test
20722093
| ldr REG0, EX->call
20732094
| str REG0, EX:RX->prev_execute_data
20742095
}
@@ -2430,7 +2451,8 @@ static int zend_jit_jmp(dasm_State **Dst, unsigned int target_label)
24302451

24312452
static int zend_jit_cond_jmp(dasm_State **Dst, const zend_op *next_opline, unsigned int target_label)
24322453
{
2433-
| brk #0 // TODO
2454+
| CMP_IP next_opline, TMP1, TMP2
2455+
| bne =>target_label
24342456

24352457
zend_jit_set_last_valid_opline(next_opline);
24362458

@@ -4799,15 +4821,26 @@ static int zend_jit_do_fcall(dasm_State **Dst, const zend_op *opline, const zend
47994821
| SET_EX_OPLINE opline, REG0
48004822

48014823
if (opline->opcode == ZEND_DO_FCALL) {
4802-
| brk #0 // TODO
4824+
if (!func) {
4825+
if (trace) {
4826+
uint32_t exit_point = zend_jit_trace_get_exit_point(opline, ZEND_JIT_EXIT_TO_VM);
4827+
4828+
exit_addr = zend_jit_trace_get_exit_addr(exit_point);
4829+
if (!exit_addr) {
4830+
return 0;
4831+
}
4832+
| brk #0 // TODO
4833+
}
4834+
}
48034835
}
48044836

48054837
if (!delayed_call_chain) {
48064838
if (call_level == 1) {
48074839
| str xzr, EX->call
48084840
} else {
48094841
| //EX(call) = call->prev_execute_data;
4810-
| brk #0 // TODO: test
4842+
| ldr REG0, EX:RX->prev_execute_data
4843+
| str REG0, EX->call
48114844
}
48124845
}
48134846
delayed_call_chain = 0;
@@ -4820,13 +4853,38 @@ static int zend_jit_do_fcall(dasm_State **Dst, const zend_op *opline, const zend
48204853
}
48214854

48224855
if (opline->opcode == ZEND_DO_FCALL) {
4823-
| brk #0 // TODO
4856+
if (!func) {
4857+
if (!trace) {
4858+
| ldr TMP1w, [REG0, #offsetof(zend_op_array, fn_flags)]
4859+
|| ZEND_ASSERT(ZEND_ACC_DEPRECATED <= MAX_IMM12);
4860+
| tst TMP1w, #ZEND_ACC_DEPRECATED
4861+
| bne >1
4862+
|.cold_code
4863+
|1:
4864+
| brk #0 // TODO
4865+
if (!GCC_GLOBAL_REGS) {
4866+
| mov FCARG1x, RX
4867+
}
4868+
| EXT_CALL zend_jit_deprecated_helper, REG0
4869+
| and RETVALw, RETVALw, #0xff
4870+
| cmp RETVALw, #0 // Result is 0 on exception
4871+
| ldr REG0, EX:RX->func // reload
4872+
| bne >1
4873+
| b ->exception_handler
4874+
|.code
4875+
|1:
4876+
}
4877+
} else if (func->common.fn_flags & ZEND_ACC_DEPRECATED) {
4878+
| brk #0
4879+
}
48244880
}
48254881

48264882
if (!func
48274883
&& opline->opcode != ZEND_DO_UCALL
48284884
&& opline->opcode != ZEND_DO_ICALL) {
4829-
| brk #0 // TODO
4885+
| ldrb TMP1w, [REG0, #offsetof(zend_function, type)]
4886+
| cmp TMP1w, #ZEND_USER_FUNCTION
4887+
| bne >8
48304888
}
48314889

48324890
if ((!func || func->type == ZEND_USER_FUNCTION)
@@ -5022,7 +5080,19 @@ static int zend_jit_do_fcall(dasm_State **Dst, const zend_op *opline, const zend
50225080
|8:
50235081
if (opline->opcode == ZEND_DO_FCALL) {
50245082
// TODO: optimize ???
5025-
| brk #0 // TODO
5083+
| // if (UNEXPECTED(ZEND_CALL_INFO(call) & ZEND_CALL_RELEASE_THIS))
5084+
| ldrb TMP1w, [RX, #(offsetof(zend_execute_data, This.u1.type_info) + 2)]
5085+
| tst TMP1w, #(ZEND_CALL_RELEASE_THIS >> 16)
5086+
| bne >1
5087+
|.cold_code
5088+
|1:
5089+
| add TMP1, RX, #offsetof(zend_execute_data, This)
5090+
| GET_Z_PTR FCARG1x, TMP1
5091+
| // OBJ_RELEASE(object);
5092+
| OBJ_RELEASE ZREG_FCARG1x, >2, ZREG_TMP1, ZREG_TMP2
5093+
| b >2
5094+
|.code
5095+
|2:
50265096
}
50275097

50285098
if (JIT_G(trigger) != ZEND_JIT_ON_HOT_TRACE ||
@@ -5084,7 +5154,7 @@ static int zend_jit_do_fcall(dasm_State **Dst, const zend_op *opline, const zend
50845154
}
50855155

50865156
if ((!trace || !func) && opline->opcode != ZEND_DO_ICALL) {
5087-
| brk #0 // TODO
5157+
| LOAD_IP_ADDR (opline + 1)
50885158
} else if (trace
50895159
&& trace->op == ZEND_JIT_TRACE_END
50905160
&& trace->stop == ZEND_JIT_TRACE_STOP_INTERPRETER) {

0 commit comments

Comments
 (0)