diff options
author | Xinchen Hui <laruence@gmail.com> | 2016-05-17 20:28:26 +0800 |
---|---|---|
committer | Xinchen Hui <laruence@gmail.com> | 2016-05-17 20:28:26 +0800 |
commit | 37b1226af16ec2cf95ffb7c2a8158ae064d8bf9d (patch) | |
tree | a88f787290e662f2dfb379c92d17bcaeede29be6 | |
parent | fad91468dbf48401ac3fc719dad3ce9f93e1a378 (diff) | |
parent | c466df6813662d921bd3f8b28c48c62652c6ffff (diff) | |
download | php-git-37b1226af16ec2cf95ffb7c2a8158ae064d8bf9d.tar.gz |
Merge branch 'master' of git.php.net:/php-src
* 'master' of git.php.net:/php-src:
Inlined fast paths of the freqently execute handlers for FETCH_DIM_R.
-rw-r--r-- | Zend/zend_execute.c | 33 | ||||
-rw-r--r-- | Zend/zend_vm_def.h | 26 | ||||
-rw-r--r-- | Zend/zend_vm_execute.h | 234 |
3 files changed, 260 insertions, 33 deletions
diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c index 0da6b32ef9..5fb0003986 100644 --- a/Zend/zend_execute.c +++ b/Zend/zend_execute.c @@ -1812,19 +1812,21 @@ static zend_never_inline void zend_fetch_dimension_address_UNSET(zval *result, z zend_fetch_dimension_address(result, container_ptr, dim, dim_type, BP_VAR_UNSET); } -static zend_always_inline void zend_fetch_dimension_address_read(zval *result, zval *container, zval *dim, int dim_type, int type, int support_strings) +static zend_always_inline void zend_fetch_dimension_address_read(zval *result, zval *container, zval *dim, int dim_type, int type, int support_strings, int slow) { zval *retval; - if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { -try_array: - retval = zend_fetch_dimension_address_inner(Z_ARRVAL_P(container), dim, dim_type, type); - ZVAL_COPY(result, retval); - return; - } else if (EXPECTED(Z_TYPE_P(container) == IS_REFERENCE)) { - container = Z_REFVAL_P(container); + if (!slow) { if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { - goto try_array; +try_array: + retval = zend_fetch_dimension_address_inner(Z_ARRVAL_P(container), dim, dim_type, type); + ZVAL_COPY(result, retval); + return; + } else if (EXPECTED(Z_TYPE_P(container) == IS_REFERENCE)) { + container = Z_REFVAL_P(container); + if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { + goto try_array; + } } } if (support_strings && EXPECTED(Z_TYPE_P(container) == IS_STRING)) { @@ -1921,17 +1923,22 @@ try_string_offset: static zend_never_inline void zend_fetch_dimension_address_read_R(zval *result, zval *container, zval *dim, int dim_type) { - zend_fetch_dimension_address_read(result, container, dim, dim_type, BP_VAR_R, 1); + zend_fetch_dimension_address_read(result, container, dim, dim_type, BP_VAR_R, 1, 0); +} + +static zend_never_inline void zend_fetch_dimension_address_read_R_slow(zval *result, zval *container, zval *dim) +{ + zend_fetch_dimension_address_read(result, container, dim, IS_CV, BP_VAR_R, 1, 1); } static zend_never_inline void zend_fetch_dimension_address_read_IS(zval *result, zval *container, zval *dim, int dim_type) { - zend_fetch_dimension_address_read(result, container, dim, dim_type, BP_VAR_IS, 1); + zend_fetch_dimension_address_read(result, container, dim, dim_type, BP_VAR_IS, 1, 0); } static zend_never_inline void zend_fetch_dimension_address_read_LIST(zval *result, zval *container, zval *dim) { - zend_fetch_dimension_address_read(result, container, dim, IS_TMP_VAR, BP_VAR_R, 0); + zend_fetch_dimension_address_read(result, container, dim, IS_TMP_VAR, BP_VAR_R, 0, 0); } ZEND_API void zend_fetch_dimension_by_zval(zval *result, zval *container, zval *dim) @@ -1941,7 +1948,7 @@ ZEND_API void zend_fetch_dimension_by_zval(zval *result, zval *container, zval * ZEND_API void zend_fetch_dimension_by_zval_is(zval *result, zval *container, zval *dim, int dim_type) { - zend_fetch_dimension_address_read(result, container, dim, dim_type, BP_VAR_IS, 1); + zend_fetch_dimension_address_read(result, container, dim, dim_type, BP_VAR_IS, 1, 0); } diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index b2393c65b0..8522523d94 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -1734,11 +1734,33 @@ ZEND_VM_HANDLER(81, ZEND_FETCH_DIM_R, CONST|TMPVAR|CV, CONST|TMPVAR|CV) { USE_OPLINE zend_free_op free_op1, free_op2; - zval *container; + zval *container, *dim, *value, *result; SAVE_OPLINE(); container = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R); - zend_fetch_dimension_address_read_R(EX_VAR(opline->result.var), container, GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R), OP2_TYPE); + dim = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R); + if (OP1_TYPE != IS_CONST) { + if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { +ZEND_VM_C_LABEL(fetch_dim_r_array): + value = zend_fetch_dimension_address_inner(Z_ARRVAL_P(container), dim, OP2_TYPE, BP_VAR_R); + result = EX_VAR(opline->result.var); + ZVAL_COPY(result, value); + } else if (EXPECTED(Z_TYPE_P(container) == IS_REFERENCE)) { + container = Z_REFVAL_P(container); + if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { + ZEND_VM_C_GOTO(fetch_dim_r_array); + } else { + ZEND_VM_C_GOTO(fetch_dim_r_slow); + } + } else { +ZEND_VM_C_LABEL(fetch_dim_r_slow): + result = EX_VAR(opline->result.var); + zend_fetch_dimension_address_read_R_slow(result, container, dim); + } + } else { + result = EX_VAR(opline->result.var); + zend_fetch_dimension_address_read_R(result, container, dim, OP2_TYPE); + } FREE_OP2(); FREE_OP1(); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index 2301d48e07..2424a636dd 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -4825,11 +4825,33 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_R_SPEC_CONST_CONST_H { USE_OPLINE - zval *container; + zval *container, *dim, *value, *result; SAVE_OPLINE(); container = EX_CONSTANT(opline->op1); - zend_fetch_dimension_address_read_R(EX_VAR(opline->result.var), container, EX_CONSTANT(opline->op2), IS_CONST); + dim = EX_CONSTANT(opline->op2); + if (IS_CONST != IS_CONST) { + if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { +fetch_dim_r_array: + value = zend_fetch_dimension_address_inner(Z_ARRVAL_P(container), dim, IS_CONST, BP_VAR_R); + result = EX_VAR(opline->result.var); + ZVAL_COPY(result, value); + } else if (EXPECTED(Z_TYPE_P(container) == IS_REFERENCE)) { + container = Z_REFVAL_P(container); + if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { + goto fetch_dim_r_array; + } else { + goto fetch_dim_r_slow; + } + } else { +fetch_dim_r_slow: + result = EX_VAR(opline->result.var); + zend_fetch_dimension_address_read_R_slow(result, container, dim); + } + } else { + result = EX_VAR(opline->result.var); + zend_fetch_dimension_address_read_R(result, container, dim, IS_CONST); + } ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); @@ -8574,11 +8596,33 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_R_SPEC_CONST_CV_HAND { USE_OPLINE - zval *container; + zval *container, *dim, *value, *result; SAVE_OPLINE(); container = EX_CONSTANT(opline->op1); - zend_fetch_dimension_address_read_R(EX_VAR(opline->result.var), container, _get_zval_ptr_cv_undef(execute_data, opline->op2.var), IS_CV); + dim = _get_zval_ptr_cv_undef(execute_data, opline->op2.var); + if (IS_CONST != IS_CONST) { + if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { +fetch_dim_r_array: + value = zend_fetch_dimension_address_inner(Z_ARRVAL_P(container), dim, IS_CV, BP_VAR_R); + result = EX_VAR(opline->result.var); + ZVAL_COPY(result, value); + } else if (EXPECTED(Z_TYPE_P(container) == IS_REFERENCE)) { + container = Z_REFVAL_P(container); + if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { + goto fetch_dim_r_array; + } else { + goto fetch_dim_r_slow; + } + } else { +fetch_dim_r_slow: + result = EX_VAR(opline->result.var); + zend_fetch_dimension_address_read_R_slow(result, container, dim); + } + } else { + result = EX_VAR(opline->result.var); + zend_fetch_dimension_address_read_R(result, container, dim, IS_CV); + } ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); @@ -10409,11 +10453,33 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_R_SPEC_CONST_TMPVAR_ { USE_OPLINE zend_free_op free_op2; - zval *container; + zval *container, *dim, *value, *result; SAVE_OPLINE(); container = EX_CONSTANT(opline->op1); - zend_fetch_dimension_address_read_R(EX_VAR(opline->result.var), container, _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2), (IS_TMP_VAR|IS_VAR)); + dim = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); + if (IS_CONST != IS_CONST) { + if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { +fetch_dim_r_array: + value = zend_fetch_dimension_address_inner(Z_ARRVAL_P(container), dim, (IS_TMP_VAR|IS_VAR), BP_VAR_R); + result = EX_VAR(opline->result.var); + ZVAL_COPY(result, value); + } else if (EXPECTED(Z_TYPE_P(container) == IS_REFERENCE)) { + container = Z_REFVAL_P(container); + if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { + goto fetch_dim_r_array; + } else { + goto fetch_dim_r_slow; + } + } else { +fetch_dim_r_slow: + result = EX_VAR(opline->result.var); + zend_fetch_dimension_address_read_R_slow(result, container, dim); + } + } else { + result = EX_VAR(opline->result.var); + zend_fetch_dimension_address_read_R(result, container, dim, (IS_TMP_VAR|IS_VAR)); + } zval_ptr_dtor_nogc(free_op2); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); @@ -40059,11 +40125,33 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_R_SPEC_CV_CONST_HAND { USE_OPLINE - zval *container; + zval *container, *dim, *value, *result; SAVE_OPLINE(); container = _get_zval_ptr_cv_undef(execute_data, opline->op1.var); - zend_fetch_dimension_address_read_R(EX_VAR(opline->result.var), container, EX_CONSTANT(opline->op2), IS_CONST); + dim = EX_CONSTANT(opline->op2); + if (IS_CV != IS_CONST) { + if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { +fetch_dim_r_array: + value = zend_fetch_dimension_address_inner(Z_ARRVAL_P(container), dim, IS_CONST, BP_VAR_R); + result = EX_VAR(opline->result.var); + ZVAL_COPY(result, value); + } else if (EXPECTED(Z_TYPE_P(container) == IS_REFERENCE)) { + container = Z_REFVAL_P(container); + if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { + goto fetch_dim_r_array; + } else { + goto fetch_dim_r_slow; + } + } else { +fetch_dim_r_slow: + result = EX_VAR(opline->result.var); + zend_fetch_dimension_address_read_R_slow(result, container, dim); + } + } else { + result = EX_VAR(opline->result.var); + zend_fetch_dimension_address_read_R(result, container, dim, IS_CONST); + } ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); @@ -47050,11 +47138,33 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_R_SPEC_CV_CV_HANDLER { USE_OPLINE - zval *container; + zval *container, *dim, *value, *result; SAVE_OPLINE(); container = _get_zval_ptr_cv_undef(execute_data, opline->op1.var); - zend_fetch_dimension_address_read_R(EX_VAR(opline->result.var), container, _get_zval_ptr_cv_undef(execute_data, opline->op2.var), IS_CV); + dim = _get_zval_ptr_cv_undef(execute_data, opline->op2.var); + if (IS_CV != IS_CONST) { + if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { +fetch_dim_r_array: + value = zend_fetch_dimension_address_inner(Z_ARRVAL_P(container), dim, IS_CV, BP_VAR_R); + result = EX_VAR(opline->result.var); + ZVAL_COPY(result, value); + } else if (EXPECTED(Z_TYPE_P(container) == IS_REFERENCE)) { + container = Z_REFVAL_P(container); + if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { + goto fetch_dim_r_array; + } else { + goto fetch_dim_r_slow; + } + } else { +fetch_dim_r_slow: + result = EX_VAR(opline->result.var); + zend_fetch_dimension_address_read_R_slow(result, container, dim); + } + } else { + result = EX_VAR(opline->result.var); + zend_fetch_dimension_address_read_R(result, container, dim, IS_CV); + } ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); @@ -51170,11 +51280,33 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_R_SPEC_CV_TMPVAR_HAN { USE_OPLINE zend_free_op free_op2; - zval *container; + zval *container, *dim, *value, *result; SAVE_OPLINE(); container = _get_zval_ptr_cv_undef(execute_data, opline->op1.var); - zend_fetch_dimension_address_read_R(EX_VAR(opline->result.var), container, _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2), (IS_TMP_VAR|IS_VAR)); + dim = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); + if (IS_CV != IS_CONST) { + if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { +fetch_dim_r_array: + value = zend_fetch_dimension_address_inner(Z_ARRVAL_P(container), dim, (IS_TMP_VAR|IS_VAR), BP_VAR_R); + result = EX_VAR(opline->result.var); + ZVAL_COPY(result, value); + } else if (EXPECTED(Z_TYPE_P(container) == IS_REFERENCE)) { + container = Z_REFVAL_P(container); + if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { + goto fetch_dim_r_array; + } else { + goto fetch_dim_r_slow; + } + } else { +fetch_dim_r_slow: + result = EX_VAR(opline->result.var); + zend_fetch_dimension_address_read_R_slow(result, container, dim); + } + } else { + result = EX_VAR(opline->result.var); + zend_fetch_dimension_address_read_R(result, container, dim, (IS_TMP_VAR|IS_VAR)); + } zval_ptr_dtor_nogc(free_op2); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); @@ -54637,11 +54769,33 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_R_SPEC_TMPVAR_CONST_ { USE_OPLINE zend_free_op free_op1; - zval *container; + zval *container, *dim, *value, *result; SAVE_OPLINE(); container = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1); - zend_fetch_dimension_address_read_R(EX_VAR(opline->result.var), container, EX_CONSTANT(opline->op2), IS_CONST); + dim = EX_CONSTANT(opline->op2); + if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { + if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { +fetch_dim_r_array: + value = zend_fetch_dimension_address_inner(Z_ARRVAL_P(container), dim, IS_CONST, BP_VAR_R); + result = EX_VAR(opline->result.var); + ZVAL_COPY(result, value); + } else if (EXPECTED(Z_TYPE_P(container) == IS_REFERENCE)) { + container = Z_REFVAL_P(container); + if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { + goto fetch_dim_r_array; + } else { + goto fetch_dim_r_slow; + } + } else { +fetch_dim_r_slow: + result = EX_VAR(opline->result.var); + zend_fetch_dimension_address_read_R_slow(result, container, dim); + } + } else { + result = EX_VAR(opline->result.var); + zend_fetch_dimension_address_read_R(result, container, dim, IS_CONST); + } zval_ptr_dtor_nogc(free_op1); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); @@ -56898,11 +57052,33 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_R_SPEC_TMPVAR_CV_HAN { USE_OPLINE zend_free_op free_op1; - zval *container; + zval *container, *dim, *value, *result; SAVE_OPLINE(); container = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1); - zend_fetch_dimension_address_read_R(EX_VAR(opline->result.var), container, _get_zval_ptr_cv_undef(execute_data, opline->op2.var), IS_CV); + dim = _get_zval_ptr_cv_undef(execute_data, opline->op2.var); + if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { + if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { +fetch_dim_r_array: + value = zend_fetch_dimension_address_inner(Z_ARRVAL_P(container), dim, IS_CV, BP_VAR_R); + result = EX_VAR(opline->result.var); + ZVAL_COPY(result, value); + } else if (EXPECTED(Z_TYPE_P(container) == IS_REFERENCE)) { + container = Z_REFVAL_P(container); + if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { + goto fetch_dim_r_array; + } else { + goto fetch_dim_r_slow; + } + } else { +fetch_dim_r_slow: + result = EX_VAR(opline->result.var); + zend_fetch_dimension_address_read_R_slow(result, container, dim); + } + } else { + result = EX_VAR(opline->result.var); + zend_fetch_dimension_address_read_R(result, container, dim, IS_CV); + } zval_ptr_dtor_nogc(free_op1); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); @@ -58062,11 +58238,33 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_R_SPEC_TMPVAR_TMPVAR { USE_OPLINE zend_free_op free_op1, free_op2; - zval *container; + zval *container, *dim, *value, *result; SAVE_OPLINE(); container = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1); - zend_fetch_dimension_address_read_R(EX_VAR(opline->result.var), container, _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2), (IS_TMP_VAR|IS_VAR)); + dim = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); + if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { + if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { +fetch_dim_r_array: + value = zend_fetch_dimension_address_inner(Z_ARRVAL_P(container), dim, (IS_TMP_VAR|IS_VAR), BP_VAR_R); + result = EX_VAR(opline->result.var); + ZVAL_COPY(result, value); + } else if (EXPECTED(Z_TYPE_P(container) == IS_REFERENCE)) { + container = Z_REFVAL_P(container); + if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { + goto fetch_dim_r_array; + } else { + goto fetch_dim_r_slow; + } + } else { +fetch_dim_r_slow: + result = EX_VAR(opline->result.var); + zend_fetch_dimension_address_read_R_slow(result, container, dim); + } + } else { + result = EX_VAR(opline->result.var); + zend_fetch_dimension_address_read_R(result, container, dim, (IS_TMP_VAR|IS_VAR)); + } zval_ptr_dtor_nogc(free_op2); zval_ptr_dtor_nogc(free_op1); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); |