From 968bdc576c0319b2ce4fa6076644f724534dfa8a Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Fri, 22 Oct 2010 13:59:23 +0000 Subject: [PATCH] Simplified foreach() handling, we don't have to inctrement/decrement refcount twice --- Zend/zend_execute.c | 17 +------- Zend/zend_vm_def.h | 37 +++------------- Zend/zend_vm_execute.h | 97 +++--------------------------------------- 3 files changed, 15 insertions(+), 136 deletions(-) diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c index 5dc739140c8..5593c946b5c 100644 --- a/Zend/zend_execute.c +++ b/Zend/zend_execute.c @@ -505,21 +505,6 @@ static inline zval *_get_obj_zval_ptr(int op_type, znode_op *op, const temp_vari return get_zval_ptr(op_type, op, Ts, should_free, type); } -static inline void zend_switch_free(temp_variable *T, int extended_value TSRMLS_DC) -{ - if (T->var.ptr) { - if (extended_value & ZEND_FE_RESET_VARIABLE) { /* foreach() free */ - Z_DELREF_P(T->var.ptr); - } - zval_ptr_dtor(&T->var.ptr); - } else if (!T->var.ptr_ptr) { - /* perform the equivalent of equivalent of a - * quick & silent get_zval_ptr, and FREE_OP - */ - PZVAL_UNLOCK_FREE(T->str_offset.str); - } -} - static void zend_assign_to_variable_reference(zval **variable_ptr_ptr, zval **value_ptr_ptr TSRMLS_DC) { zval *variable_ptr = *variable_ptr_ptr; @@ -1404,7 +1389,7 @@ static inline zend_brk_cont_element* zend_brk_cont(zval *nest_levels_zval, int a switch (brk_opline->opcode) { case ZEND_SWITCH_FREE: if (!(brk_opline->extended_value & EXT_TYPE_FREE_ON_RETURN)) { - zend_switch_free(&T(brk_opline->op1.var), brk_opline->extended_value TSRMLS_CC); + zval_ptr_dtor(&T(brk_opline->op1.var).var.ptr); } break; case ZEND_FREE: diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index d796b1f057a..8052fa1b14d 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -3212,7 +3212,7 @@ ZEND_VM_HANDLER(100, ZEND_GOTO, ANY, CONST) switch (brk_opline->opcode) { case ZEND_SWITCH_FREE: if (!(brk_opline->extended_value & EXT_TYPE_FREE_ON_RETURN)) { - zend_switch_free(&EX_T(brk_opline->op1.var), brk_opline->extended_value TSRMLS_CC); + zval_ptr_dtor(&EX_T(brk_opline->op1.var).var.ptr); } break; case ZEND_FREE: @@ -3247,7 +3247,7 @@ ZEND_VM_HANDLER(49, ZEND_SWITCH_FREE, VAR, ANY) USE_OPLINE SAVE_OPLINE(); - zend_switch_free(&EX_T(opline->op1.var), opline->extended_value TSRMLS_CC); + zval_ptr_dtor(&EX_T(opline->op1.var).var.ptr); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -4030,11 +4030,7 @@ ZEND_VM_HANDLER(77, ZEND_FE_RESET, CONST|TMP|VAR|CV, ANY) if (iter && EXPECTED(EG(exception) == NULL)) { array_ptr = zend_iterator_wrap(iter TSRMLS_CC); } else { - if (opline->extended_value & ZEND_FE_RESET_VARIABLE) { - FREE_OP1_VAR_PTR(); - } else { - FREE_OP1_IF_VAR(); - } + FREE_OP1_IF_VAR(); if (!EG(exception)) { zend_throw_exception_ex(NULL, 0 TSRMLS_CC, "Object of type %s did not create an Iterator", ce->name); } @@ -4043,7 +4039,6 @@ ZEND_VM_HANDLER(77, ZEND_FE_RESET, CONST|TMP|VAR|CV, ANY) } } - PZVAL_LOCK(array_ptr); AI_SET_PTR(&EX_T(opline->result.var), array_ptr); if (iter) { @@ -4051,25 +4046,15 @@ ZEND_VM_HANDLER(77, ZEND_FE_RESET, CONST|TMP|VAR|CV, ANY) if (iter->funcs->rewind) { iter->funcs->rewind(iter TSRMLS_CC); if (UNEXPECTED(EG(exception) != NULL)) { - Z_DELREF_P(array_ptr); zval_ptr_dtor(&array_ptr); - if (opline->extended_value & ZEND_FE_RESET_VARIABLE) { - FREE_OP1_VAR_PTR(); - } else { - FREE_OP1_IF_VAR(); - } + FREE_OP1_IF_VAR(); HANDLE_EXCEPTION(); } } is_empty = iter->funcs->valid(iter TSRMLS_CC) != SUCCESS; if (UNEXPECTED(EG(exception) != NULL)) { - Z_DELREF_P(array_ptr); zval_ptr_dtor(&array_ptr); - if (opline->extended_value & ZEND_FE_RESET_VARIABLE) { - FREE_OP1_VAR_PTR(); - } else { - FREE_OP1_IF_VAR(); - } + FREE_OP1_IF_VAR(); HANDLE_EXCEPTION(); } iter->index = -1; /* will be set to 0 before using next handler */ @@ -4099,11 +4084,7 @@ ZEND_VM_HANDLER(77, ZEND_FE_RESET, CONST|TMP|VAR|CV, ANY) is_empty = 1; } - if (opline->extended_value & ZEND_FE_RESET_VARIABLE) { - FREE_OP1_VAR_PTR(); - } else { - FREE_OP1_IF_VAR(); - } + FREE_OP1_IF_VAR(); if (is_empty) { ZEND_VM_JMP(EX(op_array)->opcodes+opline->op2.opline_num); } else { @@ -4182,7 +4163,6 @@ ZEND_VM_HANDLER(78, ZEND_FE_FETCH, VAR, ANY) * In case that ever happens we need an additional flag. */ iter->funcs->move_forward(iter TSRMLS_CC); if (UNEXPECTED(EG(exception) != NULL)) { - Z_DELREF_P(array); zval_ptr_dtor(&array); HANDLE_EXCEPTION(); } @@ -4191,7 +4171,6 @@ ZEND_VM_HANDLER(78, ZEND_FE_FETCH, VAR, ANY) if (!iter || (iter->index > 0 && iter->funcs->valid(iter TSRMLS_CC) == FAILURE)) { /* reached end of iteration */ if (UNEXPECTED(EG(exception) != NULL)) { - Z_DELREF_P(array); zval_ptr_dtor(&array); HANDLE_EXCEPTION(); } @@ -4199,7 +4178,6 @@ ZEND_VM_HANDLER(78, ZEND_FE_FETCH, VAR, ANY) } iter->funcs->get_current_data(iter, &value TSRMLS_CC); if (UNEXPECTED(EG(exception) != NULL)) { - Z_DELREF_P(array); zval_ptr_dtor(&array); HANDLE_EXCEPTION(); } @@ -4211,7 +4189,6 @@ ZEND_VM_HANDLER(78, ZEND_FE_FETCH, VAR, ANY) if (iter->funcs->get_current_key) { key_type = iter->funcs->get_current_key(iter, &str_key, &str_key_len, &int_key TSRMLS_CC); if (UNEXPECTED(EG(exception) != NULL)) { - Z_DELREF_P(array); zval_ptr_dtor(&array); HANDLE_EXCEPTION(); } @@ -4871,7 +4848,7 @@ ZEND_VM_HANDLER(149, ZEND_HANDLE_EXCEPTION, ANY, ANY) switch (brk_opline->opcode) { case ZEND_SWITCH_FREE: if (!(brk_opline->extended_value & EXT_TYPE_FREE_ON_RETURN)) { - zend_switch_free(&EX_T(brk_opline->op1.var), brk_opline->extended_value TSRMLS_CC); + zval_ptr_dtor(&EX_T(brk_opline->op1.var).var.ptr); } break; case ZEND_FREE: diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index 3bfbc0d35f0..e08954560b8 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -1080,7 +1080,7 @@ static int ZEND_FASTCALL ZEND_HANDLE_EXCEPTION_SPEC_HANDLER(ZEND_OPCODE_HANDLER switch (brk_opline->opcode) { case ZEND_SWITCH_FREE: if (!(brk_opline->extended_value & EXT_TYPE_FREE_ON_RETURN)) { - zend_switch_free(&EX_T(brk_opline->op1.var), brk_opline->extended_value TSRMLS_CC); + zval_ptr_dtor(&EX_T(brk_opline->op1.var).var.ptr); } break; case ZEND_FREE: @@ -1342,7 +1342,7 @@ static int ZEND_FASTCALL ZEND_GOTO_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) switch (brk_opline->opcode) { case ZEND_SWITCH_FREE: if (!(brk_opline->extended_value & EXT_TYPE_FREE_ON_RETURN)) { - zend_switch_free(&EX_T(brk_opline->op1.var), brk_opline->extended_value TSRMLS_CC); + zval_ptr_dtor(&EX_T(brk_opline->op1.var).var.ptr); } break; case ZEND_FREE: @@ -2533,11 +2533,7 @@ static int ZEND_FASTCALL ZEND_FE_RESET_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_A if (iter && EXPECTED(EG(exception) == NULL)) { array_ptr = zend_iterator_wrap(iter TSRMLS_CC); } else { - if (opline->extended_value & ZEND_FE_RESET_VARIABLE) { - } else { - - } if (!EG(exception)) { zend_throw_exception_ex(NULL, 0 TSRMLS_CC, "Object of type %s did not create an Iterator", ce->name); } @@ -2546,7 +2542,6 @@ static int ZEND_FASTCALL ZEND_FE_RESET_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_A } } - PZVAL_LOCK(array_ptr); AI_SET_PTR(&EX_T(opline->result.var), array_ptr); if (iter) { @@ -2554,25 +2549,15 @@ static int ZEND_FASTCALL ZEND_FE_RESET_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_A if (iter->funcs->rewind) { iter->funcs->rewind(iter TSRMLS_CC); if (UNEXPECTED(EG(exception) != NULL)) { - Z_DELREF_P(array_ptr); zval_ptr_dtor(&array_ptr); - if (opline->extended_value & ZEND_FE_RESET_VARIABLE) { - } else { - - } HANDLE_EXCEPTION(); } } is_empty = iter->funcs->valid(iter TSRMLS_CC) != SUCCESS; if (UNEXPECTED(EG(exception) != NULL)) { - Z_DELREF_P(array_ptr); zval_ptr_dtor(&array_ptr); - if (opline->extended_value & ZEND_FE_RESET_VARIABLE) { - } else { - - } HANDLE_EXCEPTION(); } iter->index = -1; /* will be set to 0 before using next handler */ @@ -2602,11 +2587,6 @@ static int ZEND_FASTCALL ZEND_FE_RESET_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_A is_empty = 1; } - if (opline->extended_value & ZEND_FE_RESET_VARIABLE) { - - } else { - - } if (is_empty) { ZEND_VM_JMP(EX(op_array)->opcodes+opline->op2.opline_num); } else { @@ -6816,11 +6796,7 @@ static int ZEND_FASTCALL ZEND_FE_RESET_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARG if (iter && EXPECTED(EG(exception) == NULL)) { array_ptr = zend_iterator_wrap(iter TSRMLS_CC); } else { - if (opline->extended_value & ZEND_FE_RESET_VARIABLE) { - } else { - - } if (!EG(exception)) { zend_throw_exception_ex(NULL, 0 TSRMLS_CC, "Object of type %s did not create an Iterator", ce->name); } @@ -6829,7 +6805,6 @@ static int ZEND_FASTCALL ZEND_FE_RESET_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARG } } - PZVAL_LOCK(array_ptr); AI_SET_PTR(&EX_T(opline->result.var), array_ptr); if (iter) { @@ -6837,25 +6812,15 @@ static int ZEND_FASTCALL ZEND_FE_RESET_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARG if (iter->funcs->rewind) { iter->funcs->rewind(iter TSRMLS_CC); if (UNEXPECTED(EG(exception) != NULL)) { - Z_DELREF_P(array_ptr); zval_ptr_dtor(&array_ptr); - if (opline->extended_value & ZEND_FE_RESET_VARIABLE) { - } else { - - } HANDLE_EXCEPTION(); } } is_empty = iter->funcs->valid(iter TSRMLS_CC) != SUCCESS; if (UNEXPECTED(EG(exception) != NULL)) { - Z_DELREF_P(array_ptr); zval_ptr_dtor(&array_ptr); - if (opline->extended_value & ZEND_FE_RESET_VARIABLE) { - } else { - - } HANDLE_EXCEPTION(); } iter->index = -1; /* will be set to 0 before using next handler */ @@ -6885,11 +6850,6 @@ static int ZEND_FASTCALL ZEND_FE_RESET_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARG is_empty = 1; } - if (opline->extended_value & ZEND_FE_RESET_VARIABLE) { - - } else { - - } if (is_empty) { ZEND_VM_JMP(EX(op_array)->opcodes+opline->op2.opline_num); } else { @@ -10781,7 +10741,7 @@ static int ZEND_FASTCALL ZEND_SWITCH_FREE_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ USE_OPLINE SAVE_OPLINE(); - zend_switch_free(&EX_T(opline->op1.var), opline->extended_value TSRMLS_CC); + zval_ptr_dtor(&EX_T(opline->op1.var).var.ptr); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -11125,11 +11085,7 @@ static int ZEND_FASTCALL ZEND_FE_RESET_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARG if (iter && EXPECTED(EG(exception) == NULL)) { array_ptr = zend_iterator_wrap(iter TSRMLS_CC); } else { - if (opline->extended_value & ZEND_FE_RESET_VARIABLE) { - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; - } else { - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; - } + if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; if (!EG(exception)) { zend_throw_exception_ex(NULL, 0 TSRMLS_CC, "Object of type %s did not create an Iterator", ce->name); } @@ -11138,7 +11094,6 @@ static int ZEND_FASTCALL ZEND_FE_RESET_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARG } } - PZVAL_LOCK(array_ptr); AI_SET_PTR(&EX_T(opline->result.var), array_ptr); if (iter) { @@ -11146,25 +11101,15 @@ static int ZEND_FASTCALL ZEND_FE_RESET_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARG if (iter->funcs->rewind) { iter->funcs->rewind(iter TSRMLS_CC); if (UNEXPECTED(EG(exception) != NULL)) { - Z_DELREF_P(array_ptr); zval_ptr_dtor(&array_ptr); - if (opline->extended_value & ZEND_FE_RESET_VARIABLE) { - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; - } else { - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; - } + if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; HANDLE_EXCEPTION(); } } is_empty = iter->funcs->valid(iter TSRMLS_CC) != SUCCESS; if (UNEXPECTED(EG(exception) != NULL)) { - Z_DELREF_P(array_ptr); zval_ptr_dtor(&array_ptr); - if (opline->extended_value & ZEND_FE_RESET_VARIABLE) { - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; - } else { - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; - } + if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; HANDLE_EXCEPTION(); } iter->index = -1; /* will be set to 0 before using next handler */ @@ -11194,11 +11139,7 @@ static int ZEND_FASTCALL ZEND_FE_RESET_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARG is_empty = 1; } - if (opline->extended_value & ZEND_FE_RESET_VARIABLE) { - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; - } else { - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; - } + if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; if (is_empty) { ZEND_VM_JMP(EX(op_array)->opcodes+opline->op2.opline_num); } else { @@ -11277,7 +11218,6 @@ static int ZEND_FASTCALL ZEND_FE_FETCH_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARG * In case that ever happens we need an additional flag. */ iter->funcs->move_forward(iter TSRMLS_CC); if (UNEXPECTED(EG(exception) != NULL)) { - Z_DELREF_P(array); zval_ptr_dtor(&array); HANDLE_EXCEPTION(); } @@ -11286,7 +11226,6 @@ static int ZEND_FASTCALL ZEND_FE_FETCH_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARG if (!iter || (iter->index > 0 && iter->funcs->valid(iter TSRMLS_CC) == FAILURE)) { /* reached end of iteration */ if (UNEXPECTED(EG(exception) != NULL)) { - Z_DELREF_P(array); zval_ptr_dtor(&array); HANDLE_EXCEPTION(); } @@ -11294,7 +11233,6 @@ static int ZEND_FASTCALL ZEND_FE_FETCH_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARG } iter->funcs->get_current_data(iter, &value TSRMLS_CC); if (UNEXPECTED(EG(exception) != NULL)) { - Z_DELREF_P(array); zval_ptr_dtor(&array); HANDLE_EXCEPTION(); } @@ -11306,7 +11244,6 @@ static int ZEND_FASTCALL ZEND_FE_FETCH_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARG if (iter->funcs->get_current_key) { key_type = iter->funcs->get_current_key(iter, &str_key, &str_key_len, &int_key TSRMLS_CC); if (UNEXPECTED(EG(exception) != NULL)) { - Z_DELREF_P(array); zval_ptr_dtor(&array); HANDLE_EXCEPTION(); } @@ -26819,11 +26756,7 @@ static int ZEND_FASTCALL ZEND_FE_RESET_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS if (iter && EXPECTED(EG(exception) == NULL)) { array_ptr = zend_iterator_wrap(iter TSRMLS_CC); } else { - if (opline->extended_value & ZEND_FE_RESET_VARIABLE) { - } else { - - } if (!EG(exception)) { zend_throw_exception_ex(NULL, 0 TSRMLS_CC, "Object of type %s did not create an Iterator", ce->name); } @@ -26832,7 +26765,6 @@ static int ZEND_FASTCALL ZEND_FE_RESET_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS } } - PZVAL_LOCK(array_ptr); AI_SET_PTR(&EX_T(opline->result.var), array_ptr); if (iter) { @@ -26840,25 +26772,15 @@ static int ZEND_FASTCALL ZEND_FE_RESET_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS if (iter->funcs->rewind) { iter->funcs->rewind(iter TSRMLS_CC); if (UNEXPECTED(EG(exception) != NULL)) { - Z_DELREF_P(array_ptr); zval_ptr_dtor(&array_ptr); - if (opline->extended_value & ZEND_FE_RESET_VARIABLE) { - } else { - - } HANDLE_EXCEPTION(); } } is_empty = iter->funcs->valid(iter TSRMLS_CC) != SUCCESS; if (UNEXPECTED(EG(exception) != NULL)) { - Z_DELREF_P(array_ptr); zval_ptr_dtor(&array_ptr); - if (opline->extended_value & ZEND_FE_RESET_VARIABLE) { - } else { - - } HANDLE_EXCEPTION(); } iter->index = -1; /* will be set to 0 before using next handler */ @@ -26888,11 +26810,6 @@ static int ZEND_FASTCALL ZEND_FE_RESET_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS is_empty = 1; } - if (opline->extended_value & ZEND_FE_RESET_VARIABLE) { - - } else { - - } if (is_empty) { ZEND_VM_JMP(EX(op_array)->opcodes+opline->op2.opline_num); } else {