Skip to content

Commit 5538a4c

Browse files
shqkingdstogov
authored andcommitted
Support failed JIT test case: assign_025.phpt
Major changes are: 1. Support opcode FETCH_DIM_W for "$arr[0][0] = $ref;" in the loop. See the updates in function zend_jit_fetch_dim(). 2. Spill the registers and store the values into memory. See the updates in function zend_jit_spill_store(). This is done for Phi function. 3. Invoke function zend_array_destory() as dtor for arrays. This is done by zend_jit_free_cv() when leaving the function foo().
1 parent d7ae4d0 commit 5538a4c

File tree

1 file changed

+153
-7
lines changed

1 file changed

+153
-7
lines changed

ext/opcache/jit/zend_jit_arm64.dasc

Lines changed: 153 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -999,7 +999,7 @@ static void* dasm_labels[zend_lb_MAX];
999999
|| if (opline && ((var_info) & (MAY_BE_ARRAY_OF_ARRAY|MAY_BE_ARRAY_OF_OBJECT|MAY_BE_ARRAY_OF_RESOURCE|MAY_BE_ARRAY_OF_REF))) {
10001000
| brk #0 // TODO
10011001
|| }
1002-
| brk #0 // TODO
1002+
| EXT_CALL zend_array_destroy, tmp_reg
10031003
|| } else {
10041004
| EXT_CALL zend_jit_array_free, tmp_reg
10051005
|| }
@@ -1114,7 +1114,6 @@ static void* dasm_labels[zend_lb_MAX];
11141114
|2:
11151115
|| }
11161116
|| } else {
1117-
| brk #0 // TODO
11181117
| GET_ZVAL_LVAL ZREG_FCARG1x, addr, Rx(tmp_reg1)
11191118
|| }
11201119
|.endmacro
@@ -2462,7 +2461,16 @@ static int zend_jit_spill_store(dasm_State **Dst, zend_jit_addr src, zend_jit_ad
24622461
ZEND_ASSERT(Z_MODE(src) == IS_REG);
24632462
ZEND_ASSERT(Z_MODE(dst) == IS_MEM_ZVAL);
24642463

2465-
| brk #0 // TODO
2464+
if ((info & MAY_BE_ANY) == MAY_BE_LONG) {
2465+
| SET_ZVAL_LVAL_FROM_REG dst, Rx(Z_REG(src)), TMP1
2466+
if (set_type) {
2467+
| SET_ZVAL_TYPE_INFO dst, IS_LONG, TMP1w, TMP2
2468+
}
2469+
} else if ((info & MAY_BE_ANY) == MAY_BE_DOUBLE) {
2470+
| brk #0 // TODO
2471+
} else {
2472+
ZEND_UNREACHABLE();
2473+
}
24662474
return 1;
24672475
}
24682476

