]> granicus.if.org Git - php/commitdiff
Inlined fast paths of the freqently execute handlers for FETCH_DIM_R.
authorDmitry Stogov <dmitry@zend.com>
Tue, 17 May 2016 12:08:04 +0000 (15:08 +0300)
committerDmitry Stogov <dmitry@zend.com>
Tue, 17 May 2016 12:08:04 +0000 (15:08 +0300)
Zend/zend_execute.c
Zend/zend_vm_def.h
Zend/zend_vm_execute.h

index 0da6b32ef9bc1dd8a746a926b90cc7b8cadd243f..5fb000398600211e501129481fe44094122b9610 100644 (file)
@@ -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);
 }
 
 
index c4a97ab05601517437a25beb95e7b18f27a6626b..0ad1f578453ecf315639c3ea22f44d7a725d8c19 100644 (file)
@@ -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();
index fc6f02a05522444e095ce3e36f8bcc9063bfecb9..eff4305decae3cb53fbe37c8c34f48bbb7dc70d5 100644 (file)
@@ -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();