summaryrefslogtreecommitdiff
path: root/Zend/zend_ast.c
diff options
context:
space:
mode:
authorNikita Popov <nikic@php.net>2014-08-17 19:15:54 +0200
committerNikita Popov <nikic@php.net>2014-08-17 19:15:54 +0200
commit1bab755a35ab7ffd5a551f7d9719f7045431dcd0 (patch)
tree12c654833e0c7c47dc46c04abc352d22f107b6c1 /Zend/zend_ast.c
parent84e757d22d437dcdaf5dfd08b69032240c69fb13 (diff)
downloadphp-git-1bab755a35ab7ffd5a551f7d9719f7045431dcd0.tar.gz
Fix GC when opcache is in use
Diffstat (limited to 'Zend/zend_ast.c')
-rw-r--r--Zend/zend_ast.c12
1 files changed, 9 insertions, 3 deletions
diff --git a/Zend/zend_ast.c b/Zend/zend_ast.c
index d6995efe88..eb35a51020 100644
--- a/Zend/zend_ast.c
+++ b/Zend/zend_ast.c
@@ -370,10 +370,16 @@ static void zend_ast_destroy_ex(zend_ast *ast, zend_bool free) {
switch (ast->kind) {
case ZEND_AST_ZVAL:
- zval_ptr_dtor(zend_ast_get_zval(ast));
- break;
- case ZEND_AST_ZNODE:
+ {
+ /* Destroy value without using GC: When opcache moves arrays into SHM it will
+ * free the zend_array structure, so references to it from outside the op array
+ * become invalid. GC would cause such a reference in the root buffer. */
+ zval *zv = zend_ast_get_zval(ast);
+ if (Z_REFCOUNTED_P(zv) && !Z_DELREF_P(zv)) {
+ _zval_dtor_func_for_ptr(Z_COUNTED_P(zv) ZEND_FILE_LINE_CC);
+ }
break;
+ }
case ZEND_AST_FUNC_DECL:
case ZEND_AST_CLOSURE:
case ZEND_AST_METHOD: