Skip to content

Commit d4fdf79

Browse files
committed
JIT for array merging
1 parent 6f48ccf commit d4fdf79

File tree

5 files changed

+41
-0
lines changed

5 files changed

+41
-0
lines changed

ext/opcache/jit/zend_jit.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2274,6 +2274,14 @@ static int zend_jit(const zend_op_array *op_array, zend_ssa *ssa, const zend_op
22742274
if ((op1_info & MAY_BE_UNDEF) || (op2_info & MAY_BE_UNDEF)) {
22752275
break;
22762276
}
2277+
if (opline->opcode == ZEND_ADD &&
2278+
(op1_info & (MAY_BE_ANY|MAY_BE_UNDEF)) == MAY_BE_ARRAY &&
2279+
(op2_info & (MAY_BE_ANY|MAY_BE_UNDEF)) == MAY_BE_ARRAY) {
2280+
if (!zend_jit_add_arrays(&dasm_state, opline, op_array, op1_info, op2_info)) {
2281+
goto jit_failure;
2282+
}
2283+
goto done;
2284+
}
22772285
if (!(op1_info & (MAY_BE_LONG|MAY_BE_DOUBLE)) ||
22782286
!(op2_info & (MAY_BE_LONG|MAY_BE_DOUBLE))) {
22792287
break;

ext/opcache/jit/zend_jit_disasm_x86.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -460,6 +460,7 @@ static int zend_jit_disasm_init(void)
460460
REGISTER_HELPER(zend_jit_check_constant);
461461
REGISTER_HELPER(zend_jit_array_free);
462462
REGISTER_HELPER(zend_jit_zval_array_dup);
463+
REGISTER_HELPER(zend_jit_add_arrays_helper);
463464
#undef REGISTER_HELPER
464465

465466
#ifndef _WIN32

ext/opcache/jit/zend_jit_helpers.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1858,3 +1858,11 @@ static HashTable *ZEND_FASTCALL zend_jit_zval_array_dup(zval *arr)
18581858
ZVAL_ARR(arr, ht);
18591859
return ht;
18601860
}
1861+
1862+
static zend_array *ZEND_FASTCALL zend_jit_add_arrays_helper(zend_array *op1, zend_array *op2)
1863+
{
1864+
zend_array *res;
1865+
res = zend_array_dup(op1);
1866+
zend_hash_merge(res, op2, zval_add_ref, 0);
1867+
return res;
1868+
}

ext/opcache/jit/zend_jit_trace.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3077,6 +3077,14 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par
30773077
if ((op1_info & MAY_BE_UNDEF) || (op2_info & MAY_BE_UNDEF)) {
30783078
break;
30793079
}
3080+
if (opline->opcode == ZEND_ADD &&
3081+
(op1_info & (MAY_BE_ANY|MAY_BE_UNDEF)) == MAY_BE_ARRAY &&
3082+
(op2_info & (MAY_BE_ANY|MAY_BE_UNDEF)) == MAY_BE_ARRAY) {
3083+
if (!zend_jit_add_arrays(&dasm_state, opline, op_array, op1_info, op2_info)) {
3084+
goto jit_failure;
3085+
}
3086+
goto done;
3087+
}
30803088
if (!(op1_info & (MAY_BE_LONG|MAY_BE_DOUBLE)) ||
30813089
!(op2_info & (MAY_BE_LONG|MAY_BE_DOUBLE))) {
30823090
break;

ext/opcache/jit/zend_jit_x86.dasc

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4357,6 +4357,22 @@ static int zend_jit_math(dasm_State **Dst, const zend_op *opline, const zend_op_
43574357
return 1;
43584358
}
43594359

4360+
static int zend_jit_add_arrays(dasm_State **Dst, const zend_op *opline, const zend_op_array *op_array, uint32_t op1_info, uint32_t op2_info)
4361+
{
4362+
zend_jit_addr op1_addr = OP1_ADDR();
4363+
zend_jit_addr op2_addr = OP2_ADDR();
4364+
zend_jit_addr res_addr = ZEND_ADDR_MEM_ZVAL(ZREG_FP, opline->result.var);
4365+
4366+
| GET_ZVAL_LVAL ZREG_FCARG1a, op1_addr
4367+
| GET_ZVAL_LVAL ZREG_FCARG2a, op2_addr
4368+
| EXT_CALL zend_jit_add_arrays_helper, r0
4369+
| SET_ZVAL_PTR res_addr, r0
4370+
| SET_ZVAL_TYPE_INFO res_addr, IS_ARRAY_EX
4371+
| FREE_OP opline->op1_type, opline->op1, op1_info, 0, op_array, opline
4372+
| FREE_OP opline->op2_type, opline->op2, op2_info, 0, op_array, opline
4373+
return 1;
4374+
}
4375+
43604376
static int zend_jit_long_math_helper(dasm_State **Dst,
43614377
const zend_op *opline,
43624378
zend_uchar opcode,

0 commit comments

Comments
 (0)