Skip to content

Commit 8a6d73b

Browse files
committed
improved performance of @ (silence) operator
1 parent 34b631f commit 8a6d73b

File tree

6 files changed

+76
-8
lines changed

6 files changed

+76
-8
lines changed

NEWS

+1
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
flag any more. Thit is very rare and useless case. ZEND_FREE might be
2727
required after them instead.
2828
. improved performance of FastCGI request parsing
29+
. improved performance of @ (silence) operator
2930
- Added concept of interned strings. All strings constants known at compile
3031
time are allocated in a single copy and never changed. (Dmitry)
3132
- Added an optimization which saves memory and emalloc/efree calls for empty

Zend/zend_globals.h

+3
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,8 @@ typedef struct _zend_declarables {
6969
} zend_declarables;
7070

7171
typedef struct _zend_vm_stack *zend_vm_stack;
72+
typedef struct _zend_ini_entry zend_ini_entry;
73+
7274

7375
struct _zend_compiler_globals {
7476
zend_stack bp_stack;
@@ -248,6 +250,7 @@ struct _zend_executor_globals {
248250

249251
HashTable *ini_directives;
250252
HashTable *modified_ini_directives;
253+
zend_ini_entry *error_reporting_ini_entry;
251254

252255
zend_objects_store objects_store;
253256
zval *exception, *prev_exception;

Zend/zend_ini.c

+2
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@ ZEND_API int zend_ini_startup(TSRMLS_D) /* {{{ */
9292

9393
EG(ini_directives) = registered_zend_ini_directives;
9494
EG(modified_ini_directives) = NULL;
95+
EG(error_reporting_ini_entry) = NULL;
9596
if (zend_hash_init_ex(registered_zend_ini_directives, 100, NULL, NULL, 1, 0) == FAILURE) {
9697
return FAILURE;
9798
}
@@ -133,6 +134,7 @@ ZEND_API int zend_copy_ini_directives(TSRMLS_D) /* {{{ */
133134
zend_ini_entry ini_entry;
134135

135136
EG(modified_ini_directives) = NULL;
137+
EG(error_reporting_ini_entry) = NULL;
136138
EG(ini_directives) = (HashTable *) malloc(sizeof(HashTable));
137139
if (zend_hash_init_ex(EG(ini_directives), registered_zend_ini_directives->nNumOfElements, NULL, NULL, 1, 0) == FAILURE) {
138140
return FAILURE;

Zend/zend_ini.h

-2
Original file line numberDiff line numberDiff line change
@@ -57,8 +57,6 @@
5757

5858
#endif
5959

60-
typedef struct _zend_ini_entry zend_ini_entry;
61-
6260
#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)
6361
#define ZEND_INI_DISP(name) void name(zend_ini_entry *ini_entry, int type)
6462

Zend/zend_vm_def.h

+35-3
Original file line numberDiff line numberDiff line change
@@ -4520,7 +4520,30 @@ ZEND_VM_HANDLER(57, ZEND_BEGIN_SILENCE, ANY, ANY)
45204520
}
45214521

45224522
if (EG(error_reporting)) {
4523-
zend_alter_ini_entry_ex("error_reporting", sizeof("error_reporting"), "0", 1, ZEND_INI_USER, ZEND_INI_STAGE_RUNTIME, 1 TSRMLS_CC);
4523+
do {
4524+
EG(error_reporting) = 0;
4525+
if (!EG(error_reporting_ini_entry)) {
4526+
if (UNEXPECTED(zend_hash_find(EG(ini_directives), "error_reporting", sizeof("error_reporting"), (void **) &EG(error_reporting_ini_entry)) == FAILURE)) {
4527+
break;
4528+
}
4529+
}
4530+
if (!EG(error_reporting_ini_entry)->modified) {
4531+
if (!EG(modified_ini_directives)) {
4532+
ALLOC_HASHTABLE(EG(modified_ini_directives));
4533+
zend_hash_init(EG(modified_ini_directives), 8, NULL, NULL, 0);
4534+
}
4535+
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)) {
4536+
EG(error_reporting_ini_entry)->orig_value = EG(error_reporting_ini_entry)->value;
4537+
EG(error_reporting_ini_entry)->orig_value_length = EG(error_reporting_ini_entry)->value_length;
4538+
EG(error_reporting_ini_entry)->orig_modifiable = EG(error_reporting_ini_entry)->modifiable;
4539+
EG(error_reporting_ini_entry)->modified = 1;
4540+
}
4541+
} else if (EG(error_reporting_ini_entry)->value != EG(error_reporting_ini_entry)->orig_value) {
4542+
efree(EG(error_reporting_ini_entry)->value);
4543+
}
4544+
EG(error_reporting_ini_entry)->value = estrndup("0", sizeof("0")-1);
4545+
EG(error_reporting_ini_entry)->value_length = sizeof("0")-1;
4546+
} while (0);
45244547
}
45254548
CHECK_EXCEPTION();
45264549
ZEND_VM_NEXT_OPCODE();
@@ -4542,9 +4565,18 @@ ZEND_VM_HANDLER(58, ZEND_END_SILENCE, TMP, ANY)
45424565
if (!EG(error_reporting) && Z_LVAL(EX_T(opline->op1.var).tmp_var) != 0) {
45434566
Z_TYPE(restored_error_reporting) = IS_LONG;
45444567
Z_LVAL(restored_error_reporting) = Z_LVAL(EX_T(opline->op1.var).tmp_var);
4568+
EG(error_reporting) = Z_LVAL(restored_error_reporting);
45454569
convert_to_string(&restored_error_reporting);
4546-
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);
4547-
zendi_zval_dtor(restored_error_reporting);
4570+
if (EXPECTED(EG(error_reporting_ini_entry) != NULL)) {
4571+
if (EXPECTED(EG(error_reporting_ini_entry)->modified &&
4572+
EG(error_reporting_ini_entry)->value != EG(error_reporting_ini_entry)->orig_value)) {
4573+
efree(EG(error_reporting_ini_entry)->value);
4574+
}
4575+
EG(error_reporting_ini_entry)->value = Z_STRVAL(restored_error_reporting);
4576+
EG(error_reporting_ini_entry)->value_length = Z_STRLEN(restored_error_reporting);
4577+
} else {
4578+
zendi_zval_dtor(restored_error_reporting);
4579+
}
45484580
}
45494581
if (EX(old_error_reporting) == &EX_T(opline->op1.var).tmp_var) {
45504582
EX(old_error_reporting) = NULL;

Zend/zend_vm_execute.h

+35-3
Original file line numberDiff line numberDiff line change
@@ -848,7 +848,30 @@ static int ZEND_FASTCALL ZEND_BEGIN_SILENCE_SPEC_HANDLER(ZEND_OPCODE_HANDLER_AR
848848
}
849849

850850
if (EG(error_reporting)) {
851-
zend_alter_ini_entry_ex("error_reporting", sizeof("error_reporting"), "0", 1, ZEND_INI_USER, ZEND_INI_STAGE_RUNTIME, 1 TSRMLS_CC);
851+
do {
852+
EG(error_reporting) = 0;
853+
if (!EG(error_reporting_ini_entry)) {
854+
if (UNEXPECTED(zend_hash_find(EG(ini_directives), "error_reporting", sizeof("error_reporting"), (void **) &EG(error_reporting_ini_entry)) == FAILURE)) {
855+
break;
856+
}
857+
}
858+
if (!EG(error_reporting_ini_entry)->modified) {
859+
if (!EG(modified_ini_directives)) {
860+
ALLOC_HASHTABLE(EG(modified_ini_directives));
861+
zend_hash_init(EG(modified_ini_directives), 8, NULL, NULL, 0);
862+
}
863+
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)) {
864+
EG(error_reporting_ini_entry)->orig_value = EG(error_reporting_ini_entry)->value;
865+
EG(error_reporting_ini_entry)->orig_value_length = EG(error_reporting_ini_entry)->value_length;
866+
EG(error_reporting_ini_entry)->orig_modifiable = EG(error_reporting_ini_entry)->modifiable;
867+
EG(error_reporting_ini_entry)->modified = 1;
868+
}
869+
} else if (EG(error_reporting_ini_entry)->value != EG(error_reporting_ini_entry)->orig_value) {
870+
efree(EG(error_reporting_ini_entry)->value);
871+
}
872+
EG(error_reporting_ini_entry)->value = estrndup("0", sizeof("0")-1);
873+
EG(error_reporting_ini_entry)->value_length = sizeof("0")-1;
874+
} while (0);
852875
}
853876
CHECK_EXCEPTION();
854877
ZEND_VM_NEXT_OPCODE();
@@ -6898,9 +6921,18 @@ static int ZEND_FASTCALL ZEND_END_SILENCE_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_
68986921
if (!EG(error_reporting) && Z_LVAL(EX_T(opline->op1.var).tmp_var) != 0) {
68996922
Z_TYPE(restored_error_reporting) = IS_LONG;
69006923
Z_LVAL(restored_error_reporting) = Z_LVAL(EX_T(opline->op1.var).tmp_var);
6924+
EG(error_reporting) = Z_LVAL(restored_error_reporting);
69016925
convert_to_string(&restored_error_reporting);
6902-
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);
6903-
zendi_zval_dtor(restored_error_reporting);
6926+
if (EXPECTED(EG(error_reporting_ini_entry) != NULL)) {
6927+
if (EXPECTED(EG(error_reporting_ini_entry)->modified &&
6928+
EG(error_reporting_ini_entry)->value != EG(error_reporting_ini_entry)->orig_value)) {
6929+
efree(EG(error_reporting_ini_entry)->value);
6930+
}
6931+
EG(error_reporting_ini_entry)->value = Z_STRVAL(restored_error_reporting);
6932+
EG(error_reporting_ini_entry)->value_length = Z_STRLEN(restored_error_reporting);
6933+
} else {
6934+
zendi_zval_dtor(restored_error_reporting);
6935+
}
69046936
}
69056937
if (EX(old_error_reporting) == &EX_T(opline->op1.var).tmp_var) {
69066938
EX(old_error_reporting) = NULL;

0 commit comments

Comments
 (0)