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