1
0
mirror of https://github.com/php/php-src.git synced 2026-03-28 10:12:18 +01:00

Fixed bug #67725 (now we create immutable arrays only in SHM)

This commit is contained in:
Dmitry Stogov
2014-08-05 15:38:43 +04:00
parent 3700364ca5
commit ce1af1e47b
9 changed files with 42 additions and 68 deletions

View File

@@ -33,5 +33,5 @@ unset($foo);
unset($bar);
var_dump(gc_collect_cycles());
?>
--EXPECT--
int(3)
--EXPECTREGEX--
int\([23]\)

View File

@@ -6378,23 +6378,27 @@ str_index:
if (constant_array) {
/* remove run-time array construction and use constant array instead */
opline = &CG(active_op_array)->opcodes[next_op_num-1];
while (opline != init_opline) {
while (1) {
if (opline->op2_type == IS_CONST) {
zend_del_literal(CG(active_op_array), opline->op2.constant);
}
zend_del_literal(CG(active_op_array), opline->op1.constant);
if (opline->op1_type == IS_CONST) {
if (Z_TYPE(CONSTANT(opline->op1.constant)) == IS_ARRAY &&
Z_REFCOUNTED(CONSTANT(opline->op1.constant)) &&
Z_REFCOUNT(CONSTANT(opline->op1.constant)) == 2) {
/* don't delete nested arrays */
Z_DELREF(CONSTANT(opline->op1.constant));
ZVAL_UNDEF(&CONSTANT(opline->op1.constant));
}
zend_del_literal(CG(active_op_array), opline->op1.constant);
}
if (opline == init_opline) {
break;
}
opline--;
}
if (opline->op2_type == IS_CONST) {
zend_del_literal(CG(active_op_array), opline->op2.constant);
}
if (opline->op1_type == IS_CONST) {
zend_del_literal(CG(active_op_array), opline->op1.constant);
}
CG(active_op_array)->last = array_node->u.op.opline_num;
zend_make_immutable_array(&array TSRMLS_CC);
result->op_type = IS_CONST;
ZVAL_COPY_VALUE(&result->u.constant, &array);
} else {
@@ -7846,58 +7850,14 @@ void zend_do_end_compilation(TSRMLS_D) /* {{{ */
}
/* }}} */
ZEND_API void zend_make_immutable_array(zval *zv TSRMLS_DC) /* {{{ */
{
zend_constant *c;
if (Z_IMMUTABLE_P(zv)) {
return;
}
Z_TYPE_FLAGS_P(zv) = IS_TYPE_IMMUTABLE;
GC_REFCOUNT(Z_COUNTED_P(zv)) = 2;
Z_ARRVAL_P(zv)->u.flags &= ~HASH_FLAG_APPLY_PROTECTION;
/* store as an anonymous constant */
c = emalloc(sizeof(zend_constant));
ZVAL_COPY_VALUE(&c->value, zv);
c->flags = 0;
c->name = NULL;
c->module_number = PHP_USER_CONSTANT;
zend_hash_next_index_insert_ptr(EG(zend_constants), c);
}
/* }}} */
void zend_make_immutable_array_r(zval *zv TSRMLS_DC) /* {{{ */
{
zval *el;
if (Z_IMMUTABLE_P(zv)) {
return;
}
zend_make_immutable_array(zv TSRMLS_CC);
ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(zv), el) {
if (Z_TYPE_P(el) == IS_ARRAY) {
zend_make_immutable_array_r(el TSRMLS_CC);
}
} ZEND_HASH_FOREACH_END();
}
/* }}} */
void zend_do_constant_expression(znode *result, zend_ast *ast TSRMLS_DC) /* {{{ */
{
if (ast->kind == ZEND_CONST) {
ZVAL_COPY_VALUE(&result->u.constant, &ast->u.val);
efree(ast);
if (Z_TYPE(result->u.constant) == IS_ARRAY) {
zend_make_immutable_array_r(&result->u.constant TSRMLS_CC);
}
} else if (zend_ast_is_ct_constant(ast)) {
zend_ast_evaluate(&result->u.constant, ast, NULL TSRMLS_CC);
zend_ast_destroy(ast);
if (Z_TYPE(result->u.constant) == IS_ARRAY) {
zend_make_immutable_array_r(&result->u.constant TSRMLS_CC);
}
} else {
ZVAL_NEW_AST(&result->u.constant, ast);
}

View File

@@ -461,7 +461,6 @@ typedef int (*unary_op_type)(zval *, zval * TSRMLS_DC);
typedef int (*binary_op_type)(zval *, zval *, zval * TSRMLS_DC);
ZEND_API unary_op_type get_unary_op(int opcode);
ZEND_API binary_op_type get_binary_op(int opcode);
ZEND_API void zend_make_immutable_array(zval *zv TSRMLS_DC);
void zend_do_while_cond(znode *expr, znode *close_bracket_token TSRMLS_DC);
void zend_do_while_end(const znode *while_token, const znode *close_bracket_token TSRMLS_DC);

View File

@@ -32,9 +32,7 @@ void free_zend_constant(zval *zv)
zend_constant *c = Z_PTR_P(zv);
if (!(c->flags & CONST_PERSISTENT)) {
if (Z_REFCOUNTED(c->value) || Z_IMMUTABLE(c->value)) {
_zval_dtor_func(Z_COUNTED(c->value) ZEND_FILE_LINE_CC);
}
zval_dtor(&c->value);
} else {
zval_internal_dtor(&c->value);
}

View File

@@ -3835,7 +3835,7 @@ ZEND_VM_HANDLER(99, ZEND_FETCH_CONSTANT, VAR|CONST|UNUSED, CONST)
retval = EX_VAR(opline->result.var);
ZVAL_COPY_VALUE(retval, &c->value);
if (Z_OPT_COPYABLE_P(retval) || Z_OPT_REFCOUNTED_P(retval)) {
if (Z_OPT_COPYABLE_P(retval) && (c->flags & CONST_PERSISTENT)) {
if (Z_OPT_COPYABLE_P(retval)) {
zval_copy_ctor_func(retval);
} else {
Z_ADDREF_P(retval);
@@ -4478,6 +4478,8 @@ ZEND_VM_HANDLER(77, ZEND_FE_RESET, CONST|TMP|VAR|CV, ANY)
}
} else if (Z_IMMUTABLE_P(array_ptr)) {
zval_copy_ctor(array_ptr);
} else {
SEPARATE_ZVAL_NOREF(array_ptr);
}
if (Z_REFCOUNTED_P(array_ref)) Z_ADDREF_P(array_ref);
} else if (Z_TYPE_P(array_ptr) == IS_OBJECT) {

View File

@@ -3095,6 +3095,8 @@ static int ZEND_FASTCALL ZEND_FE_RESET_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_A
}
} else if (Z_IMMUTABLE_P(array_ptr)) {
zval_copy_ctor(array_ptr);
} else {
SEPARATE_ZVAL_NOREF(array_ptr);
}
if (Z_REFCOUNTED_P(array_ref)) Z_ADDREF_P(array_ref);
} else if (Z_TYPE_P(array_ptr) == IS_OBJECT) {
@@ -4137,7 +4139,7 @@ static int ZEND_FASTCALL ZEND_FETCH_CONSTANT_SPEC_CONST_CONST_HANDLER(ZEND_OPCO
retval = EX_VAR(opline->result.var);
ZVAL_COPY_VALUE(retval, &c->value);
if (Z_OPT_COPYABLE_P(retval) || Z_OPT_REFCOUNTED_P(retval)) {
if (Z_OPT_COPYABLE_P(retval) && (c->flags & CONST_PERSISTENT)) {
if (Z_OPT_COPYABLE_P(retval)) {
zval_copy_ctor_func(retval);
} else {
Z_ADDREF_P(retval);
@@ -8601,6 +8603,8 @@ static int ZEND_FASTCALL ZEND_FE_RESET_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARG
}
} else if (Z_IMMUTABLE_P(array_ptr)) {
zval_copy_ctor(array_ptr);
} else {
SEPARATE_ZVAL_NOREF(array_ptr);
}
if (Z_REFCOUNTED_P(array_ref)) Z_ADDREF_P(array_ref);
} else if (Z_TYPE_P(array_ptr) == IS_OBJECT) {
@@ -14030,6 +14034,8 @@ static int ZEND_FASTCALL ZEND_FE_RESET_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARG
}
} else if (Z_IMMUTABLE_P(array_ptr)) {
zval_copy_ctor(array_ptr);
} else {
SEPARATE_ZVAL_NOREF(array_ptr);
}
if (Z_REFCOUNTED_P(array_ref)) Z_ADDREF_P(array_ref);
} else if (Z_TYPE_P(array_ptr) == IS_OBJECT) {
@@ -16173,7 +16179,7 @@ static int ZEND_FASTCALL ZEND_FETCH_CONSTANT_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE
retval = EX_VAR(opline->result.var);
ZVAL_COPY_VALUE(retval, &c->value);
if (Z_OPT_COPYABLE_P(retval) || Z_OPT_REFCOUNTED_P(retval)) {
if (Z_OPT_COPYABLE_P(retval) && (c->flags & CONST_PERSISTENT)) {
if (Z_OPT_COPYABLE_P(retval)) {
zval_copy_ctor_func(retval);
} else {
Z_ADDREF_P(retval);
@@ -25440,7 +25446,7 @@ static int ZEND_FASTCALL ZEND_FETCH_CONSTANT_SPEC_UNUSED_CONST_HANDLER(ZEND_OPC
retval = EX_VAR(opline->result.var);
ZVAL_COPY_VALUE(retval, &c->value);
if (Z_OPT_COPYABLE_P(retval) || Z_OPT_REFCOUNTED_P(retval)) {
if (Z_OPT_COPYABLE_P(retval) && (c->flags & CONST_PERSISTENT)) {
if (Z_OPT_COPYABLE_P(retval)) {
zval_copy_ctor_func(retval);
} else {
Z_ADDREF_P(retval);
@@ -31369,6 +31375,8 @@ static int ZEND_FASTCALL ZEND_FE_RESET_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS
}
} else if (Z_IMMUTABLE_P(array_ptr)) {
zval_copy_ctor(array_ptr);
} else {
SEPARATE_ZVAL_NOREF(array_ptr);
}
if (Z_REFCOUNTED_P(array_ref)) Z_ADDREF_P(array_ref);
} else if (Z_TYPE_P(array_ptr) == IS_OBJECT) {

View File

@@ -498,7 +498,7 @@ PHP_FUNCTION( collator_sort_with_sort_keys )
/* sort it */
zend_qsort( sortKeyIndxBuf, sortKeyCount, sortKeyIndxSize, collator_cmp_sort_keys TSRMLS_CC );
zval_dtor( array );
zval_ptr_dtor( array );
/* for resulting hash we'll assign new hash keys rather then reordering */
array_init(array);

View File

@@ -110,9 +110,6 @@ int zend_optimizer_add_literal(zend_op_array *op_array, zval *zv TSRMLS_DC)
int i = op_array->last_literal;
op_array->last_literal++;
op_array->literals = (zval*)erealloc(op_array->literals, op_array->last_literal * sizeof(zval));
if (Z_TYPE_P(zv) == IS_ARRAY) {
zend_make_immutable_array(zv TSRMLS_CC);
}
ZVAL_COPY_VALUE(&op_array->literals[i], zv);
Z_CACHE_SLOT(op_array->literals[i]) = -1;
//??? Z_SET_REFCOUNT(op_array->literals[i].constant, 2);

View File

@@ -195,6 +195,7 @@ static void zend_persist_zval(zval *z TSRMLS_DC)
new_ptr = zend_shared_alloc_get_xlat_entry(Z_ARR_P(z));
if (new_ptr) {
Z_ARR_P(z) = new_ptr;
Z_TYPE_FLAGS_P(z) = IS_TYPE_IMMUTABLE;
} else {
if (Z_IMMUTABLE_P(z)) {
Z_ARR_P(z) = zend_accel_memdup(Z_ARR_P(z), sizeof(zend_array));
@@ -202,6 +203,10 @@ static void zend_persist_zval(zval *z TSRMLS_DC)
} else {
zend_accel_store(Z_ARR_P(z), sizeof(zend_array));
zend_hash_persist(Z_ARRVAL_P(z), zend_persist_zval TSRMLS_CC);
/* make immutable array */
Z_TYPE_FLAGS_P(z) = IS_TYPE_IMMUTABLE;
GC_REFCOUNT(Z_COUNTED_P(z)) = 2;
Z_ARRVAL_P(z)->u.flags &= ~HASH_FLAG_APPLY_PROTECTION;
}
}
break;
@@ -252,6 +257,7 @@ static void zend_persist_zval_const(zval *z TSRMLS_DC)
new_ptr = zend_shared_alloc_get_xlat_entry(Z_ARR_P(z));
if (new_ptr) {
Z_ARR_P(z) = new_ptr;
Z_TYPE_FLAGS_P(z) = IS_TYPE_IMMUTABLE;
} else {
if (Z_IMMUTABLE_P(z)) {
Z_ARR_P(z) = zend_accel_memdup(Z_ARR_P(z), sizeof(zend_array));
@@ -259,6 +265,10 @@ static void zend_persist_zval_const(zval *z TSRMLS_DC)
} else {
zend_accel_store(Z_ARR_P(z), sizeof(zend_array));
zend_hash_persist(Z_ARRVAL_P(z), zend_persist_zval TSRMLS_CC);
/* make immutable array */
Z_TYPE_FLAGS_P(z) = IS_TYPE_IMMUTABLE;
GC_REFCOUNT(Z_COUNTED_P(z)) = 2;
Z_ARRVAL_P(z)->u.flags &= ~HASH_FLAG_APPLY_PROTECTION;
}
}
break;