]> granicus.if.org Git - php/commitdiff
Reduce ZEND_THROW specialization
authorNikita Popov <nikita.ppv@gmail.com>
Wed, 9 Oct 2019 11:17:25 +0000 (13:17 +0200)
committerNikita Popov <nikita.ppv@gmail.com>
Wed, 9 Oct 2019 11:17:25 +0000 (13:17 +0200)
Throwing is very expensive due to the need of gathering the backtrace,
so it makes little sense to optimize refcounting to this degree.

Zend/zend_vm_def.h
Zend/zend_vm_execute.h
Zend/zend_vm_handlers.h
Zend/zend_vm_opcodes.c

index b2ea3fefd58c1a535e2ccc2f68bcad702fcd306f..3043cebdaac93faadadb22e63ec7b6540d489938 100644 (file)
@@ -4427,7 +4427,7 @@ ZEND_VM_HANDLER(161, ZEND_GENERATOR_RETURN, CONST|TMP|VAR|CV, ANY)
        ZEND_VM_RETURN();
 }
 
-ZEND_VM_COLD_CONST_HANDLER(108, ZEND_THROW, CONST|TMP|VAR|CV, ANY)
+ZEND_VM_COLD_CONST_HANDLER(108, ZEND_THROW, CONST|TMPVAR|CV, ANY)
 {
        USE_OPLINE
        zval *value;
@@ -4456,13 +4456,10 @@ ZEND_VM_COLD_CONST_HANDLER(108, ZEND_THROW, CONST|TMP|VAR|CV, ANY)
        } while (0);
 
        zend_exception_save();
-       if (OP1_TYPE != IS_TMP_VAR) {
-               Z_TRY_ADDREF_P(value);
-       }
-
+       Z_TRY_ADDREF_P(value);
        zend_throw_exception_object(value);
        zend_exception_restore();
-       FREE_OP1_IF_VAR();
+       FREE_OP1();
        HANDLE_EXCEPTION();
 }
 
index accf802b17a5e69b2ae5d7a5ff66dc5850314d80..537b677e855ec0a07d0e89614d1d1a64416a5732 100644 (file)
@@ -3605,10 +3605,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_THROW_SPEC_CONST_
        } while (0);
 
        zend_exception_save();
-       if (IS_CONST != IS_TMP_VAR) {
-               Z_TRY_ADDREF_P(value);
-       }
-
+       Z_TRY_ADDREF_P(value);
        zend_throw_exception_object(value);
        zend_exception_restore();
 
@@ -13138,6 +13135,42 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_FREE_SPEC_TMPVA
        ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
+static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_THROW_SPEC_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+       USE_OPLINE
+       zval *value;
+
+       SAVE_OPLINE();
+       value = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC);
+
+       do {
+               if ((IS_TMP_VAR|IS_VAR) == IS_CONST || UNEXPECTED(Z_TYPE_P(value) != IS_OBJECT)) {
+                       if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && Z_ISREF_P(value)) {
+                               value = Z_REFVAL_P(value);
+                               if (EXPECTED(Z_TYPE_P(value) == IS_OBJECT)) {
+                                       break;
+                               }
+                       }
+                       if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) {
+                               ZVAL_UNDEFINED_OP1();
+                               if (UNEXPECTED(EG(exception) != NULL)) {
+                                       HANDLE_EXCEPTION();
+                               }
+                       }
+                       zend_throw_error(NULL, "Can only throw objects");
+                       zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+                       HANDLE_EXCEPTION();
+               }
+       } while (0);
+
+       zend_exception_save();
+       Z_TRY_ADDREF_P(value);
+       zend_throw_exception_object(value);
+       zend_exception_restore();
+       zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+       HANDLE_EXCEPTION();
+}
+
 static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEND_VAL_SPEC_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
        USE_OPLINE
@@ -17508,45 +17541,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_GENERATOR_RETURN_SPEC_TMP_HAND
        ZEND_VM_RETURN();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_THROW_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
