mirror of
https://github.com/php/php-src.git
synced 2026-04-01 21:22:13 +02:00
JIT: prefer string reallocation instead of allocation/memcpy/deallocation
This commit is contained in:
@@ -4804,12 +4804,14 @@ static int zend_jit_concat_helper(dasm_State **Dst,
|
||||
}
|
||||
| LOAD_ZVAL_ADDR FCARG2x, op1_addr
|
||||
| LOAD_ZVAL_ADDR CARG3, op2_addr
|
||||
| EXT_CALL zend_jit_fast_concat_helper, REG0
|
||||
if (op1_type == IS_CV || op1_type == IS_CONST) {
|
||||
| EXT_CALL zend_jit_fast_concat_helper, REG0
|
||||
} else {
|
||||
| EXT_CALL zend_jit_fast_concat_tmp_helper, REG0
|
||||
}
|
||||
}
|
||||
/* concatination with empty string may increase refcount */
|
||||
op1_info |= MAY_BE_RCN;
|
||||
op2_info |= MAY_BE_RCN;
|
||||
| FREE_OP op1_type, op1, op1_info, 0, opline, ZREG_TMP1, ZREG_TMP2
|
||||
| FREE_OP op2_type, op2, op2_info, 0, opline, ZREG_TMP1, ZREG_TMP2
|
||||
|5:
|
||||
}
|
||||
|
||||
@@ -637,6 +637,7 @@ static int zend_jit_disasm_init(void)
|
||||
REGISTER_HELPER(zend_jit_assign_dim_op_helper);
|
||||
REGISTER_HELPER(zend_jit_fast_assign_concat_helper);
|
||||
REGISTER_HELPER(zend_jit_fast_concat_helper);
|
||||
REGISTER_HELPER(zend_jit_fast_concat_tmp_helper);
|
||||
REGISTER_HELPER(zend_jit_isset_dim_helper);
|
||||
REGISTER_HELPER(zend_jit_free_call_frame);
|
||||
REGISTER_HELPER(zend_jit_fetch_global_helper);
|
||||
|
||||
@@ -1265,6 +1265,40 @@ static void ZEND_FASTCALL zend_jit_fast_concat_helper(zval *result, zval *op1, z
|
||||
ZSTR_VAL(result_str)[result_len] = '\0';
|
||||
}
|
||||
|
||||
static void ZEND_FASTCALL zend_jit_fast_concat_tmp_helper(zval *result, zval *op1, zval *op2)
|
||||
{
|
||||
zend_string *op1_str = Z_STR_P(op1);
|
||||
size_t op1_len = ZSTR_LEN(op1_str);
|
||||
size_t op2_len = Z_STRLEN_P(op2);
|
||||
size_t result_len = op1_len + op2_len;
|
||||
zend_string *result_str;
|
||||
|
||||
if (UNEXPECTED(op1_len > SIZE_MAX - op2_len)) {
|
||||
zend_throw_error(NULL, "String size overflow");
|
||||
return;
|
||||
}
|
||||
|
||||
do {
|
||||
if (!ZSTR_IS_INTERNED(op1_str)) {
|
||||
if (GC_REFCOUNT(op1_str) == 1) {
|
||||
Z_STR_P(op1) = result_str =
|
||||
perealloc(op1_str, ZEND_MM_ALIGNED_SIZE(_ZSTR_STRUCT_SIZE(result_len)), 0);
|
||||
ZSTR_LEN(result_str) = result_len;
|
||||
zend_string_forget_hash_val(result_str);
|
||||
break;
|
||||
}
|
||||
GC_DELREF(op1_str);
|
||||
}
|
||||
result_str = zend_string_alloc(result_len, 0);
|
||||
memcpy(ZSTR_VAL(result_str), ZSTR_VAL(op1_str), op1_len);
|
||||
} while (0);
|
||||
|
||||
ZVAL_NEW_STR(result, result_str);
|
||||
|
||||
memcpy(ZSTR_VAL(result_str) + op1_len, Z_STRVAL_P(op2), op2_len);
|
||||
ZSTR_VAL(result_str)[result_len] = '\0';
|
||||
}
|
||||
|
||||
static int ZEND_FASTCALL zend_jit_isset_dim_helper(zval *container, zval *offset)
|
||||
{
|
||||
if (UNEXPECTED(Z_TYPE_P(offset) == IS_UNDEF)) {
|
||||
|
||||
@@ -5251,15 +5251,17 @@ static int zend_jit_concat_helper(dasm_State **Dst,
|
||||
| sub r4, 12
|
||||
| PUSH_ZVAL_ADDR op2_addr, r0
|
||||
|.endif
|
||||
| EXT_CALL zend_jit_fast_concat_helper, r0
|
||||
if (op1_type == IS_CV || op1_type == IS_CONST) {
|
||||
| EXT_CALL zend_jit_fast_concat_helper, r0
|
||||
} else {
|
||||
| EXT_CALL zend_jit_fast_concat_tmp_helper, r0
|
||||
}
|
||||
|.if not(X64)
|
||||
| add r4, 12
|
||||
|.endif
|
||||
}
|
||||
/* concatination with empty string may increase refcount */
|
||||
op1_info |= MAY_BE_RCN;
|
||||
op2_info |= MAY_BE_RCN;
|
||||
| FREE_OP op1_type, op1, op1_info, 0, opline
|
||||
| FREE_OP op2_type, op2, op2_info, 0, opline
|
||||
|5:
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user