summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitry Stogov <dmitry@zend.com>2015-04-02 12:29:15 +0300
committerDmitry Stogov <dmitry@zend.com>2015-04-02 12:29:15 +0300
commitf29c98c1289b00e0dbb58631df6a5e006f5311d1 (patch)
treeae18ad7ea747ef14651d995ceb3d589855624128
parent3645a80b381cedf80b1503565265bc09d45fbde6 (diff)
downloadphp-git-f29c98c1289b00e0dbb58631df6a5e006f5311d1.tar.gz
Prevent GC from changing zval or object 'color' before they are actually inserted into possible roots buffer.
-rw-r--r--Zend/zend_gc.c9
1 files changed, 2 insertions, 7 deletions
diff --git a/Zend/zend_gc.c b/Zend/zend_gc.c
index 55ca456fd0..83458db631 100644
--- a/Zend/zend_gc.c
+++ b/Zend/zend_gc.c
@@ -147,8 +147,6 @@ ZEND_API void gc_zval_possible_root(zval *zv TSRMLS_DC)
GC_BENCH_INC(zval_possible_root);
if (GC_ZVAL_GET_COLOR(zv) != GC_PURPLE) {
- GC_ZVAL_SET_PURPLE(zv);
-
if (!GC_ZVAL_ADDRESS(zv)) {
gc_root_buffer *newRoot = GC_G(unused);
@@ -159,7 +157,6 @@ ZEND_API void gc_zval_possible_root(zval *zv TSRMLS_DC)
GC_G(first_unused)++;
} else {
if (!GC_G(gc_enabled)) {
- GC_ZVAL_SET_BLACK(zv);
return;
}
zv->refcount__gc++;
@@ -169,10 +166,10 @@ ZEND_API void gc_zval_possible_root(zval *zv TSRMLS_DC)
if (!newRoot) {
return;
}
- GC_ZVAL_SET_PURPLE(zv);
GC_G(unused) = newRoot->prev;
}
+ GC_ZVAL_SET_PURPLE(zv);
newRoot->next = GC_G(roots).next;
newRoot->prev = &GC_G(roots);
GC_G(roots).next->prev = newRoot;
@@ -203,7 +200,6 @@ ZEND_API void gc_zobj_possible_root(zval *zv TSRMLS_DC)
obj = &EG(objects_store).object_buckets[Z_OBJ_HANDLE_P(zv)].bucket.obj;
if (GC_GET_COLOR(obj->buffered) != GC_PURPLE) {
- GC_SET_PURPLE(obj->buffered);
if (!GC_ADDRESS(obj->buffered)) {
gc_root_buffer *newRoot = GC_G(unused);
@@ -214,7 +210,6 @@ ZEND_API void gc_zobj_possible_root(zval *zv TSRMLS_DC)
GC_G(first_unused)++;
} else {
if (!GC_G(gc_enabled)) {
- GC_ZVAL_SET_BLACK(zv);
return;
}
zv->refcount__gc++;
@@ -225,10 +220,10 @@ ZEND_API void gc_zobj_possible_root(zval *zv TSRMLS_DC)
return;
}
obj = &EG(objects_store).object_buckets[Z_OBJ_HANDLE_P(zv)].bucket.obj;
- GC_SET_PURPLE(obj->buffered);
GC_G(unused) = newRoot->prev;
}
+ GC_SET_PURPLE(obj->buffered);
newRoot->next = GC_G(roots).next;
newRoot->prev = &GC_G(roots);
GC_G(roots).next->prev = newRoot;