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

Reply via email to