From f0ad7472b068e25dcf985e9af8f7735caf63d7f9 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Tue, 2 Sep 2014 22:13:24 +0400 Subject: [PATCH] Avoid memory allocation/deallocation in BEGIN_SILENCE/END_SILENCE opcode handlers. --- Zend/zend_types.h | 1 + Zend/zend_vm_def.h | 92 +++++++++++++++++++++++------------------- Zend/zend_vm_execute.h | 86 ++++++++++++++++++++++----------------- 3 files changed, 100 insertions(+), 79 deletions(-) diff --git a/Zend/zend_types.h b/Zend/zend_types.h index 47f408f4b3..368311aedb 100644 --- a/Zend/zend_types.h +++ b/Zend/zend_types.h @@ -134,6 +134,7 @@ struct _zval_struct { uint32_t str_offset; /* string offset */ uint32_t cache_slot; /* literal cache slot */ uint32_t lineno; /* line number (for ast nodes) */ + int error_reporting; /* old error_reporting (@) */ } u2; }; diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index 72f9d3bd04..a1fbba752e 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -5048,22 +5048,27 @@ ZEND_VM_HANDLER(57, ZEND_BEGIN_SILENCE, ANY, ANY) USE_OPLINE SAVE_OPLINE(); - ZVAL_LONG(EX_VAR(opline->result.var), EG(error_reporting)); - if (Z_TYPE(EX(old_error_reporting)) == IS_UNDEF) { - ZVAL_LONG(&EX(old_error_reporting), EG(error_reporting)); - } - if (EG(error_reporting)) { - do { - EG(error_reporting) = 0; - if (!EG(error_reporting_ini_entry)) { - zend_ini_entry *p = zend_hash_str_find_ptr(EG(ini_directives), "error_reporting", sizeof("error_reporting")-1); - if (p) { - EG(error_reporting_ini_entry) = p; - } else { - break; - } + EX_VAR(opline->result.var)->u2.error_reporting = EG(error_reporting); + do { + if (!EG(error_reporting_ini_entry)) { + zend_ini_entry *p = zend_hash_str_find_ptr(EG(ini_directives), "error_reporting", sizeof("error_reporting")-1); + if (p) { + EG(error_reporting_ini_entry) = p; + } else { + EG(error_reporting) = 0; + break; } + } + ZVAL_NEW_STR(EX_VAR(opline->result.var), EG(error_reporting_ini_entry)->value); + if (EG(error_reporting_ini_entry)->value) { + zend_string_addref(EG(error_reporting_ini_entry)->value); + } + if (Z_TYPE(EX(old_error_reporting)) == IS_UNDEF) { + ZVAL_NEW_STR(&EX(old_error_reporting), EG(error_reporting_ini_entry)->value); + } + if (EG(error_reporting)) { + EG(error_reporting) = 0; if (!EG(error_reporting_ini_entry)->modified) { if (!EG(modified_ini_directives)) { ALLOC_HASHTABLE(EG(modified_ini_directives)); @@ -5082,9 +5087,8 @@ ZEND_VM_HANDLER(57, ZEND_BEGIN_SILENCE, ANY, ANY) } else { EG(error_reporting_ini_entry)->value = zend_string_init("0", sizeof("0")-1, 0); } - } while (0); - } - CHECK_EXCEPTION(); + } + } while (0); ZEND_VM_NEXT_OPCODE(); } @@ -5098,25 +5102,30 @@ ZEND_VM_HANDLER(142, ZEND_RAISE_ABSTRACT_ERROR, ANY, ANY) ZEND_VM_HANDLER(58, ZEND_END_SILENCE, TMP, ANY) { USE_OPLINE - char buf[MAX_LENGTH_OF_LONG + 1]; - char *res; SAVE_OPLINE(); - if (!EG(error_reporting) && Z_LVAL_P(EX_VAR(opline->op1.var)) != 0) { - EG(error_reporting) = Z_LVAL_P(EX_VAR(opline->op1.var)); - _zend_print_signed_to_buf(buf + sizeof(buf) - 1, EG(error_reporting), zend_ulong, res); - if (EXPECTED(EG(error_reporting_ini_entry) != NULL)) { + if (!EG(error_reporting)) { + EG(error_reporting) = EX_VAR(opline->op1.var)->u2.error_reporting; + if (EXPECTED(Z_TYPE_P(EX_VAR(opline->op1.var)) == IS_STRING)) { if (EXPECTED(EG(error_reporting_ini_entry)->modified && EG(error_reporting_ini_entry)->value != EG(error_reporting_ini_entry)->orig_value)) { zend_string_release(EG(error_reporting_ini_entry)->value); } - EG(error_reporting_ini_entry)->value = zend_string_init(res, buf + sizeof(buf) - 1 - res, 0); - } + EG(error_reporting_ini_entry)->value = Z_STR_P(EX_VAR(opline->op1.var)); + if (Z_TYPE(EX(old_error_reporting)) != IS_UNDEF && + Z_STR(EX(old_error_reporting)) == EG(error_reporting_ini_entry)->value) { + ZVAL_UNDEF(&EX(old_error_reporting)); + } + } + } else { + if (EXPECTED(Z_TYPE_P(EX_VAR(opline->op1.var)) == IS_STRING)) { + zend_string_release(Z_STR_P(EX_VAR(opline->op1.var))); + if (Z_TYPE(EX(old_error_reporting)) != IS_UNDEF && + Z_STR(EX(old_error_reporting)) == Z_STR_P(EX_VAR(opline->op1.var))) { + ZVAL_UNDEF(&EX(old_error_reporting)); + } + } } -//??? if (EX(old_error_reporting) == EX_VAR(opline->op1.var)) { -//??? EX(old_error_reporting) = NULL; -//??? } - CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -5472,18 +5481,19 @@ ZEND_VM_HANDLER(149, ZEND_HANDLE_EXCEPTION, ANY, ANY) } /* restore previous error_reporting value */ - if (!EG(error_reporting) && Z_TYPE(EX(old_error_reporting)) != IS_UNDEF && Z_LVAL(EX(old_error_reporting)) != 0) { - zval restored_error_reporting; - zend_string *key; - - ZVAL_LONG(&restored_error_reporting, Z_LVAL(EX(old_error_reporting))); - convert_to_string(&restored_error_reporting); - key = zend_string_init("error_reporting", sizeof("error_reporting")-1, 0); - zend_alter_ini_entry_ex(key, Z_STR(restored_error_reporting), ZEND_INI_USER, ZEND_INI_STAGE_RUNTIME, 1 TSRMLS_CC); - zend_string_free(key); - zval_dtor(&restored_error_reporting); - } - ZVAL_UNDEF(&EX(old_error_reporting)); + if (Z_TYPE(EX(old_error_reporting)) != IS_UNDEF) { + if (!EG(error_reporting)) { + zend_string *key; + + key = zend_string_init("error_reporting", sizeof("error_reporting")-1, 0); + zend_alter_ini_entry_ex(key, Z_STR(EX(old_error_reporting)), ZEND_INI_USER, ZEND_INI_STAGE_RUNTIME, 1 TSRMLS_CC); + zend_string_free(key); + } + if (Z_STR(EX(old_error_reporting))) { + zend_string_release(Z_STR(EX(old_error_reporting))); + } + ZVAL_UNDEF(&EX(old_error_reporting)); + } if (finally_op_num && (!catch_op_num || catch_op_num >= finally_op_num)) { if (EX(delayed_exception)) { diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index 6110c81810..2118904616 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -1108,22 +1108,27 @@ static int ZEND_FASTCALL ZEND_BEGIN_SILENCE_SPEC_HANDLER(ZEND_OPCODE_HANDLER_AR USE_OPLINE SAVE_OPLINE(); - ZVAL_LONG(EX_VAR(opline->result.var), EG(error_reporting)); - if (Z_TYPE(EX(old_error_reporting)) == IS_UNDEF) { - ZVAL_LONG(&EX(old_error_reporting), EG(error_reporting)); - } - if (EG(error_reporting)) { - do { - EG(error_reporting) = 0; - if (!EG(error_reporting_ini_entry)) { - zend_ini_entry *p = zend_hash_str_find_ptr(EG(ini_directives), "error_reporting", sizeof("error_reporting")-1); - if (p) { - EG(error_reporting_ini_entry) = p; - } else { - break; - } + EX_VAR(opline->result.var)->u2.error_reporting = EG(error_reporting); + do { + if (!EG(error_reporting_ini_entry)) { + zend_ini_entry *p = zend_hash_str_find_ptr(EG(ini_directives), "error_reporting", sizeof("error_reporting")-1); + if (p) { + EG(error_reporting_ini_entry) = p; + } else { + EG(error_reporting) = 0; + break; } + } + ZVAL_NEW_STR(EX_VAR(opline->result.var), EG(error_reporting_ini_entry)->value); + if (EG(error_reporting_ini_entry)->value) { + zend_string_addref(EG(error_reporting_ini_entry)->value); + } + if (Z_TYPE(EX(old_error_reporting)) == IS_UNDEF) { + ZVAL_NEW_STR(&EX(old_error_reporting), EG(error_reporting_ini_entry)->value); + } + if (EG(error_reporting)) { + EG(error_reporting) = 0; if (!EG(error_reporting_ini_entry)->modified) { if (!EG(modified_ini_directives)) { ALLOC_HASHTABLE(EG(modified_ini_directives)); @@ -1142,9 +1147,8 @@ static int ZEND_FASTCALL ZEND_BEGIN_SILENCE_SPEC_HANDLER(ZEND_OPCODE_HANDLER_AR } else { EG(error_reporting_ini_entry)->value = zend_string_init("0", sizeof("0")-1, 0); } - } while (0); - } - CHECK_EXCEPTION(); + } + } while (0); ZEND_VM_NEXT_OPCODE(); } @@ -1367,18 +1371,19 @@ static int ZEND_FASTCALL ZEND_HANDLE_EXCEPTION_SPEC_HANDLER(ZEND_OPCODE_HANDLER } /* restore previous error_reporting value */ - if (!EG(error_reporting) && Z_TYPE(EX(old_error_reporting)) != IS_UNDEF && Z_LVAL(EX(old_error_reporting)) != 0) { - zval restored_error_reporting; - zend_string *key; + if (Z_TYPE(EX(old_error_reporting)) != IS_UNDEF) { + if (!EG(error_reporting)) { + zend_string *key; - ZVAL_LONG(&restored_error_reporting, Z_LVAL(EX(old_error_reporting))); - convert_to_string(&restored_error_reporting); - key = zend_string_init("error_reporting", sizeof("error_reporting")-1, 0); - zend_alter_ini_entry_ex(key, Z_STR(restored_error_reporting), ZEND_INI_USER, ZEND_INI_STAGE_RUNTIME, 1 TSRMLS_CC); - zend_string_free(key); - zval_dtor(&restored_error_reporting); + key = zend_string_init("error_reporting", sizeof("error_reporting")-1, 0); + zend_alter_ini_entry_ex(key, Z_STR(EX(old_error_reporting)), ZEND_INI_USER, ZEND_INI_STAGE_RUNTIME, 1 TSRMLS_CC); + zend_string_free(key); + } + if (Z_STR(EX(old_error_reporting))) { + zend_string_release(Z_STR(EX(old_error_reporting))); + } + ZVAL_UNDEF(&EX(old_error_reporting)); } - ZVAL_UNDEF(&EX(old_error_reporting)); if (finally_op_num && (!catch_op_num || catch_op_num >= finally_op_num)) { if (EX(delayed_exception)) { @@ -10032,25 +10037,30 @@ static int ZEND_FASTCALL ZEND_EXIT_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) static int ZEND_FASTCALL ZEND_END_SILENCE_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - char buf[MAX_LENGTH_OF_LONG + 1]; - char *res; SAVE_OPLINE(); - if (!EG(error_reporting) && Z_LVAL_P(EX_VAR(opline->op1.var)) != 0) { - EG(error_reporting) = Z_LVAL_P(EX_VAR(opline->op1.var)); - _zend_print_signed_to_buf(buf + sizeof(buf) - 1, EG(error_reporting), zend_ulong, res); - if (EXPECTED(EG(error_reporting_ini_entry) != NULL)) { + if (!EG(error_reporting)) { + EG(error_reporting) = EX_VAR(opline->op1.var)->u2.error_reporting; + if (EXPECTED(Z_TYPE_P(EX_VAR(opline->op1.var)) == IS_STRING)) { if (EXPECTED(EG(error_reporting_ini_entry)->modified && EG(error_reporting_ini_entry)->value != EG(error_reporting_ini_entry)->orig_value)) { zend_string_release(EG(error_reporting_ini_entry)->value); } - EG(error_reporting_ini_entry)->value = zend_string_init(res, buf + sizeof(buf) - 1 - res, 0); + EG(error_reporting_ini_entry)->value = Z_STR_P(EX_VAR(opline->op1.var)); + if (Z_TYPE(EX(old_error_reporting)) != IS_UNDEF && + Z_STR(EX(old_error_reporting)) == EG(error_reporting_ini_entry)->value) { + ZVAL_UNDEF(&EX(old_error_reporting)); + } + } + } else { + if (EXPECTED(Z_TYPE_P(EX_VAR(opline->op1.var)) == IS_STRING)) { + zend_string_release(Z_STR_P(EX_VAR(opline->op1.var))); + if (Z_TYPE(EX(old_error_reporting)) != IS_UNDEF && + Z_STR(EX(old_error_reporting)) == Z_STR_P(EX_VAR(opline->op1.var))) { + ZVAL_UNDEF(&EX(old_error_reporting)); + } } } -//??? if (EX(old_error_reporting) == EX_VAR(opline->op1.var)) { -//??? EX(old_error_reporting) = NULL; -//??? } - CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } -- 2.40.0