-{
-       USE_OPLINE
-       zval *value;
-
-       SAVE_OPLINE();
-       value = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
-
-       do {
-               if (IS_TMP_VAR == IS_CONST || UNEXPECTED(Z_TYPE_P(value) != IS_OBJECT)) {
-                       if ((IS_TMP_VAR & (IS_VAR|IS_CV)) && Z_ISREF_P(value)) {
-                               value = Z_REFVAL_P(value);
-                               if (EXPECTED(Z_TYPE_P(value) == IS_OBJECT)) {
-                                       break;
-                               }
-                       }
-                       if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) {
-                               ZVAL_UNDEFINED_OP1();
-                               if (UNEXPECTED(EG(exception) != NULL)) {
-                                       HANDLE_EXCEPTION();
-                               }
-                       }
-                       zend_throw_error(NULL, "Can only throw objects");
-                       zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
-                       HANDLE_EXCEPTION();
-               }
-       } while (0);
-
-       zend_exception_save();
-       if (IS_TMP_VAR != IS_TMP_VAR) {
-               Z_TRY_ADDREF_P(value);
-       }
-
-       zend_throw_exception_object(value);
-       zend_exception_restore();
-
-       HANDLE_EXCEPTION();
-}
-
 static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEND_VAL_EX_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
        USE_OPLINE
@@ -20254,45 +20248,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_GENERATOR_RETURN_SPEC_VAR_HAND
        ZEND_VM_RETURN();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_THROW_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
-{
-       USE_OPLINE
-       zval *value;
-
-       SAVE_OPLINE();
-       value = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC);
-
-       do {
-               if (IS_VAR == IS_CONST || UNEXPECTED(Z_TYPE_P(value) != IS_OBJECT)) {
-                       if ((IS_VAR & (IS_VAR|IS_CV)) && Z_ISREF_P(value)) {
-                               value = Z_REFVAL_P(value);
-                               if (EXPECTED(Z_TYPE_P(value) == IS_OBJECT)) {
-                                       break;
-                               }
-                       }
-                       if (IS_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) {
-                               ZVAL_UNDEFINED_OP1();
-                               if (UNEXPECTED(EG(exception) != NULL)) {
-                                       HANDLE_EXCEPTION();
-                               }
-                       }
-                       zend_throw_error(NULL, "Can only throw objects");
-                       zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
-                       HANDLE_EXCEPTION();
-               }
-       } while (0);
-
-       zend_exception_save();
-       if (IS_VAR != IS_TMP_VAR) {
-               Z_TRY_ADDREF_P(value);
-       }
-
-       zend_throw_exception_object(value);
-       zend_exception_restore();
-       zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
-       HANDLE_EXCEPTION();
-}
-
 static zend_always_inline ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEND_VAR_SPEC_VAR_INLINE_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
        USE_OPLINE
@@ -36997,10 +36952,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_THROW_SPEC_CV_HANDLER(ZEND_OPC
        } while (0);
 
        zend_exception_save();
-       if (IS_CV != IS_TMP_VAR) {
-               Z_TRY_ADDREF_P(value);
-       }
-
+       Z_TRY_ADDREF_P(value);
        zend_throw_exception_object(value);
        zend_exception_restore();
 
@@ -51833,8 +51785,8 @@ ZEND_API void execute_ex(zend_execute_data *ex)
                        (void*)&&ZEND_SEND_VAR_NO_REF_SPEC_VAR_LABEL,
                        (void*)&&ZEND_CATCH_SPEC_CONST_LABEL,
                        (void*)&&ZEND_THROW_SPEC_CONST_LABEL,
-                       (void*)&&ZEND_THROW_SPEC_TMP_LABEL,
-                       (void*)&&ZEND_THROW_SPEC_VAR_LABEL,
+                       (void*)&&ZEND_THROW_SPEC_TMPVAR_LABEL,
+                       (void*)&&ZEND_THROW_SPEC_TMPVAR_LABEL,
                        (void*)&&ZEND_NULL_LABEL,
                        (void*)&&ZEND_THROW_SPEC_CV_LABEL,
                        (void*)&&ZEND_FETCH_CLASS_SPEC_UNUSED_CONST_LABEL,
@@ -54734,6 +54686,10 @@ zend_leave_helper_SPEC_LABEL:
                                VM_TRACE(ZEND_FE_FREE_SPEC_TMPVAR)
                                ZEND_FE_FREE_SPEC_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
                                HYBRID_BREAK();
