]> granicus.if.org Git - php/commitdiff
improved performance of @ (silence) operator
authorDmitry Stogov <dmitry@php.net>
Wed, 18 Aug 2010 13:58:13 +0000 (13:58 +0000)
committerDmitry Stogov <dmitry@php.net>
Wed, 18 Aug 2010 13:58:13 +0000 (13:58 +0000)
NEWS
Zend/zend_globals.h
Zend/zend_ini.c
Zend/zend_ini.h
Zend/zend_vm_def.h
Zend/zend_vm_execute.h

diff --git a/NEWS b/NEWS
index 3d5454f9f2be643b4ab7ef24bf4e44b1af364243..d4c448531bc53c226487c7f0a0cc2b590ba29d85 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -26,6 +26,7 @@
     flag any more. Thit is very rare and useless case. ZEND_FREE might be
     required after them instead.
   . improved performance of FastCGI request parsing
+  . improved performance of @ (silence) operator
 - Added concept of interned strings. All strings constants known at compile
   time are allocated in a single copy and never changed. (Dmitry)
 - Added an optimization which saves memory and emalloc/efree calls for empty
index 444670578008f424eb042e0caec91e285d863494..dfc8075bdddb94da781cd7878fe96a53af2252f4 100644 (file)
@@ -69,6 +69,8 @@ typedef struct _zend_declarables {
 } zend_declarables;
 
 typedef struct _zend_vm_stack *zend_vm_stack;
