1
0
mirror of https://github.com/php/php-src.git synced 2026-04-05 23:23:03 +02:00

Reduce ZEND_THROW specialization

Throwing is very expensive due to the need of gathering the backtrace,
so it makes little sense to optimize refcounting to this degree.
This commit is contained in:
Nikita Popov
2019-10-09 13:17:25 +02:00
parent f6f32f2cf0
commit 2aba10be4a
4 changed files with 52 additions and 107 deletions

View 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();
}

View 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,

View File

@@ -962,8 +962,8 @@
_(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) \

View File

@@ -329,7 +329,7 @@ static uint32_t zend_vm_opcodes_flags[195] = {
0x01000000,
0x00001001,
0x02042003,
0x00000003,
0x00000007,
0x00040771,
0x00000057,
0x0b000003,