Skip to content

Commit

Permalink
JIT: prefer string reallocation instead of allocation/memcpy/dealloca…
Browse files Browse the repository at this point in the history
…tion
  • Loading branch information
dstogov committed Sep 7, 2021
1 parent aed94e2 commit 7fcb45d
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 6 deletions.
8 changes: 5 additions & 3 deletions ext/opcache/jit/zend_jit_arm64.dasc
Original file line number Diff line number Diff line change
Expand Up @@ -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:
}
Expand Down
1 change: 1 addition & 0 deletions ext/opcache/jit/zend_jit_disasm.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
34 changes: 34 additions & 0 deletions ext/opcache/jit/zend_jit_helpers.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)) {
Expand Down
8 changes: 5 additions & 3 deletions ext/opcache/jit/zend_jit_x86.dasc
Original file line number Diff line number Diff line change
Expand Up @@ -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:
}
Expand Down

0 comments on commit 7fcb45d

Please sign in to comment.