Hei,
I backported Marcus' performance-improvement-when-not-using-a-key-in-foreach
patch to 4.3 and attached it. I am planning to commit this after 4.3.9
is released. If there are any comments, please let me know.
Derick
--
Derick Rethans
http://derickrethans.nl | http://ez.no | http://xdebug.org
? php_test_results_20040914.txt
? ext/gd/testsbug27582.png
? ext/tokenizer/tests/bug26463.diff
? ext/tokenizer/tests/bug26463.exp
? ext/tokenizer/tests/bug26463.log
? ext/tokenizer/tests/bug26463.out
? ext/tokenizer/tests/bug26463.php
Index: Zend/zend_compile.c
===================================================================
RCS file: /repository/Zend/Attic/zend_compile.c,v
retrieving revision 1.240.2.7
diff -u -p -r1.240.2.7 zend_compile.c
--- Zend/zend_compile.c 29 Aug 2004 16:51:09 -0000 1.240.2.7
+++ Zend/zend_compile.c 14 Sep 2004 11:10:58 -0000
@@ -2147,9 +2147,9 @@ void zend_do_foreach_begin(znode *foreac
}
-void zend_do_foreach_cont(znode *value, znode *key, znode *as_token TSRMLS_DC)
+void zend_do_foreach_cont(znode *value, znode *key, znode *as_token, znode
*foreach_token TSRMLS_DC)
{
- zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
+ zend_op *opline;
znode result_value, result_key, dummy;
if (key->op_type != IS_UNUSED) {
@@ -2159,18 +2159,10 @@ void zend_do_foreach_cont(znode *value,
tmp = key;
key = value;
value = tmp;
- }
- opline->opcode = ZEND_FETCH_DIM_TMP_VAR;
- opline->result.op_type = IS_VAR;
- opline->result.u.EA.type = 0;
- opline->result.u.opline_num = get_temporary_variable(CG(active_op_array));
- opline->op1 = *as_token;
- opline->op2.op_type = IS_CONST;
- opline->op2.u.constant.type = IS_LONG;
- opline->op2.u.constant.value.lval = 0;
- opline->extended_value = ZEND_FETCH_STANDARD; /* ignored in fetch_dim_tmp_var,
but what the hell. */
- result_value = opline->result;
+ /* Mark extended_value in case both key and value are being used */
+
CG(active_op_array)->opcodes[foreach_token->u.opline_num].extended_value |=
ZEND_FE_FETCH_WITH_KEY;
+ }
if (key->op_type != IS_UNUSED) {
opline = get_next_op(CG(active_op_array) TSRMLS_CC);
@@ -2181,9 +2173,23 @@ void zend_do_foreach_cont(znode *value,
opline->op1 = *as_token;
opline->op2.op_type = IS_CONST;
opline->op2.u.constant.type = IS_LONG;
+ opline->op2.u.constant.value.lval = 0;
+ opline->extended_value = ZEND_FETCH_STANDARD; /* ignored in
fetch_dim_tmp_var, but what the hell. */
+ result_value = opline->result;
+
+ opline = get_next_op(CG(active_op_array) TSRMLS_CC);
+ opline->opcode = ZEND_FETCH_DIM_TMP_VAR;
+ opline->result.op_type = IS_VAR;
+ opline->result.u.EA.type = 0;
+ opline->result.u.opline_num =
get_temporary_variable(CG(active_op_array));
+ opline->op1 = *as_token;
+ opline->op2.op_type = IS_CONST;
+ opline->op2.u.constant.type = IS_LONG;
opline->op2.u.constant.value.lval = 1;
opline->extended_value = ZEND_FETCH_STANDARD; /* ignored in
fetch_dim_tmp_var, but what the hell. */
result_key = opline->result;
+ } else {
+ result_value =
CG(active_op_array)->opcodes[foreach_token->u.opline_num].result;
}
zend_do_assign(&dummy, value, &result_value TSRMLS_CC);
@@ -2191,8 +2197,8 @@ void zend_do_foreach_cont(znode *value,
if (key->op_type != IS_UNUSED) {
zend_do_assign(&dummy, key, &result_key TSRMLS_CC);
CG(active_op_array)->opcodes[CG(active_op_array)->last-1].result.u.EA.type |=
EXT_TYPE_UNUSED;
+ zend_do_free(as_token TSRMLS_CC);
}
- zend_do_free(as_token TSRMLS_CC);
do_begin_loop(TSRMLS_C);
INC_BPC(CG(active_op_array));
Index: Zend/zend_compile.h
===================================================================
RCS file: /repository/Zend/Attic/zend_compile.h,v
retrieving revision 1.144.4.5
diff -u -p -r1.144.4.5 zend_compile.h
--- Zend/zend_compile.h 31 May 2003 01:37:43 -0000 1.144.4.5
+++ Zend/zend_compile.h 14 Sep 2004 11:10:58 -0000
@@ -326,7 +326,7 @@ void zend_do_unset(znode *variable TSRML
void zend_do_isset_or_isempty(int type, znode *result, znode *variable TSRMLS_DC);
void zend_do_foreach_begin(znode *foreach_token, znode *array, znode
*open_brackets_token, znode *as_token, int variable TSRMLS_DC);
-void zend_do_foreach_cont(znode *value, znode *key, znode *as_token TSRMLS_DC);
+void zend_do_foreach_cont(znode *value, znode *key, znode *as_token, znode
*foreach_token TSRMLS_DC);
void zend_do_foreach_end(znode *foreach_token, znode *open_brackets_token TSRMLS_DC);
void zend_do_declare_begin(TSRMLS_D);
@@ -577,6 +577,9 @@ int zendlex(znode *zendlval TSRMLS_DC);
#define ZEND_FETCH_STANDARD 0
#define ZEND_FETCH_ADD_LOCK 1
+#define ZEND_FE_FETCH_BYREF 1
+#define ZEND_FE_FETCH_WITH_KEY 2
+
#define ZEND_MEMBER_FUNC_CALL 1<<0
#define ZEND_CTOR_CALL 1<<1
Index: Zend/zend_execute.c
===================================================================
RCS file: /repository/Zend/Attic/zend_execute.c,v
retrieving revision 1.316.2.39
diff -u -p -r1.316.2.39 zend_execute.c
--- Zend/zend_execute.c 2 Aug 2004 02:35:05 -0000 1.316.2.39
+++ Zend/zend_execute.c 14 Sep 2004 11:10:58 -0000
@@ -2350,13 +2350,14 @@ send_by_ref:
}
NEXT_OPCODE();
case ZEND_FE_FETCH: {
- zval *array = get_zval_ptr(&EX(opline)->op1,
EX(Ts), &EG(free_op1), BP_VAR_R);
- zval *result =
&EX(Ts)[EX(opline)->result.u.var].tmp_var;
+ zend_op *opline = EX(opline);
+ zval *array = get_zval_ptr(&opline->op1,
EX(Ts), &EG(free_op1), BP_VAR_R);
zval **value, *key;
char *str_key;
uint str_key_len;
ulong int_key;
HashTable *fe_ht;
+ zend_bool use_key = opline->extended_value &
ZEND_FE_FETCH_WITH_KEY;
PZVAL_LOCK(array);
@@ -2370,27 +2371,33 @@ send_by_ref:
EX(opline) =
op_array->opcodes+EX(opline)->op2.u.opline_num;
continue;
}
- array_init(result);
+ zval *result =
&EX(Ts)[opline->result.u.var].tmp_var;
+ if (!use_key) {
+ *result = **value;
+ zval_copy_ctor(result);
+ } else {
+ array_init(result);
- (*value)->refcount++;
- zend_hash_index_update(result->value.ht, 0,
value, sizeof(zval *), NULL);
+ (*value)->refcount++;
+
zend_hash_index_update(result->value.ht, 0, value, sizeof(zval *), NULL);
- ALLOC_ZVAL(key);
- INIT_PZVAL(key);
- switch (zend_hash_get_current_key_ex(fe_ht,
&str_key, &str_key_len, &int_key, 1, NULL)) {
- case HASH_KEY_IS_STRING:
- key->value.str.val = str_key;
- key->value.str.len =
str_key_len-1;
- key->type = IS_STRING;
- break;
- case HASH_KEY_IS_LONG:
- key->value.lval = int_key;
- key->type = IS_LONG;
- break;
- EMPTY_SWITCH_DEFAULT_CASE()
+ ALLOC_ZVAL(key);
+ INIT_PZVAL(key);
+ switch
(zend_hash_get_current_key_ex(fe_ht, &str_key, &str_key_len, &int_key, 1, NULL)) {
+ case HASH_KEY_IS_STRING:
+ key->value.str.val =
str_key;
+ key->value.str.len =
str_key_len-1;
+ key->type = IS_STRING;
+ break;
+ case HASH_KEY_IS_LONG:
+ key->value.lval =
int_key;
+ key->type = IS_LONG;
+ break;
+ EMPTY_SWITCH_DEFAULT_CASE()
+ }
+
zend_hash_index_update(result->value.ht, 1, &key, sizeof(zval *), NULL);
}
- zend_hash_index_update(result->value.ht, 1,
&key, sizeof(zval *), NULL);
zend_hash_move_forward(fe_ht);
}
NEXT_OPCODE();
Index: Zend/zend_language_parser.y
===================================================================
RCS file: /repository/Zend/Attic/zend_language_parser.y,v
retrieving revision 1.23
diff -u -p -r1.23 zend_language_parser.y
--- Zend/zend_language_parser.y 4 Aug 2002 06:39:44 -0000 1.23
+++ Zend/zend_language_parser.y 14 Sep 2004 11:10:58 -0000
@@ -199,8 +199,8 @@ unticked_statement:
| expr ';' { zend_do_free(&$1 TSRMLS_CC);
}
| T_USE use_filename ';' { zend_error(E_COMPILE_ERROR,"use: Not
yet supported. Please use include_once() or require_once()");
zval_dtor(&$2.u.constant); }
| T_UNSET '(' unset_variables ')' ';'
- | T_FOREACH '(' w_cvar T_AS { zend_do_foreach_begin(&$1, &$3, &$2, &$4,
1 TSRMLS_CC); } w_cvar foreach_optional_arg ')' { zend_do_foreach_cont(&$6, &$7, &$4
TSRMLS_CC); } foreach_statement { zend_do_foreach_end(&$1, &$2 TSRMLS_CC); }
- | T_FOREACH '(' expr_without_variable T_AS { zend_do_foreach_begin(&$1,
&$3, &$2, &$4, 0 TSRMLS_CC); } w_cvar foreach_optional_arg ')' {
zend_do_foreach_cont(&$6, &$7, &$4 TSRMLS_CC); } foreach_statement {
zend_do_foreach_end(&$1, &$2 TSRMLS_CC); }
+ | T_FOREACH '(' w_cvar T_AS { zend_do_foreach_begin(&$1, &$3, &$2, &$4,
1 TSRMLS_CC); } w_cvar foreach_optional_arg ')' { zend_do_foreach_cont(&$6, &$7, &$4,
&$1 TSRMLS_CC); } foreach_statement { zend_do_foreach_end(&$1, &$2 TSRMLS_CC); }
+ | T_FOREACH '(' expr_without_variable T_AS { zend_do_foreach_begin(&$1,
&$3, &$2, &$4, 0 TSRMLS_CC); } w_cvar foreach_optional_arg ')' {
zend_do_foreach_cont(&$6, &$7, &$4, &$1 TSRMLS_CC); } foreach_statement {
zend_do_foreach_end(&$1, &$2 TSRMLS_CC); }
| T_DECLARE { $1.u.opline_num = get_next_op_number(CG(active_op_array));
zend_do_declare_begin(TSRMLS_C); } '(' declare_list ')' declare_statement
{zend_do_declare_end(&$1 TSRMLS_CC); }
| ';' /* empty statement */
;
Index: ext/standard/array.c
===================================================================
RCS file: /repository/php-src/ext/standard/array.c,v
retrieving revision 1.199.2.36
diff -u -p -r1.199.2.36 array.c
--- ext/standard/array.c 10 Aug 2004 06:04:12 -0000 1.199.2.36
+++ ext/standard/array.c 14 Sep 2004 11:10:59 -0000
@@ -1712,7 +1712,7 @@ static void _phpi_pop(INTERNAL_FUNCTION_
zval **stack, /* Input stack */
**val; /* Value to be popped */
char *key = NULL;
- int key_len = 0;
+ uint key_len = 0;
ulong index;
/* Get the arguments and do error-checking */
Index: ext/standard/file.c
===================================================================
RCS file: /repository/php-src/ext/standard/file.c,v
retrieving revision 1.279.2.61
diff -u -p -r1.279.2.61 file.c
--- ext/standard/file.c 17 Aug 2004 14:10:03 -0000 1.279.2.61
+++ ext/standard/file.c 14 Sep 2004 11:11:00 -0000
@@ -909,7 +909,7 @@ static int parse_context_options(php_str
HashPosition pos, opos;
zval **wval, **oval;
char *wkey, *okey;
- int wkey_len, okey_len;
+ uint wkey_len, okey_len;
int ret = SUCCESS;
ulong num_key;
--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php