Browse Source

Inlined fast paths of the freqently execute handlers for FETCH_DIM_R.

pull/1912/head
Dmitry Stogov 10 years ago
parent
commit
c466df6813
  1. 33
      Zend/zend_execute.c
  2. 26
      Zend/zend_vm_def.h
  3. 234
      Zend/zend_vm_execute.h

33
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);
}

26
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();

234
Zend/zend_vm_execute.h

@ -4831,11 +4831,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();
@ -8580,11 +8602,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();
@ -10415,11 +10459,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();
@ -40065,11 +40131,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();
@ -47056,11 +47144,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();
@ -51176,11 +51286,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();
@ -54643,11 +54775,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();
@ -56904,11 +57058,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();
@ -58068,11 +58244,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();

Loading…
Cancel
Save