@@ -2527,7 +2535,25 @@ static int zend_jit_load_var(dasm_State **Dst, uint32_t info, int var, zend_reg
25272535
static int zend_jit_update_regs(dasm_State **Dst, uint32_t var, zend_jit_addr src, zend_jit_addr dst, uint32_t info)
25282536
{
25292537
if (!zend_jit_same_addr(src, dst)) {
2530-
| brk #0 // TODO: test
2538+
if (Z_MODE(src) == IS_REG) {
2539+
if (Z_MODE(dst) == IS_REG) {
2540+
| brk #0 // TODO
2541+
} else if (Z_MODE(dst) == IS_MEM_ZVAL) {
2542+
| brk #0 // TODO
2543+
} else {
2544+
ZEND_UNREACHABLE();
2545+
}
2546+
} else if (Z_MODE(src) == IS_MEM_ZVAL) {
2547+
if (Z_MODE(dst) == IS_REG) {
2548+
if (!zend_jit_load_reg(Dst, src, dst, info)) {
2549+
return 0;
2550+
}
2551+
} else {
2552+
ZEND_UNREACHABLE();
2553+
}
2554+
} else {
2555+
ZEND_UNREACHABLE();
2556+
}
25312557
}
25322558
return 1;
25332559
}
@@ -3205,7 +3231,10 @@ static int zend_jit_fetch_dimension_address_inner(dasm_State **Dst, const zend_o
32053231
if (packed_loaded) {
32063232
| // ZEND_HASH_INDEX_FIND(ht, hval, retval, num_undef);
32073233
if (op1_info & MAY_BE_ARRAY_HASH) {
3208-
| brk #0 // TODO
3234+
|| ZEND_ASSERT(HASH_FLAG_PACKED <= MAX_IMM12);
3235+
| ldr TMP1w, [FCARG1x, #offsetof(zend_array, u.flags)]
3236+
| tst TMP1w, #HASH_FLAG_PACKED
3237+
| beq >4 // HASH_FIND
32093238
}
32103239
| // if (EXPECTED((zend_ulong)(_h) < (zend_ulong)(_ht)->nNumUsed))
32113240

@@ -3265,7 +3294,24 @@ static int zend_jit_fetch_dimension_address_inner(dasm_State **Dst, const zend_o
32653294
if (packed_loaded) {
32663295
| IF_NOT_Z_TYPE REG0, IS_UNDEF, >8, TMP1w
32673296
}
3268-
| brk #0 // TODO
3297+
if (!(op1_info & MAY_BE_ARRAY_KEY_LONG) || packed_loaded) {
3298+
|2:
3299+
| //retval = zend_hash_index_add_new(ht, hval, &EG(uninitialized_zval));
3300+
if (!op2_loaded) {
3301+
| // hval = Z_LVAL_P(dim);
3302+
| brk #0 // TODO
3303+
| GET_ZVAL_LVAL ZREG_FCARG2x, op2_addr, TMP1
3304+
}
3305+
| LOAD_ADDR_ZTS CARG3, executor_globals, uninitialized_zval
3306+
| EXT_CALL zend_hash_index_add_new, REG0
3307+
| mov REG0, RETVALx
3308+
if (op1_info & MAY_BE_ARRAY_HASH) {
3309+
| brk #0 // TODO
3310+
}
3311+
}
3312+
if (op1_info & MAY_BE_ARRAY_HASH) {
3313+
| brk #0 // TODO
3314+
}
32693315
break;
32703316
default:
32713317
ZEND_UNREACHABLE();
@@ -5649,7 +5695,107 @@ static int zend_jit_fetch_dim(dasm_State **Dst,
56495695

56505696
op2_addr = (opline->op2_type != IS_UNUSED) ? OP2_ADDR() : 0;
56515697

5652-
| brk #0 // TODO
5698+
if (op1_info & MAY_BE_REF) {
5699+
| brk #0 // TODO
5700+
}
5701+
5702+
if (op1_info & MAY_BE_ARRAY) {
5703+
if (op1_info & ((MAY_BE_ANY|MAY_BE_UNDEF) - MAY_BE_ARRAY)) {
5704+
| IF_NOT_ZVAL_TYPE op1_addr, IS_ARRAY, >7, TMP1w, TMP2
5705+
}
5706+
|3:
5707+
| SEPARATE_ARRAY op1_addr, op1_info, 1, ZREG_TMP1, ZREG_TMP2
5708+
}
5709+
if (op1_info & (MAY_BE_UNDEF|MAY_BE_NULL|MAY_BE_FALSE)) {
5710+
if (op1_info & MAY_BE_ARRAY) {
5711+
|.cold_code
5712+
|7:
5713+
}
5714+
if (op1_info & (MAY_BE_ANY-(MAY_BE_NULL|MAY_BE_FALSE|MAY_BE_ARRAY))) {
5715+
| brk #0 // TODO
5716+
}
5717+
if ((op1_info & MAY_BE_UNDEF)
5718+
&& opline->opcode == ZEND_FETCH_DIM_RW) {
5719+
| brk #0 // TODO
5720+
}
5721+
| // ZVAL_ARR(container, zend_new_array(8));
5722+
if (Z_REG(op1_addr) != ZREG_FP) {
5723+
| brk #0 // TODO
5724+
}
5725+
| EXT_CALL _zend_new_array_0, REG0
5726+
| mov REG0, RETVALx
5727+
if (Z_REG(op1_addr) != ZREG_FP) {
5728+
| brk #0 // TODO
5729+
}
5730+
| SET_ZVAL_LVAL_FROM_REG op1_addr, REG0, TMP1
5731+
| SET_ZVAL_TYPE_INFO op1_addr, IS_ARRAY_EX, TMP1w, TMP2
5732+
| mov FCARG1x, REG0
5733+
if (op1_info & MAY_BE_ARRAY) {
5734+
| brk #0 // TODO
5735+
| b >1
5736+
|.code
5737+
|1:
5738+
}
5739+
}
5740+
5741+
if (op1_info & (MAY_BE_UNDEF|MAY_BE_NULL|MAY_BE_FALSE|MAY_BE_ARRAY)) {
5742+
|6:
5743+
if (opline->op2_type == IS_UNUSED) {
5744+
| brk #0 // TODO
5745+
} else {
5746+
uint32_t type;
5747+
5748+
switch (opline->opcode) {
5749+
case ZEND_FETCH_DIM_W:
5750+
case ZEND_FETCH_LIST_W:
5751+
type = BP_VAR_W;
5752+
break;
5753+
case ZEND_FETCH_DIM_RW:
5754+
type = BP_VAR_RW;
5755+
break;
5756+
case ZEND_FETCH_DIM_UNSET:
5757+
type = BP_VAR_UNSET;
5758+
break;
5759+
default:
5760+
ZEND_UNREACHABLE();
5761+
}
5762+
5763+
if (!zend_jit_fetch_dimension_address_inner(Dst, opline, type, op1_info, op2_info, NULL, NULL, NULL)) {
5764+
return 0;
5765+
}
5766+
5767+
|8:
5768+
| SET_ZVAL_PTR res_addr, REG0, TMP1
5769+
| SET_ZVAL_TYPE_INFO res_addr, IS_INDIRECT, TMP1w, TMP2
5770+
5771+
if (type == BP_VAR_RW || (op2_info & ((MAY_BE_ANY|MAY_BE_UNDEF) - (MAY_BE_LONG|MAY_BE_STRING)))) {
5772+
|.cold_code
5773+
|9:
5774+
| brk #0 // TODO
5775+
|.code
5776+
}
5777+
}
5778+
}
5779+
5780+
if (op1_info & (MAY_BE_ANY-(MAY_BE_NULL|MAY_BE_FALSE|MAY_BE_ARRAY))) {
5781+
| brk #7
5782+
}
5783+
5784+
#ifdef ZEND_JIT_USE_RC_INFERENCE
5785+
if ((opline->op2_type & (IS_TMP_VAR|IS_VAR)) && (op1_info & (MAY_BE_UNDEF|MAY_BE_NULL|MAY_BE_FALSE|MAY_BE_ARRAY|MAY_BE_OBJECT))) {
5786+
/* ASSIGN_DIM may increase refcount of the key */
5787+
op2_info |= MAY_BE_RCN;
5788+
}
5789+
#endif
5790+
5791+
|8:
5792+
| FREE_OP opline->op2_type, opline->op2, op2_info, 0, opline
5793+
5794+
if (may_throw) {
5795+
if (!zend_jit_check_exception(Dst)) {
5796+
return 0;
5797+
}
5798+
}
56535799
return 1;
56545800
}
56555801

0 commit comments

Comments
 (0)