+                       HYBRID_CASE(ZEND_THROW_SPEC_TMPVAR):
+                               VM_TRACE(ZEND_THROW_SPEC_TMPVAR)
+                               ZEND_THROW_SPEC_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+                               HYBRID_BREAK();
                        HYBRID_CASE(ZEND_SEND_VAL_SPEC_TMPVAR):
                                VM_TRACE(ZEND_SEND_VAL_SPEC_TMPVAR)
                                ZEND_SEND_VAL_SPEC_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
@@ -55123,10 +55079,6 @@ zend_leave_helper_SPEC_LABEL:
                                VM_TRACE(ZEND_GENERATOR_RETURN_SPEC_TMP)
                                ZEND_GENERATOR_RETURN_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
                                HYBRID_BREAK();
-                       HYBRID_CASE(ZEND_THROW_SPEC_TMP):
-                               VM_TRACE(ZEND_THROW_SPEC_TMP)
-                               ZEND_THROW_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-                               HYBRID_BREAK();
                        HYBRID_CASE(ZEND_SEND_VAL_EX_SPEC_TMP):
                                VM_TRACE(ZEND_SEND_VAL_EX_SPEC_TMP)
                                ZEND_SEND_VAL_EX_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
@@ -55408,10 +55360,6 @@ zend_leave_helper_SPEC_LABEL:
                                VM_TRACE(ZEND_GENERATOR_RETURN_SPEC_VAR)
                                ZEND_GENERATOR_RETURN_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
                                HYBRID_BREAK();
-                       HYBRID_CASE(ZEND_THROW_SPEC_VAR):
-                               VM_TRACE(ZEND_THROW_SPEC_VAR)
-                               ZEND_THROW_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-                               HYBRID_BREAK();
                        HYBRID_CASE(ZEND_SEND_VAR_SPEC_VAR):
                                VM_TRACE(ZEND_SEND_VAR_SPEC_VAR)
                                ZEND_SEND_VAR_SPEC_VAR_INLINE_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
@@ -59349,8 +59297,8 @@ void zend_vm_init(void)
                ZEND_SEND_VAR_NO_REF_SPEC_VAR_HANDLER,
                ZEND_CATCH_SPEC_CONST_HANDLER,
                ZEND_THROW_SPEC_CONST_HANDLER,
-               ZEND_THROW_SPEC_TMP_HANDLER,
-               ZEND_THROW_SPEC_VAR_HANDLER,
+               ZEND_THROW_SPEC_TMPVAR_HANDLER,
+               ZEND_THROW_SPEC_TMPVAR_HANDLER,
                ZEND_NULL_HANDLER,
                ZEND_THROW_SPEC_CV_HANDLER,
                ZEND_FETCH_CLASS_SPEC_UNUSED_CONST_HANDLER,
index 7aa1a93981e35839f7a636d023892f26dcfc3975..e3b037e916b9d06c8cfa0586c0367b35e026fb87 100644 (file)
        _(1859, ZEND_SEND_VAR_NO_REF_SPEC_VAR) \
        _(1860, ZEND_CATCH_SPEC_CONST) \
        _(1861, ZEND_THROW_SPEC_CONST) \
-       _(1862, ZEND_THROW_SPEC_TMP) \
-       _(1863, ZEND_THROW_SPEC_VAR) \
+       _(1862, ZEND_THROW_SPEC_TMPVAR) \
+       _(1863, ZEND_THROW_SPEC_TMPVAR) \
        _(1865, ZEND_THROW_SPEC_CV) \
        _(1866, ZEND_FETCH_CLASS_SPEC_UNUSED_CONST) \
        _(1867, ZEND_FETCH_CLASS_SPEC_UNUSED_TMPVAR) \
index f66c219436d7580233e1b9c19869797a94a93eec..07de4f8d28fe44dc175133f4fcd5c6627fe3f4f0 100644 (file)
@@ -329,7 +329,7 @@ static uint32_t zend_vm_opcodes_flags[195] = {
        0x01000000,
        0x00001001,
        0x02042003,
-       0x00000003,
+       0x00000007,
        0x00040771,
        0x00000057,
        0x0b000003,