+typedef struct _zend_ini_entry zend_ini_entry;
+
 
 struct _zend_compiler_globals {
        zend_stack bp_stack;
@@ -248,6 +250,7 @@ struct _zend_executor_globals {
 
        HashTable *ini_directives;
        HashTable *modified_ini_directives;
+       zend_ini_entry *error_reporting_ini_entry;                      
 
        zend_objects_store objects_store;
        zval *exception, *prev_exception;
index 60af9acf407bc27d78ec0e0aa8b238c1740a7b4f..f30f01a5e1a1590837530da97b0543d82c68aa78 100644 (file)
@@ -92,6 +92,7 @@ ZEND_API int zend_ini_startup(TSRMLS_D) /* {{{ */
 
        EG(ini_directives) = registered_zend_ini_directives;
        EG(modified_ini_directives) = NULL;
+       EG(error_reporting_ini_entry) = NULL;
        if (zend_hash_init_ex(registered_zend_ini_directives, 100, NULL, NULL, 1, 0) == FAILURE) {
                return FAILURE;
        }
@@ -133,6 +134,7 @@ ZEND_API int zend_copy_ini_directives(TSRMLS_D) /* {{{ */
        zend_ini_entry ini_entry;
 
        EG(modified_ini_directives) = NULL;
+       EG(error_reporting_ini_entry) = NULL;
        EG(ini_directives) = (HashTable *) malloc(sizeof(HashTable));
        if (zend_hash_init_ex(EG(ini_directives), registered_zend_ini_directives->nNumOfElements, NULL, NULL, 1, 0) == FAILURE) {
                return FAILURE;
index ccc5414632ebd29681737f393ea3541c8fd8914c..397dbaef210b687d5edd18c1fca18ccf844a83c5 100644 (file)
@@ -57,8 +57,6 @@
 
 #endif
 
-typedef struct _zend_ini_entry zend_ini_entry;
-
 #define ZEND_INI_MH(name) int name(zend_ini_entry *entry, char *new_value, uint new_value_length, void *mh_arg1, void *mh_arg2, void *mh_arg3, int stage TSRMLS_DC)
 #define ZEND_INI_DISP(name) void name(zend_ini_entry *ini_entry, int type)
 
index f25599f5bcee2ab04837c90340a347a34d36a3ad..bae4c995ff350dabea9bdd221d5ac47798c49a76 100644 (file)
@@ -4520,7 +4520,30 @@ ZEND_VM_HANDLER(57, ZEND_BEGIN_SILENCE, ANY, ANY)
        }
 
        if (EG(error_reporting)) {
-               zend_alter_ini_entry_ex("error_reporting", sizeof("error_reporting"), "0", 1, ZEND_INI_USER, ZEND_INI_STAGE_RUNTIME, 1 TSRMLS_CC);
+               do {
+                       EG(error_reporting) = 0;
+                       if (!EG(error_reporting_ini_entry)) {
+                               if (UNEXPECTED(zend_hash_find(EG(ini_directives), "error_reporting", sizeof("error_reporting"), (void **) &EG(error_reporting_ini_entry)) == FAILURE)) {
+                                       break;
+                               }
+                       }
+                       if (!EG(error_reporting_ini_entry)->modified) {
+                               if (!EG(modified_ini_directives)) {
+                                       ALLOC_HASHTABLE(EG(modified_ini_directives));
+                                       zend_hash_init(EG(modified_ini_directives), 8, NULL, NULL, 0);
+                               }
+                               if (EXPECTED(zend_hash_add(EG(modified_ini_directives), "error_reporting", sizeof("error_reporting"), &EG(error_reporting_ini_entry), sizeof(zend_ini_entry*), NULL) == SUCCESS)) {
+                                       EG(error_reporting_ini_entry)->orig_value = EG(error_reporting_ini_entry)->value;
+                                       EG(error_reporting_ini_entry)->orig_value_length = EG(error_reporting_ini_entry)->value_length;
+                                       EG(error_reporting_ini_entry)->orig_modifiable = EG(error_reporting_ini_entry)->modifiable;
+                                       EG(error_reporting_ini_entry)->modified = 1;
+                               }
+                       } else if (EG(error_reporting_ini_entry)->value != EG(error_reporting_ini_entry)->orig_value) {
+                               efree(EG(error_reporting_ini_entry)->value);
+                       }
+                       EG(error_reporting_ini_entry)->value = estrndup("0", sizeof("0")-1);
+                       EG(error_reporting_ini_entry)->value_length = sizeof("0")-1;
+               } while (0);
        }
        CHECK_EXCEPTION();
        ZEND_VM_NEXT_OPCODE();
@@ -4542,9 +4565,18 @@ ZEND_VM_HANDLER(58, ZEND_END_SILENCE, TMP, ANY)
        if (!EG(error_reporting) && Z_LVAL(EX_T(opline->op1.var).tmp_var) != 0) {
                Z_TYPE(restored_error_reporting) = IS_LONG;
                Z_LVAL(restored_error_reporting) = Z_LVAL(EX_T(opline->op1.var).tmp_var);
+               EG(error_reporting) = Z_LVAL(restored_error_reporting);
                convert_to_string(&restored_error_reporting);
-               zend_alter_ini_entry_ex("error_reporting", sizeof("error_reporting"), Z_STRVAL(restored_error_reporting), Z_STRLEN(restored_error_reporting), ZEND_INI_USER, ZEND_INI_STAGE_RUNTIME, 1 TSRMLS_CC);
-               zendi_zval_dtor(restored_error_reporting);
+               if (EXPECTED(EG(error_reporting_ini_entry) != NULL)) {
+                       if (EXPECTED(EG(error_reporting_ini_entry)->modified &&
+                           EG(error_reporting_ini_entry)->value != EG(error_reporting_ini_entry)->orig_value)) {
+                               efree(EG(error_reporting_ini_entry)->value);
+                       }
+                       EG(error_reporting_ini_entry)->value = Z_STRVAL(restored_error_reporting);
+                       EG(error_reporting_ini_entry)->value_length = Z_STRLEN(restored_error_reporting);
+               } else {
+                       zendi_zval_dtor(restored_error_reporting);
+               }
        }
        if (EX(old_error_reporting) == &EX_T(opline->op1.var).tmp_var) {
                EX(old_error_reporting) = NULL;
index 87cbfbc5f21d3f7fe42563ecbca4cb0441c6d063..3b07493c526f38455f4827b280f7705dc86b2572 100644 (file)
@@ -848,7 +848,30 @@ static int ZEND_FASTCALL  ZEND_BEGIN_SILENCE_SPEC_HANDLER(ZEND_OPCODE_HANDLER_AR
        }
 
        if (EG(error_reporting)) {
-               zend_alter_ini_entry_ex("error_reporting", sizeof("error_reporting"), "0", 1, ZEND_INI_USER, ZEND_INI_STAGE_RUNTIME, 1 TSRMLS_CC);
+               do {
+                       EG(error_reporting) = 0;
+                       if (!EG(error_reporting_ini_entry)) {
+                               if (UNEXPECTED(zend_hash_find(EG(ini_directives), "error_reporting", sizeof("error_reporting"), (void **) &EG(error_reporting_ini_entry)) == FAILURE)) {
+                                       break;
+                               }
+                       }
+                       if (!EG(error_reporting_ini_entry)->modified) {
+                               if (!EG(modified_ini_directives)) {
+                                       ALLOC_HASHTABLE(EG(modified_ini_directives));
+                                       zend_hash_init(EG(modified_ini_directives), 8, NULL, NULL, 0);
+                               }
+                               if (EXPECTED(zend_hash_add(EG(modified_ini_directives), "error_reporting", sizeof("error_reporting"), &EG(error_reporting_ini_entry), sizeof(zend_ini_entry*), NULL) == SUCCESS)) {
+                                       EG(error_reporting_ini_entry)->orig_value = EG(error_reporting_ini_entry)->value;
+                                       EG(error_reporting_ini_entry)->orig_value_length = EG(error_reporting_ini_entry)->value_length;
+                                       EG(error_reporting_ini_entry)->orig_modifiable = EG(error_reporting_ini_entry)->modifiable;
+                                       EG(error_reporting_ini_entry)->modified = 1;
+                               }
+                       } else if (EG(error_reporting_ini_entry)->value != EG(error_reporting_ini_entry)->orig_value) {
+                               efree(EG(error_reporting_ini_entry)->value);
+                       }
+                       EG(error_reporting_ini_entry)->value = estrndup("0", sizeof("0")-1);
+                       EG(error_reporting_ini_entry)->value_length = sizeof("0")-1;
+               } while (0);
        }
        CHECK_EXCEPTION();
        ZEND_VM_NEXT_OPCODE();
@@ -6898,9 +6921,18 @@ static int ZEND_FASTCALL  ZEND_END_SILENCE_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_
        if (!EG(error_reporting) && Z_LVAL(EX_T(opline->op1.var).tmp_var) != 0) {
                Z_TYPE(restored_error_reporting) = IS_LONG;
                Z_LVAL(restored_error_reporting) = Z_LVAL(EX_T(opline->op1.var).tmp_var);
+               EG(error_reporting) = Z_LVAL(restored_error_reporting);
                convert_to_string(&restored_error_reporting);
-               zend_alter_ini_entry_ex("error_reporting", sizeof("error_reporting"), Z_STRVAL(restored_error_reporting), Z_STRLEN(restored_error_reporting), ZEND_INI_USER, ZEND_INI_STAGE_RUNTIME, 1 TSRMLS_CC);
-               zendi_zval_dtor(restored_error_reporting);
+               if (EXPECTED(EG(error_reporting_ini_entry) != NULL)) {
+                       if (EXPECTED(EG(error_reporting_ini_entry)->modified &&
+                           EG(error_reporting_ini_entry)->value != EG(error_reporting_ini_entry)->orig_value)) {
+                               efree(EG(error_reporting_ini_entry)->value);
+                       }
+                       EG(error_reporting_ini_entry)->value = Z_STRVAL(restored_error_reporting);
+                       EG(error_reporting_ini_entry)->value_length = Z_STRLEN(restored_error_reporting);
+               } else {
+                       zendi_zval_dtor(restored_error_reporting);
+               }
        }
        if (EX(old_error_reporting) == &EX_T(opline->op1.var).tmp_var) {
                EX(old_error_reporting) = NULL;