1
0
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:
Dmitry Stogov
2021-09-07 15:28:15 +03:00
parent aed94e2ca8
commit 7fcb45dffa
4 changed files with 45 additions and 6 deletions

View File

@@ -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:
}

View File

@@ -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);

View File

@@ -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)) {

View File

@@ -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:
}