Hey,

is it possibleto port this back to PHP 4.3?

Derick

---------- Forwarded message ----------
Date: Thu, 12 Aug 2004 05:41:02 -0000
From: Andi Gutmans <[EMAIL PROTECTED]>
To: [EMAIL PROTECTED]
Subject: [ZEND-ENGINE-CVS] cvs: ZendEngine2 / zend_compile.c zend_execute.c


andi            Thu Aug 12 01:41:02 2004 EDT

  Modified files:
    /ZendEngine2        zend_compile.c zend_execute.c
  Log:
  - Significantly improve performance of foreach($arr as $data). (Marcus)

http://cvs.php.net/diff.php/ZendEngine2/zend_compile.c?r1=1.574&r2=1.575&ty=u
Index: ZendEngine2/zend_compile.c
diff -u ZendEngine2/zend_compile.c:1.574 ZendEngine2/zend_compile.c:1.575
--- ZendEngine2/zend_compile.c:1.574    Mon Aug  2 18:41:34 2004
+++ ZendEngine2/zend_compile.c  Thu Aug 12 01:41:01 2004
@@ -17,7 +17,7 @@
    +----------------------------------------------------------------------+
 */
 
-/* $Id: zend_compile.c,v 1.574 2004/08/02 22:41:34 helly Exp $ */
+/* $Id: zend_compile.c,v 1.575 2004/08/12 05:41:01 andi Exp $ */
 
 #include "zend_language_parser.h"
 #include "zend.h"
@@ -3340,7 +3340,7 @@
 
 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;
        zend_bool assign_by_ref=0;
 
@@ -3351,6 +3351,9 @@
                tmp = key;
                key = value;
                value = tmp;
+
+               /* Mark extended_value in case both key and value are being used */
+               
CG(active_op_array)->opcodes[foreach_token->u.opline_num].extended_value |= 2;
        }
 
        if ((key->op_type != IS_UNUSED) && (key->u.EA.type & 
ZEND_PARSED_REFERENCE_VARIABLE)) {
@@ -3362,20 +3365,10 @@
                if 
(!CG(active_op_array)->opcodes[foreach_token->u.opline_num-1].extended_value) {
                        zend_error(E_COMPILE_ERROR, "Cannot create references to 
elements of a temporary array expression");
                }
-               
CG(active_op_array)->opcodes[foreach_token->u.opline_num].extended_value = 1;
+               /* Mark extended_value for assign-by-reference */
+               
CG(active_op_array)->opcodes[foreach_token->u.opline_num].extended_value |= 1;
        }
 
-       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;
-
        if (key->op_type != IS_UNUSED) {
                opline = get_next_op(CG(active_op_array) TSRMLS_CC);
                opline->opcode = ZEND_FETCH_DIM_TMP_VAR;
@@ -3385,13 +3378,33 @@
                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;
        }
 
        if (assign_by_ref) {
-               zend_do_assign_ref(&dummy, value, &result_value TSRMLS_CC);
+               if (key->op_type == IS_UNUSED) {
+                       /* Mark FE_FETCH as IS_VAR as it holds the data directly as a 
value */
+                       
CG(active_op_array)->opcodes[foreach_token->u.opline_num].result.op_type = IS_VAR;
+                       zend_do_assign_ref(NULL, value, 
&CG(active_op_array)->opcodes[foreach_token->u.opline_num].result TSRMLS_CC);
+               } else {
+                       zend_do_assign_ref(NULL, value, &result_value TSRMLS_CC);
+               }
        } else {
                zend_do_assign(&dummy, value, &result_value TSRMLS_CC);
        }
@@ -3399,8 +3412,8 @@
        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));
http://cvs.php.net/diff.php/ZendEngine2/zend_execute.c?r1=1.665&r2=1.666&ty=u
Index: ZendEngine2/zend_execute.c
diff -u ZendEngine2/zend_execute.c:1.665 ZendEngine2/zend_execute.c:1.666
--- ZendEngine2/zend_execute.c:1.665    Wed Aug 11 16:19:49 2004
+++ ZendEngine2/zend_execute.c  Thu Aug 12 01:41:01 2004
@@ -17,7 +17,7 @@
    +----------------------------------------------------------------------+
 */
 
-/* $Id: zend_execute.c,v 1.665 2004/08/11 20:19:49 helly Exp $ */
+/* $Id: zend_execute.c,v 1.666 2004/08/12 05:41:01 andi Exp $ */
 
 #define ZEND_INTENSIVE_DEBUGGING 0
 
