Skip to content

Commit ba54bd0

Browse files
shqkingdstogov
authored andcommitted
Support failed JIT test case: fetch_obj_002.phpt
One new path is covered inside function zend_jit_fetch_obj() due to the use of FETCH_OBJ_R opcode. Note that function zend_jit_zval_copy_deref() is invoked along this new path. Updates in function zend_jit_free() are made to support FREE opcode. Stub function zend_jit_leave_function_stub() is touched for the first time.
1 parent fe94eb4 commit ba54bd0

File tree

1 file changed

+99
-7
lines changed

1 file changed

+99
-7
lines changed

ext/opcache/jit/zend_jit_arm64.dasc

Lines changed: 99 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -453,7 +453,7 @@ static void* dasm_labels[zend_lb_MAX];
453453
|.endmacro
454454

455455
|.macro GET_Z_TYPE_INFO, reg, zv
456-
| mov reg, dword [zv+offsetof(zval,u1.type_info)]
456+
| ldr reg, [zv, #offsetof(zval,u1.type_info)]
457457
|.endmacro
458458

459459
|.macro SET_Z_TYPE_INFO, zv, type, tmp_reg
@@ -826,7 +826,8 @@ static void* dasm_labels[zend_lb_MAX];
826826
|.endmacro
827827

828828
|.macro IF_UNDEF, type_reg, label
829-
| brk #0 // TODO
829+
| tst type_reg, type_reg
830+
| beq label
830831
|.endmacro
831832

832833
|.macro IF_TYPE, type, val, label
@@ -1031,7 +1032,6 @@ static void* dasm_labels[zend_lb_MAX];
10311032
|.cold_code
10321033
|1:
10331034
|| } else {
1034-
| brk #0 // TODO: test.
10351035
| IF_NOT_ZVAL_REFCOUNTED addr, >4, Rw(tmp_reg1), Rx(tmp_reg2)
10361036
|| }
10371037
|| }
@@ -1338,7 +1338,35 @@ static int zend_jit_exception_handler_undef_stub(dasm_State **Dst)
13381338
static int zend_jit_leave_function_stub(dasm_State **Dst)
13391339
{
13401340
|->leave_function_handler:
1341-
| brk #0 // TODO: test
1341+
if (zend_jit_vm_kind == ZEND_VM_KIND_HYBRID) {
1342+
| LOAD_32BIT_VAL TMP1w, ZEND_CALL_TOP
1343+
| tst FCARG1w, TMP1w
1344+
| bne >1
1345+
| brk #0 // TODO: currently jump to label 1.
1346+
| EXT_CALL zend_jit_leave_nested_func_helper, REG0
1347+
| ADD_HYBRID_SPAD
1348+
| JMP_IP TMP1
1349+
|1:
1350+
| EXT_CALL zend_jit_leave_top_func_helper, REG0
1351+
| ADD_HYBRID_SPAD
1352+
| JMP_IP TMP1
1353+
} else {
1354+
if (GCC_GLOBAL_REGS) {
1355+
| add sp, sp, SPAD
1356+
} else {
1357+
| mov FCARG2x, FP
1358+
| ldp FP, RX, T2 // retore FP and IP
1359+
| ldr LR, T4 // retore LR
1360+
| add sp, sp, NR_SPAD
1361+
}
1362+
| LOAD_32BIT_VAL TMP1w, ZEND_CALL_TOP
1363+
| tst FCARG1w, TMP1w
1364+
| bne >1
1365+
| brk #0 // TODO: currently jump to label 1.
1366+
| EXT_JMP zend_jit_leave_nested_func_helper, REG0
1367+
|1:
1368+
| EXT_JMP zend_jit_leave_top_func_helper, REG0
1369+
}
13421370

13431371
return 1;
13441372
}
@@ -6193,7 +6221,23 @@ static int zend_jit_zval_copy_deref(dasm_State **Dst, zend_jit_addr res_addr, ze
61936221
{
61946222
ZEND_ASSERT(type_reg == ZREG_REG2);
61956223

6196-
| brk #0 // TODO
6224+
| GET_ZVAL_PTR REG1, val_addr, TMP1
6225+
| lsr TMP1w, REG2w, #8
6226+
| and TMP1w, TMP1w, #0xff // TMP1w -> 8-15 bits of REG2w
6227+
| IF_NOT_REFCOUNTED TMP1w, >2
6228+
| brk #0 // TODO: currently jump to label 2 directly.
6229+
| and TMP2w, REG2w, #0xff // TMP2w -> low 8 bits of REG2w
6230+
| IF_NOT_TYPE TMP2w, IS_REFERENCE, >1
6231+
| add TMP3, REG1, #offsetof(zend_reference, val)
6232+
| GET_Z_TYPE_INFO REG2w, TMP3
6233+
| GET_Z_PTR REG1, TMP3
6234+
| IF_NOT_REFCOUNTED TMP1w, >2
6235+
|1:
6236+
| GC_ADDREF REG1, TMP1w
6237+
|2:
6238+
| SET_ZVAL_PTR res_addr, REG1, TMP1
6239+
| SET_ZVAL_TYPE_INFO_FROM_REG res_addr, REG2, TMP1
6240+
61976241
return 1;
61986242
}
61996243

@@ -6899,7 +6943,30 @@ static int zend_jit_fetch_obj(dasm_State **Dst,
68996943
}
69006944
} else {
69016945
prop_addr = ZEND_ADDR_MEM_ZVAL(ZREG_FCARG1x, prop_info->offset);
6902-
| brk #0 // TODO
6946+
| LOAD_32BIT_VAL TMP1w, (prop_info->offset + 8)
6947+
| ldr REG2w, [FCARG1x, TMP1]
6948+
if (JIT_G(trigger) == ZEND_JIT_ON_HOT_TRACE) {
6949+
if (opline->opcode == ZEND_FETCH_OBJ_W || !(res_info & MAY_BE_GUARD) || !JIT_G(current_frame)) {
6950+
/* perform IS_UNDEF check only after result type guard (during deoptimization) */
6951+
int32_t exit_point = zend_jit_trace_get_exit_point(opline, ZEND_JIT_EXIT_TO_VM);
6952+
const void *exit_addr = zend_jit_trace_get_exit_addr(exit_point);
6953+
6954+
if (!exit_addr) {
6955+
return 0;
6956+
}
6957+
| brk #0 // TODO
6958+
}
6959+
} else {
6960+
| and TMP1w, REG2w, #0xff // low 8 bits. 8-15 bits are used later in zend_jit_zval_copy_deref().
6961+
| IF_UNDEF TMP1w, >5
6962+
}
6963+
if (opline->opcode == ZEND_FETCH_OBJ_W
6964+
&& (opline->extended_value & ZEND_FETCH_OBJ_FLAGS)
6965+
&& ZEND_TYPE_IS_SET(prop_info->type)) {
6966+
uint32_t flags = opline->extended_value & ZEND_FETCH_OBJ_FLAGS;
6967+
6968+
| brk #0 // TODO
6969+
}
69036970
}
69046971
if (op1_avoid_refcounting) {
69056972
SET_STACK_REG(JIT_G(current_frame)->stack,
@@ -7266,7 +7333,32 @@ static int zend_jit_free(dasm_State **Dst, const zend_op *opline, uint32_t op1_i
72667333
{
72677334
zend_jit_addr op1_addr = OP1_ADDR();
72687335

7269-
| brk #0 // TODO
7336+
if (op1_info & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT|MAY_BE_RESOURCE|MAY_BE_REF)) {
7337+
if (may_throw) {
7338+
| brk #0 // TODO
7339+
| SET_EX_OPLINE opline, REG0
7340+
}
7341+
if (opline->opcode == ZEND_FE_FREE && (op1_info & (MAY_BE_OBJECT|MAY_BE_REF))) {
7342+
if (op1_info & MAY_BE_ARRAY) {
7343+
| brk #0 // TODO
7344+
| IF_ZVAL_TYPE op1_addr, IS_ARRAY, >7, TMP1w, TMP2
7345+
}
7346+
| brk #0 // TODO
7347+
| LOAD_32BIT_VAL TMP1w, opline->op1.var + offsetof(zval, u2.fe_iter_idx)
7348+
| ldr FCARG1w, [FP, TMP1]
7349+
| LOAD_32BIT_VAL TMP1w, -1
7350+
| cmp FCARG1w, TMP1w
7351+
| beq >7
7352+
| EXT_CALL zend_hash_iterator_del, REG0
7353+
|7:
7354+
}
7355+
| ZVAL_PTR_DTOR op1_addr, op1_info, 0, 0, opline, ZREG_TMP1, ZREG_TMP2
7356+
if (may_throw) {
7357+
if (!zend_jit_check_exception(Dst)) {
7358+
return 0;
7359+
}
7360+
}
7361+
}
72707362
return 1;
72717363
}
72727364

0 commit comments

Comments
 (0)