Skip to content

Commit 06103d6

Browse files
committed
Use zval_ptr_dtor_nogc() to free IS_TMP_VAR operands.
Removed ZEND_SWITCH_FREE opcode (ZEND_FREE used instead).
1 parent b279570 commit 06103d6

File tree

11 files changed

+462
-538
lines changed

11 files changed

+462
-538
lines changed

Zend/zend_compile.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -859,7 +859,7 @@ static int generate_free_loop_var(znode *var TSRMLS_DC) /* {{{ */
859859
{
860860
zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
861861

862-
opline->opcode = var->op_type == IS_TMP_VAR ? ZEND_FREE : ZEND_SWITCH_FREE;
862+
opline->opcode = ZEND_FREE;
863863
SET_NODE(opline->op1, var);
864864
SET_UNUSED(opline->op2);
865865
}
@@ -3588,7 +3588,7 @@ void zend_compile_switch(zend_ast *ast TSRMLS_DC) /* {{{ */
35883588
zend_end_loop(get_next_op_number(CG(active_op_array)), 1 TSRMLS_CC);
35893589

35903590
if (expr_node.op_type == IS_VAR || expr_node.op_type == IS_TMP_VAR) {
3591-
zend_emit_op(NULL, expr_node.op_type == IS_TMP_VAR ? ZEND_FREE : ZEND_SWITCH_FREE,
3591+
zend_emit_op(NULL, ZEND_FREE,
35923592
&expr_node, NULL TSRMLS_CC);
35933593
} else if (expr_node.op_type == IS_CONST) {
35943594
zval_dtor(&expr_node.u.constant);

Zend/zend_execute.c

Lines changed: 11 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -100,15 +100,6 @@ static const zend_internal_function zend_pass_function = {
100100

101101
#define FREE_OP(should_free) \
102102
if (should_free.var) { \
103-
if ((zend_uintptr_t)should_free.var & 1L) { \
104-
zval_dtor((zval*)((zend_uintptr_t)should_free.var & ~1L)); \
105-
} else { \
106-
zval_ptr_dtor_nogc(should_free.var); \
107-
} \
108-
}
109-
110-
#define FREE_OP_IF_VAR(should_free) \
111-
if (should_free.var != NULL && (((zend_uintptr_t)should_free.var & 1L) == 0)) { \
112103
zval_ptr_dtor_nogc(should_free.var); \
113104
}
114105

@@ -117,10 +108,6 @@ static const zend_internal_function zend_pass_function = {
117108
zval_ptr_dtor_nogc(should_free.var); \
118109
}
119110

120-
#define TMP_FREE(z) (zval*)(((zend_uintptr_t)(z)) | 1L)
121-
122-
#define IS_TMP_FREE(should_free) ((zend_uintptr_t)should_free.var & 1L)
123-
124111
/* End of zend_execute_locks.h */
125112

126113
#define CV_DEF_OF(i) (EX(func)->op_array.vars[i])
@@ -362,7 +349,7 @@ static inline zval *_get_zval_ptr(int op_type, const znode_op *node, const zend_
362349
break;
363350
case IS_TMP_VAR:
364351
ret = EX_VAR(node->var);
365-
should_free->var = TMP_FREE(ret);
352+
should_free->var = ret;
366353
return ret;
367354
break;
368355
case IS_VAR:
@@ -392,7 +379,7 @@ static inline zval *_get_zval_ptr_deref(int op_type, const znode_op *node, const
392379
break;
393380
case IS_TMP_VAR:
394381
ret = EX_VAR(node->var);
395-
should_free->var = TMP_FREE(ret);
382+
should_free->var = ret;
396383
return ret;
397384
break;
398385
case IS_VAR:
@@ -744,10 +731,12 @@ static inline void zend_assign_to_object(zval *retval, zval *object_ptr, zval *p
744731
ZVAL_COPY(retval, value);
745732
}
746733
zval_ptr_dtor(value);
747-
FREE_OP_IF_VAR(free_value);
734+
if (value_type == IS_VAR) {
735+
FREE_OP(free_value);
736+
}
748737
}
749738

750-
static void zend_assign_to_string_offset(zval *str, zend_long offset, zval *value, int value_type, zval *result TSRMLS_DC)
739+
static void zend_assign_to_string_offset(zval *str, zend_long offset, zval *value, zval *result TSRMLS_DC)
751740
{
752741
zend_string *old_str;
753742

@@ -779,12 +768,6 @@ static void zend_assign_to_string_offset(zval *str, zend_long offset, zval *valu
779768
zend_string_release(tmp);
780769
} else {
781770
Z_STRVAL_P(str)[offset] = Z_STRVAL_P(value)[0];
782-
if (value_type == IS_TMP_VAR) {
783-
/* we can safely free final_value here
784-
* because separation is done only
785-
* in case value_type == IS_VAR */
786-
zval_dtor(value);
787-
}
788771
}
789772
/*
790773
* the value of an assignment to a string offset is undefined
@@ -824,7 +807,7 @@ static zend_always_inline zval* zend_assign_to_variable(zval *variable_ptr, zval
824807
return variable_ptr;
825808
}
826809
garbage = Z_COUNTED_P(variable_ptr);
827-
if (GC_REFCOUNT(garbage) == 1) {
810+
if (--GC_REFCOUNT(garbage) == 0) {
828811
ZVAL_COPY_VALUE(variable_ptr, value);
829812
if (value_type == IS_CONST) {
830813
/* IS_CONST can't be IS_OBJECT, IS_RESOURCE or IS_REFERENCE */
@@ -836,10 +819,9 @@ static zend_always_inline zval* zend_assign_to_variable(zval *variable_ptr, zval
836819
Z_ADDREF_P(variable_ptr);
837820
}
838821
}
839-
_zval_dtor_func(garbage ZEND_FILE_LINE_CC);
822+
_zval_dtor_func_for_ptr(garbage ZEND_FILE_LINE_CC);
840823
return variable_ptr;
841824
} else { /* we need to split */
842-
GC_REFCOUNT(garbage)--;
843825
/* optimized version of GC_ZVAL_CHECK_POSSIBLE_ROOT(variable_ptr) */
844826
if ((Z_COLLECTABLE_P(variable_ptr)) &&
845827
UNEXPECTED(!GC_INFO(garbage))) {
@@ -1036,7 +1018,7 @@ static zend_always_inline zval *zend_fetch_dimension_address(zval *result, zval
10361018
zend_long offset;
10371019

10381020
if (type != BP_VAR_UNSET && UNEXPECTED(Z_STRLEN_P(container) == 0)) {
1039-
zval_dtor(container);
1021+
zval_ptr_dtor_nogc(container);
10401022
convert_to_array:
10411023
ZVAL_NEW_ARR(container);
10421024
zend_hash_init(Z_ARRVAL_P(container), 8, NULL, ZVAL_PTR_DTOR, 0);
@@ -1337,13 +1319,9 @@ static inline zend_brk_cont_element* zend_brk_cont(int nest_levels, int array_of
13371319
if (nest_levels>1) {
13381320
zend_op *brk_opline = &op_array->opcodes[jmp_to->brk];
13391321

1340-
if (brk_opline->opcode == ZEND_SWITCH_FREE) {
1341-
if (!(brk_opline->extended_value & EXT_TYPE_FREE_ON_RETURN)) {
1342-
zval_ptr_dtor(EX_VAR(brk_opline->op1.var));
1343-
}
1344-
} else if (brk_opline->opcode == ZEND_FREE) {
1322+
if (brk_opline->opcode == ZEND_FREE) {
13451323
if (!(brk_opline->extended_value & EXT_TYPE_FREE_ON_RETURN)) {
1346-
zval_dtor(EX_VAR(brk_opline->op1.var));
1324+
zval_ptr_dtor_nogc(EX_VAR(brk_opline->op1.var));
13471325
}
13481326
}
13491327
}

Zend/zend_generators.c

Lines changed: 3 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -57,19 +57,9 @@ static void zend_generator_cleanup_unfinished_execution(zend_generator *generato
5757
} else if (brk_cont->brk > op_num) {
5858
zend_op *brk_opline = op_array->opcodes + brk_cont->brk;
5959

60-
switch (brk_opline->opcode) {
61-
case ZEND_SWITCH_FREE:
62-
{
63-
zval *var = EX_VAR_2(execute_data, brk_opline->op1.var);
64-
zval_ptr_dtor(var);
65-
}
66-
break;
67-
case ZEND_FREE:
68-
{
69-
zval *var = EX_VAR_2(execute_data, brk_opline->op1.var);
70-
zval_dtor(var);
71-
}
72-
break;
60+
if (brk_opline->opcode == ZEND_FREE) {
61+
zval *var = EX_VAR_2(execute_data, brk_opline->op1.var);
62+
zval_ptr_dtor_nogc(var);
7363
}
7464
}
7565
}

Zend/zend_vm_def.h

Lines changed: 12 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1643,26 +1643,27 @@ ZEND_VM_HANDLER(147, ZEND_ASSIGN_DIM, VAR|CV, CONST|TMP|VAR|UNUSED|CV)
16431643
FREE_OP2();
16441644
value = get_zval_ptr_deref((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
16451645
if (UNEXPECTED(variable_ptr != NULL)) {
1646-
zend_assign_to_string_offset(variable_ptr, Z_LVAL_P(EX_VAR((opline+1)->op2.var)), value, (opline+1)->op1_type, (RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : NULL) TSRMLS_CC);
1646+
zend_assign_to_string_offset(variable_ptr, Z_LVAL_P(EX_VAR((opline+1)->op2.var)), value, (RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : NULL) TSRMLS_CC);
1647+
FREE_OP(free_op_data1);
16471648
} else {
16481649
variable_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC);
16491650
if (UNEXPECTED(variable_ptr == &EG(error_zval))) {
1650-
if (IS_TMP_FREE(free_op_data1)) {
1651-
zval_dtor(value);
1652-
}
1651+
FREE_OP(free_op_data1);
16531652
if (RETURN_VALUE_USED(opline)) {
16541653
ZVAL_NULL(EX_VAR(opline->result.var));
16551654
}
16561655
FREE_OP_VAR_PTR(free_op_data2);
16571656
} else {
16581657
value = zend_assign_to_variable(variable_ptr, value, (opline+1)->op1_type TSRMLS_CC);
1658+
if ((opline+1)->op1_type == IS_VAR) {
1659+
FREE_OP(free_op_data1);
1660+
}
16591661
if (RETURN_VALUE_USED(opline)) {
16601662
ZVAL_COPY(EX_VAR(opline->result.var), value);
16611663
}
16621664
FREE_OP_VAR_PTR(free_op_data2);
16631665
}
16641666
}
1665-
FREE_OP_IF_VAR(free_op_data1);
16661667
}
16671668
FREE_OP1_VAR_PTR();
16681669
/* assign_dim has two opcodes! */
@@ -1684,7 +1685,7 @@ ZEND_VM_HANDLER(38, ZEND_ASSIGN, VAR|CV, CONST|TMP|VAR|CV)
16841685

16851686
if (OP1_TYPE == IS_VAR && UNEXPECTED(variable_ptr == &EG(error_zval))) {
16861687
if (OP2_TYPE == IS_TMP_VAR) {
1687-
zval_dtor(value);
1688+
FREE_OP2();
16881689
}
16891690
if (RETURN_VALUE_USED(opline)) {
16901691
ZVAL_NULL(EX_VAR(opline->result.var));
@@ -2041,11 +2042,7 @@ ZEND_VM_HANDLER(70, ZEND_FREE, TMP|VAR, ANY)
20412042
USE_OPLINE
20422043

20432044
SAVE_OPLINE();
2044-
if (OP1_TYPE == IS_TMP_VAR) {
2045-
zval_dtor(EX_VAR(opline->op1.var));
2046-
} else {
2047-
zval_ptr_dtor(EX_VAR(opline->op1.var));
2048-
}
2045+
zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
20492046
CHECK_EXCEPTION();
20502047
ZEND_VM_NEXT_OPCODE();
20512048
}
@@ -3652,13 +3649,9 @@ ZEND_VM_HANDLER(100, ZEND_GOTO, ANY, CONST)
36523649

36533650
brk_opline = EX(func)->op_array.opcodes + el->brk;
36543651

3655-
if (brk_opline->opcode == ZEND_SWITCH_FREE) {
3656-
if (!(brk_opline->extended_value & EXT_TYPE_FREE_ON_RETURN)) {
3657-
zval_ptr_dtor(EX_VAR(brk_opline->op1.var));
3658-
}
3659-
} else if (brk_opline->opcode == ZEND_FREE) {
3652+
if (brk_opline->opcode == ZEND_FREE) {
36603653
if (!(brk_opline->extended_value & EXT_TYPE_FREE_ON_RETURN)) {
3661-
zval_dtor(EX_VAR(brk_opline->op1.var));
3654+
zval_ptr_dtor_nogc(EX_VAR(brk_opline->op1.var));
36623655
}
36633656
}
36643657
ZEND_VM_JMP(opline->op1.jmp_addr);
@@ -3680,16 +3673,6 @@ ZEND_VM_HANDLER(48, ZEND_CASE, CONST|TMP|VAR|CV, CONST|TMP|VAR|CV)
36803673
ZEND_VM_NEXT_OPCODE();
36813674
}
36823675

3683-
ZEND_VM_HANDLER(49, ZEND_SWITCH_FREE, VAR, ANY)
3684-
{
3685-
USE_OPLINE
3686-
3687-
SAVE_OPLINE();
3688-
zval_ptr_dtor(EX_VAR(opline->op1.var));
3689-
CHECK_EXCEPTION();
3690-
ZEND_VM_NEXT_OPCODE();
3691-
}
3692-
36933676
ZEND_VM_HANDLER(68, ZEND_NEW, ANY, ANY)
36943677
{
36953678
USE_OPLINE
@@ -5485,13 +5468,9 @@ ZEND_VM_HANDLER(149, ZEND_HANDLE_EXCEPTION, ANY, ANY)
54855468
catch_op_num >= EX(func)->op_array.brk_cont_array[i].brk) {
54865469
zend_op *brk_opline = &EX(func)->op_array.opcodes[EX(func)->op_array.brk_cont_array[i].brk];
54875470

5488-
if (brk_opline->opcode == ZEND_SWITCH_FREE) {
5489-
if (!(brk_opline->extended_value & EXT_TYPE_FREE_ON_RETURN)) {
5490-
zval_ptr_dtor(EX_VAR(brk_opline->op1.var));
5491-
}
5492-
} else if (brk_opline->opcode == ZEND_FREE) {
5471+
if (brk_opline->opcode == ZEND_FREE) {
54935472
if (!(brk_opline->extended_value & EXT_TYPE_FREE_ON_RETURN)) {
5494-
zval_dtor(EX_VAR(brk_opline->op1.var));
5473+
zval_ptr_dtor_nogc(EX_VAR(brk_opline->op1.var));
54955474
}
54965475
}
54975476
}

0 commit comments

Comments
 (0)