]> granicus.if.org Git - php/commitdiff
Speedup GC initialization
authorDmitry Stogov <dmitry@php.net>
Fri, 11 Apr 2008 17:32:18 +0000 (17:32 +0000)
committerDmitry Stogov <dmitry@php.net>
Fri, 11 Apr 2008 17:32:18 +0000 (17:32 +0000)
Zend/zend_gc.c
Zend/zend_gc.h

index 659ec55ec6f34214c5435229c47e5d8a61bdf2b5..2f3910c2f271b2a3b0a8e9fa4a64afad8cb28371 100644 (file)
@@ -111,20 +111,18 @@ ZEND_API void gc_reset(TSRMLS_D)
        GC_G(zobj_marked_grey) = 0;
 #endif
 
-       if (GC_G(buf) &&
-           (GC_G(roots).next != &GC_G(roots) ||
-            GC_G(roots).prev != &GC_G(roots))) {
-
+       if (GC_G(buf)) {
                GC_G(roots).next = &GC_G(roots);
                GC_G(roots).prev = &GC_G(roots);
 
-               GC_G(unused) = &GC_G(buf)[0];
-               for (i = 0; i < GC_ROOT_BUFFER_MAX_ENTRIES-1; i++) {
-                       GC_G(buf)[i].prev = &GC_G(buf)[i+1];
-               }
-               GC_G(buf)[GC_ROOT_BUFFER_MAX_ENTRIES-1].prev = NULL;
+               GC_G(unused) = NULL;
+               GC_G(first_unused) = GC_G(buf);
 
                GC_G(zval_to_free) = NULL;
+       } else {
+               GC_G(unused) = NULL;
+               GC_G(first_unused) = NULL;
+               GC_G(last_unused) = NULL;
        }
 }
 
@@ -132,6 +130,7 @@ ZEND_API void gc_init(TSRMLS_D)
 {
        if (GC_G(buf) == NULL && GC_G(gc_enabled)) {
                GC_G(buf) = (gc_root_buffer*) malloc(sizeof(gc_root_buffer) * GC_ROOT_BUFFER_MAX_ENTRIES);
+               GC_G(last_unused) = &GC_G(buf)[GC_ROOT_BUFFER_MAX_ENTRIES];
                gc_reset(TSRMLS_C);
        }
 }
@@ -164,7 +163,12 @@ ZEND_API void gc_zval_possible_root(zval *zv TSRMLS_DC)
                if (!GC_ZVAL_ADDRESS(zv)) {
                        gc_root_buffer *newRoot = GC_G(unused);
 
-                       if (!newRoot) {
+                       if (newRoot) {
+                               GC_G(unused) = newRoot->prev;
+                       } else if (GC_G(first_unused) != GC_G(last_unused)) {
+                               newRoot = GC_G(first_unused);
+                               GC_G(first_unused)++;
+                       } else {
                                if (!GC_G(gc_enabled)) {
                                        GC_ZVAL_SET_BLACK(zv);
                                        return;
@@ -177,10 +181,9 @@ ZEND_API void gc_zval_possible_root(zval *zv TSRMLS_DC)
                                        return;
                                }
                                GC_ZVAL_SET_PURPLE(zv);
+                               GC_G(unused) = newRoot->prev;
                        }
 
-                       GC_G(unused) = newRoot->prev;
-
                        newRoot->next = GC_G(roots).next;
                        newRoot->prev = &GC_G(roots);
                        GC_G(roots).next->prev = newRoot;
@@ -215,7 +218,12 @@ ZEND_API void gc_zobj_possible_root(zval *zv TSRMLS_DC)
                if (!GC_ADDRESS(obj->buffered)) {
                        gc_root_buffer *newRoot = GC_G(unused);
 
-                       if (!newRoot) {
+                       if (newRoot) {
+                               GC_G(unused) = newRoot->prev;
+                       } else if (GC_G(first_unused) != GC_G(last_unused)) {
+                               newRoot = GC_G(first_unused);
+                               GC_G(first_unused)++;
+                       } else {
                                if (!GC_G(gc_enabled)) {
                                        GC_ZVAL_SET_BLACK(zv);
                                        return;
@@ -229,10 +237,9 @@ ZEND_API void gc_zobj_possible_root(zval *zv TSRMLS_DC)
                                }
                                obj = &EG(objects_store).object_buckets[Z_OBJ_HANDLE_P(zv)].bucket.obj;
                                GC_SET_PURPLE(obj->buffered);
+                               GC_G(unused) = newRoot->prev;
                        }
 
-                       GC_G(unused) = newRoot->prev;
-
                        newRoot->next = GC_G(roots).next;
                        newRoot->prev = &GC_G(roots);
                        GC_G(roots).next->prev = newRoot;
index 45fb3a7d6831d1672f22208448a4cbb34d06f929..d72ef72ab7d17351f3dd43cc4ff653445c9f9f2b 100644 (file)
@@ -103,6 +103,8 @@ typedef struct _zend_gc_globals {
        gc_root_buffer   *buf;                          /* preallocated arrays of buffers   */
        gc_root_buffer    roots;                        /* list of possible roots of cycles */
        gc_root_buffer   *unused;                       /* list of unused buffers           */
+       gc_root_buffer   *first_unused;         /* pointer to first unused buffer   */
+       gc_root_buffer   *last_unused;          /* pointer to last unused buffer    */
 
        zval_gc_info     *zval_to_free;         /* temporaryt list of zvals to free */
        zval_gc_info     *free_list;