cvs: ZendEngine2(PHP_5_3) / zend_gc.c zend_gc.h /tests gc_029.phpt
[email protected] ("Dmitry Stogov")
| Newsgroups | php.zend-engine.cvs |
|---|---|
| Message-ID | <cvsdmitry1205519795@cvsserver> |
dmitry Fri Mar 14 18:36:35 2008 UTC
Added files: (Branch: PHP_5_3)
/ZendEngine2/tests gc_029.phpt
Modified files:
/ZendEngine2 zend_gc.c zend_gc.h
Log:
Improve GC to support garbage created in destructors during objects utilization
http://cvs.php.net/viewvc.cgi/ZendEngine2/zend_gc.c?r1=1.1.2.8&r2=1.1.2.9&diff_format=u
Index: ZendEngine2/zend_gc.c
diff -u ZendEngine2/zend_gc.c:1.1.2.8 ZendEngine2/zend_gc.c:1.1.2.9
--- ZendEngine2/zend_gc.c:1.1.2.8 Fri Mar 14 13:35:40 2008
+++ ZendEngine2/zend_gc.c Fri Mar 14 18:36:34 2008
@@ -17,7 +17,7 @@
+----------------------------------------------------------------------+
*/
-/* $Id: zend_gc.c,v 1.1.2.8 2008/03/14 13:35:40 dmitry Exp $ */
+/* $Id: zend_gc.c,v 1.1.2.9 2008/03/14 18:36:34 dmitry Exp $ */
#include "zend.h"
#include "zend_API.h"
@@ -56,6 +56,7 @@
gc_globals->unused = NULL;
gc_globals->zval_to_free = NULL;
gc_globals->free_list = NULL;
+ gc_globals->next_to_free = NULL;
gc_globals->gc_runs = 0;
gc_globals->collected = 0;
@@ -138,7 +139,7 @@
ZEND_API void gc_zval_possible_root(zval *zv TSRMLS_DC)
{
if (UNEXPECTED(GC_G(free_list) != NULL &&
- GC_ZVAL_ADDRESS(zv) != NULL &&
+ GC_ZVAL_ADDRESS(zv) != NULL &&
GC_ZVAL_GET_COLOR(zv) == GC_BLACK)) {
zval_gc_info **p = &GC_G(free_list);
@@ -260,6 +261,9 @@
while (*p != NULL) {
if (*p == (zval_gc_info*)zv) {
+ if (GC_G(next_to_free) == (zval_gc_info*)zv) {
+ GC_G(next_to_free) = ((zval_gc_info*)zv)->u.next;
+ }
*p = (*p)->u.next;
return;
}
@@ -470,14 +474,9 @@
if (Z_TYPE_P(pz) == IS_OBJECT) {
zobj_collect_white(pz TSRMLS_CC);
- if (EXPECTED(EG(objects_store).object_buckets[Z_OBJ_HANDLE_P(pz)].valid &&
- Z_OBJ_HANDLER_P(pz, get_properties) != NULL)) {
- Z_OBJPROP_P(pz)->pDestructor = NULL;
- }
} else {
if (Z_TYPE_P(pz) == IS_ARRAY) {
zend_hash_apply(Z_ARRVAL_P(pz), (apply_func_t) children_collect_white TSRMLS_CC);
- Z_ARRVAL_P(pz)->pDestructor = NULL;
}
}
@@ -521,30 +520,33 @@
}
}
+#define FREE_LIST_END ((zval_gc_info*)((-1)|~GC_COLOR))
+
ZEND_API int gc_collect_cycles(TSRMLS_D)
{
int count = 0;
if (GC_G(roots).next != &GC_G(roots)) {
- zval_gc_info *p, *q, *orig_free_list;
+ zval_gc_info *p, *q, *orig_free_list, *orig_next_to_free;
if (GC_G(gc_active)) {
return 0;
}
GC_G(gc_runs)++;
- GC_G(zval_to_free) = NULL;
+ GC_G(zval_to_free) = FREE_LIST_END;
GC_G(gc_active) = 1;
gc_mark_roots(TSRMLS_C);
gc_scan_roots(TSRMLS_C);
gc_collect_roots(TSRMLS_C);
orig_free_list = GC_G(free_list);
+ orig_next_to_free = GC_G(next_to_free);
p = GC_G(free_list) = GC_G(zval_to_free);
GC_G(zval_to_free) = NULL;
GC_G(gc_active) = 0;
/* First call destructors */
- while (p) {
+ while (p != FREE_LIST_END) {
if (Z_TYPE(p->z) == IS_OBJECT) {
if (EG(objects_store).object_buckets &&
EG(objects_store).object_buckets[Z_OBJ_HANDLE(p->z)].valid &&
@@ -558,32 +560,47 @@
} zend_end_try();
}
}
+ count++;
p = p->u.next;
}
+ /* Destroy zvals */
p = GC_G(free_list);
- while (p) {
- q = p->u.next;
+ while (p != FREE_LIST_END) {
+ GC_G(next_to_free) = p->u.next;
if (Z_TYPE(p->z) == IS_OBJECT) {
if (EG(objects_store).object_buckets &&
EG(objects_store).object_buckets[Z_OBJ_HANDLE(p->z)].valid &&
EG(objects_store).object_buckets[Z_OBJ_HANDLE(p->z)].bucket.obj.refcount <= 0) {
EG(objects_store).object_buckets[Z_OBJ_HANDLE(p->z)].bucket.obj.refcount = 1;
zend_try {
+ Z_TYPE(p->z) = IS_NULL;
zend_objects_store_del_ref_by_handle(Z_OBJ_HANDLE(p->z) TSRMLS_CC);
} zend_end_try();
}
+ } else if (Z_TYPE(p->z) == IS_ARRAY) {
+ Z_TYPE(p->z) = IS_NULL;
+ zend_hash_destroy(Z_ARRVAL(p->z));
+ FREE_HASHTABLE(Z_ARRVAL(p->z));
} else {
zend_try {
zval_dtor(&p->z);
} zend_end_try();
+ Z_TYPE(p->z) = IS_NULL;
}
+ p = GC_G(next_to_free);
+ }
+
+ /* Free zvals */
+ p = GC_G(free_list);
+ while (p != FREE_LIST_END) {
+ q = p->u.next;
FREE_ZVAL_EX(&p->z);
p = q;
- count++;
}
GC_G(collected) += count;
GC_G(free_list) = orig_free_list;
+ GC_G(next_to_free) = orig_next_to_free;
}
return count;
http://cvs.php.net/viewvc.cgi/ZendEngine2/zend_gc.h?r1=1.1.2.5&r2=1.1.2.6&diff_format=u
Index: ZendEngine2/zend_gc.h
diff -u ZendEngine2/zend_gc.h:1.1.2.5 ZendEngine2/zend_gc.h:1.1.2.6
--- ZendEngine2/zend_gc.h:1.1.2.5 Fri Mar 14 13:35:40 2008
+++ ZendEngine2/zend_gc.h Fri Mar 14 18:36:34 2008
@@ -17,7 +17,7 @@
+----------------------------------------------------------------------+
*/
-/* $Id: zend_gc.h,v 1.1.2.5 2008/03/14 13:35:40 dmitry Exp $ */
+/* $Id: zend_gc.h,v 1.1.2.6 2008/03/14 18:36:34 dmitry Exp $ */
#ifndef ZEND_GC_H
#define ZEND_GC_H
@@ -106,6 +106,7 @@
zval_gc_info *zval_to_free; /* temporaryt list of zvals to free */
zval_gc_info *free_list;
+ zval_gc_info *next_to_free;
zend_uint gc_runs;
zend_uint collected;
http://cvs.php.net/viewvc.cgi/ZendEngine2/tests/gc_029.phpt?view=markup&rev=1.1
Index: ZendEngine2/tests/gc_029.phpt
+++ ZendEngine2/tests/gc_029.phpt