@@ -3772,7 +3772,6 @@
 int zend_fe_fetch_handler(ZEND_OPCODE_HANDLER_ARGS)
 {
        zval *array = get_zval_ptr(&opline->op1, EX(Ts), &EG(free_op1), BP_VAR_R);
-       zval *result = &EX_T(opline->result.u.var).tmp_var;
        zval **value, *key;
        char *str_key;
        uint str_key_len;
@@ -3780,6 +3779,8 @@
        HashTable *fe_ht;
        zend_object_iterator *iter = NULL;
        int key_type;
+       /* extended_value & 2 means that the key is also needed */
+       zend_bool use_key = opline->extended_value & 2;
 
        PZVAL_LOCK(array);
 
@@ -3805,10 +3806,12 @@
 
                                zend_hash_move_forward(fe_ht);
                        } while (key_type != HASH_KEY_IS_STRING || 
zend_check_property_access(zobj, str_key TSRMLS_CC) != SUCCESS);
-                       zend_unmangle_property_name(str_key, &class_name, &prop_name);
-                       str_key_len = strlen(prop_name);
-                       str_key = estrndup(prop_name, str_key_len);
-                       str_key_len++;
+                       if (use_key) {
+                               zend_unmangle_property_name(str_key, &class_name, 
&prop_name);
+                               str_key_len = strlen(prop_name);
+                               str_key = estrndup(prop_name, str_key_len);
+                               str_key_len++;
+                       }
                        break;
                }
 
@@ -3819,7 +3822,9 @@
                                SET_OPCODE(op_array->opcodes+opline->op2.u.opline_num);
                                return 0; /* CHECK_ME */
                        }
-                       key_type = zend_hash_get_current_key_ex(fe_ht, &str_key, 
&str_key_len, &int_key, 1, NULL);
+                       if (use_key) {
+                               key_type = zend_hash_get_current_key_ex(fe_ht, 
&str_key, &str_key_len, &int_key, 1, NULL);
+                       }
                        zend_hash_move_forward(fe_ht);
                        break;
 
@@ -3841,41 +3846,59 @@
                                SET_OPCODE(op_array->opcodes+opline->op2.u.opline_num);
                                return 0; /* CHECK_ME */
                        }
-                       if (iter->funcs->get_current_key) {
-                               key_type = iter->funcs->get_current_key(iter, 
&str_key, &str_key_len, &int_key TSRMLS_CC);
-                       } else {
-                               key_type = HASH_KEY_IS_LONG;
-                               int_key = iter->index;
+                       if (use_key) {
+                               if (iter->funcs->get_current_key) {
+                                       key_type = iter->funcs->get_current_key(iter, 
&str_key, &str_key_len, &int_key TSRMLS_CC);
+                               } else {
+                                       key_type = HASH_KEY_IS_LONG;
+                                       int_key = iter->index;
+                               }
                        }
 
                        break;
        }
 
-       array_init(result);
-
-       if (opline->extended_value) {
+       if (opline->extended_value & 1) {
                SEPARATE_ZVAL_IF_NOT_REF(value);
                (*value)->is_ref = 1;
        }
-       (*value)->refcount++;
-       zend_hash_index_update(result->value.ht, 0, value, sizeof(zval *), NULL);
 
-       ALLOC_ZVAL(key);
-       INIT_PZVAL(key);
+       if (!use_key) {
+               if (opline->extended_value & 1) {
+                       EX_T(opline->result.u.var).var.ptr_ptr = value;
+                       (*value)->refcount++;
+               } else {
+                       zval *result = &EX_T(opline->result.u.var).tmp_var;
 
-       switch (key_type) {
-               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()
+                       *result = **value;
+                       zval_copy_ctor(result);
+               }
+       } else {
+               zval *result = &EX_T(opline->result.u.var).tmp_var;
+
+               (*value)->refcount++;
+
+               array_init(result);
+
+               zend_hash_index_update(result->value.ht, 0, value, sizeof(zval *), 
NULL);
+
+               ALLOC_ZVAL(key);
+               INIT_PZVAL(key);
+
+               switch (key_type) {
+                       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);
 
        NEXT_OPCODE();
 }

-- 
Zend Engine CVS Mailing List (http://cvs.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php
-- 
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to