mirror of
https://github.com/php/php-src.git
synced 2025-08-16 05:58:45 +02:00
JIT: Code generation for ROPE_INIT, ROPE_ADD and ROPE_END with STRING operands
This commit is contained in:
parent
425c2e3ba1
commit
c5ded13614
6 changed files with 133 additions and 0 deletions
|
@ -3899,6 +3899,17 @@ static int zend_jit(const zend_op_array *op_array, zend_ssa *ssa, const zend_op
|
|||
goto jit_failure;
|
||||
}
|
||||
goto done;
|
||||
case ZEND_ROPE_INIT:
|
||||
case ZEND_ROPE_ADD:
|
||||
case ZEND_ROPE_END:
|
||||
op2_info = OP2_INFO();
|
||||
if ((op2_info & (MAY_BE_UNDEF|MAY_BE_ANY|MAY_BE_REF)) != MAY_BE_STRING) {
|
||||
break;
|
||||
}
|
||||
if (!zend_jit_rope(&dasm_state, opline, op2_info)) {
|
||||
goto jit_failure;
|
||||
}
|
||||
goto done;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -13953,6 +13953,48 @@ static int zend_jit_in_array(dasm_State **Dst, const zend_op *opline, uint32_t o
|
|||
return 1;
|
||||
}
|
||||
|
||||
static int zend_jit_rope(dasm_State **Dst, const zend_op *opline, uint32_t op2_info)
|
||||
{
|
||||
uint32_t offset;
|
||||
|
||||
offset = (opline->opcode == ZEND_ROPE_INIT) ?
|
||||
opline->result.var :
|
||||
opline->op1.var + opline->extended_value * sizeof(zend_string*);
|
||||
|
||||
if (opline->op2_type == IS_CONST) {
|
||||
zval *zv = RT_CONSTANT(opline, opline->op2);
|
||||
zend_string *str;
|
||||
|
||||
ZEND_ASSERT(Z_TYPE_P(zv) == IS_STRING);
|
||||
str = Z_STR_P(zv);
|
||||
| LOAD_ADDR REG0, str
|
||||
| MEM_ACCESS_64_WITH_UOFFSET str, REG0, FP, offset, TMP1
|
||||
} else {
|
||||
zend_jit_addr op2_addr = OP2_ADDR();
|
||||
|
||||
ZEND_ASSERT((op2_info & (MAY_BE_UNDEF|MAY_BE_ANY|MAY_BE_REF)) == MAY_BE_STRING);
|
||||
|
||||
| GET_ZVAL_PTR REG1, op2_addr, TMP1
|
||||
| MEM_ACCESS_64_WITH_UOFFSET str, REG1, FP, offset, TMP1
|
||||
if (opline->op2_type == IS_CV) {
|
||||
| GET_ZVAL_TYPE_INFO REG0w, op2_addr, TMP1
|
||||
| TRY_ADDREF op2_info, REG0w, REG1, TMP1w
|
||||
}
|
||||
}
|
||||
|
||||
if (opline->opcode == ZEND_ROPE_END) {
|
||||
zend_jit_addr res_addr = RES_ADDR();
|
||||
|
||||
| ADD_SUB_64_WITH_CONST add, FCARG1x, FP, opline->op1.var, TMP1
|
||||
| LOAD_32BIT_VAL FCARG2w, opline->extended_value
|
||||
| EXT_CALL zend_jit_rope_end, TMP1
|
||||
| SET_ZVAL_PTR res_addr, RETVALx, TMP1
|
||||
| SET_ZVAL_TYPE_INFO res_addr, IS_STRING_EX, TMP1w, TMP2
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static bool zend_jit_noref_guard(dasm_State **Dst, const zend_op *opline, zend_jit_addr var_addr)
|
||||
{
|
||||
int32_t exit_point = zend_jit_trace_get_exit_point(opline, 0);
|
||||
|
|
|
@ -693,6 +693,7 @@ static int zend_jit_disasm_init(void)
|
|||
REGISTER_HELPER(zend_jit_pre_dec_obj_helper);
|
||||
REGISTER_HELPER(zend_jit_post_inc_obj_helper);
|
||||
REGISTER_HELPER(zend_jit_post_dec_obj_helper);
|
||||
REGISTER_HELPER(zend_jit_rope_end);
|
||||
#if (PHP_VERSION_ID <= 80100) && (SIZEOF_SIZE_T == 4)
|
||||
REGISTER_HELPER(zval_jit_update_constant_ex);
|
||||
#endif
|
||||
|
|
|
@ -2597,3 +2597,24 @@ static void ZEND_FASTCALL zend_jit_free_trampoline_helper(zend_function *func)
|
|||
zend_string_release_ex(func->common.function_name, 0);
|
||||
zend_free_trampoline(func);
|
||||
}
|
||||
|
||||
static zend_string* ZEND_FASTCALL zend_jit_rope_end(zend_string **rope, uint32_t count)
|
||||
{
|
||||
zend_string *ret;
|
||||
uint32_t i;
|
||||
size_t len = 0;
|
||||
char *target;
|
||||
|
||||
for (i = 0; i <= count; i++) {
|
||||
len += ZSTR_LEN(rope[i]);
|
||||
}
|
||||
ret = zend_string_alloc(len, 0);
|
||||
target = ZSTR_VAL(ret);
|
||||
for (i = 0; i <= count; i++) {
|
||||
memcpy(target, ZSTR_VAL(rope[i]), ZSTR_LEN(rope[i]));
|
||||
target += ZSTR_LEN(rope[i]);
|
||||
zend_string_release_ex(rope[i], 0);
|
||||
}
|
||||
*target = '\0';
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -1937,6 +1937,11 @@ propagate_arg:
|
|||
ADD_OP1_TRACE_GUARD();
|
||||
}
|
||||
break;
|
||||
case ZEND_ROPE_INIT:
|
||||
case ZEND_ROPE_ADD:
|
||||
case ZEND_ROPE_END:
|
||||
ADD_OP2_TRACE_GUARD();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -5794,6 +5799,18 @@ generic_dynamic_call:
|
|||
TRACE_FRAME_SET_UNKNOWN_NUM_ARGS(JIT_G(current_frame)->call);
|
||||
}
|
||||
break;
|
||||
case ZEND_ROPE_INIT:
|
||||
case ZEND_ROPE_ADD:
|
||||
case ZEND_ROPE_END:
|
||||
op2_info = OP2_INFO();
|
||||
CHECK_OP2_TRACE_TYPE();
|
||||
if ((op2_info & (MAY_BE_UNDEF|MAY_BE_ANY|MAY_BE_REF)) != MAY_BE_STRING) {
|
||||
break;
|
||||
}
|
||||
if (!zend_jit_rope(&dasm_state, opline, op2_info)) {
|
||||
goto jit_failure;
|
||||
}
|
||||
goto done;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -14798,6 +14798,47 @@ static int zend_jit_in_array(dasm_State **Dst, const zend_op *opline, uint32_t o
|
|||
return 1;
|
||||
}
|
||||
|
||||
static int zend_jit_rope(dasm_State **Dst, const zend_op *opline, uint32_t op2_info)
|
||||
{
|
||||
uint32_t offset;
|
||||
|
||||
offset = (opline->opcode == ZEND_ROPE_INIT) ?
|
||||
opline->result.var :
|
||||
opline->op1.var + opline->extended_value * sizeof(zend_string*);
|
||||
|
||||
if (opline->op2_type == IS_CONST) {
|
||||
zval *zv = RT_CONSTANT(opline, opline->op2);
|
||||
zend_string *str;
|
||||
|
||||
ZEND_ASSERT(Z_TYPE_P(zv) == IS_STRING);
|
||||
str = Z_STR_P(zv);
|
||||
| ADDR_STORE aword [FP + offset], str, r0
|
||||
} else {
|
||||
zend_jit_addr op2_addr = OP2_ADDR();
|
||||
|
||||
ZEND_ASSERT((op2_info & (MAY_BE_UNDEF|MAY_BE_ANY|MAY_BE_REF)) == MAY_BE_STRING);
|
||||
|
||||
| GET_ZVAL_PTR r1, op2_addr
|
||||
| mov aword [FP + offset], r1
|
||||
if (opline->op2_type == IS_CV) {
|
||||
| GET_ZVAL_TYPE_INFO eax, op2_addr
|
||||
| TRY_ADDREF op2_info, ah, r1
|
||||
}
|
||||
}
|
||||
|
||||
if (opline->opcode == ZEND_ROPE_END) {
|
||||
zend_jit_addr res_addr = RES_ADDR();
|
||||
|
||||
| lea FCARG1a, [FP + opline->op1.var]
|
||||
| mov FCARG2d, opline->extended_value
|
||||
| EXT_CALL zend_jit_rope_end, r0
|
||||
| SET_ZVAL_PTR res_addr, r0
|
||||
| SET_ZVAL_TYPE_INFO res_addr, IS_STRING_EX
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static bool zend_jit_noref_guard(dasm_State **Dst, const zend_op *opline, zend_jit_addr var_addr)
|
||||
{
|
||||
int32_t exit_point = zend_jit_trace_get_exit_point(opline, 0);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue