diff options
author | Dmitry Stogov <dmitry@zend.com> | 2014-02-10 10:04:30 +0400 |
---|---|---|
committer | Dmitry Stogov <dmitry@zend.com> | 2014-02-10 10:04:30 +0400 |
commit | f4cfaf36e23ca47da3e352e1c60909104c059647 (patch) | |
tree | 0db3e2a323b12c5bbf1a958c857f92eb58c240d1 /Zend/zend_gc.h | |
parent | 89a9acea1f9d821a9805b3857bf4febbba08690d (diff) | |
download | php-git-f4cfaf36e23ca47da3e352e1c60909104c059647.tar.gz |
Use better data structures (incomplete)
Diffstat (limited to 'Zend/zend_gc.h')
-rw-r--r-- | Zend/zend_gc.h | 143 |
1 files changed, 28 insertions, 115 deletions
diff --git a/Zend/zend_gc.h b/Zend/zend_gc.h index ac5f6350a2..2f3a399c99 100644 --- a/Zend/zend_gc.h +++ b/Zend/zend_gc.h @@ -40,62 +40,45 @@ # define GC_BENCH_PEAK(peak, counter) #endif -#define GC_COLOR 0x03 +#define GC_COLOR 0xc000 -#define GC_BLACK 0x00 -#define GC_WHITE 0x01 -#define GC_GREY 0x02 -#define GC_PURPLE 0x03 +#define GC_BLACK 0x0000 +#define GC_WHITE 0x8000 +#define GC_GREY 0x4000 +#define GC_PURPLE 0xc000 #define GC_ADDRESS(v) \ - ((gc_root_buffer*)(((zend_uintptr_t)(v)) & ~GC_COLOR)) + ((v) & ~GC_COLOR) #define GC_SET_ADDRESS(v, a) \ - (v) = ((gc_root_buffer*)((((zend_uintptr_t)(v)) & GC_COLOR) | ((zend_uintptr_t)(a)))) + do {(v) = ((v) & GC_COLOR) | (a);} while (0) #define GC_GET_COLOR(v) \ (((zend_uintptr_t)(v)) & GC_COLOR) #define GC_SET_COLOR(v, c) \ - (v) = ((gc_root_buffer*)((((zend_uintptr_t)(v)) & ~GC_COLOR) | (c))) + do {(v) = ((v) & ~GC_COLOR) | (c);} while (0) #define GC_SET_BLACK(v) \ - (v) = ((gc_root_buffer*)(((zend_uintptr_t)(v)) & ~GC_COLOR)) + do {(v) = (v) & ~GC_COLOR;} while (0) #define GC_SET_PURPLE(v) \ - (v) = ((gc_root_buffer*)(((zend_uintptr_t)(v)) | GC_PURPLE)) + do {(v) = (v) | GC_COLOR;} while (0) -#define GC_ZVAL_INIT(z) \ - ((zval_gc_info*)(z))->u.buffered = NULL #define GC_ZVAL_ADDRESS(v) \ - GC_ADDRESS(((zval_gc_info*)(v))->u.buffered) + GC_ADDRESS(Z_GC_BUFFER_P(v)) #define GC_ZVAL_SET_ADDRESS(v, a) \ - GC_SET_ADDRESS(((zval_gc_info*)(v))->u.buffered, (a)) + GC_SET_ADDRESS(Z_GC_BUFFER_P(v), (a)) #define GC_ZVAL_GET_COLOR(v) \ - GC_GET_COLOR(((zval_gc_info*)(v))->u.buffered) + GC_GET_COLOR(Z_GC_BUFFER_P(v)) #define GC_ZVAL_SET_COLOR(v, c) \ - GC_SET_COLOR(((zval_gc_info*)(v))->u.buffered, (c)) + GC_SET_COLOR(Z_GC_BUFFER_P(v), (c)) #define GC_ZVAL_SET_BLACK(v) \ - GC_SET_BLACK(((zval_gc_info*)(v))->u.buffered) + GC_SET_BLACK(Z_GC_BUFFER_P(v)) #define GC_ZVAL_SET_PURPLE(v) \ - GC_SET_PURPLE(((zval_gc_info*)(v))->u.buffered) - -#define GC_OBJ_INIT(z) \ - (z)->buffered = NULL + GC_SET_PURPLE(Z_GC_BUFFER_P(v)) typedef struct _gc_root_buffer { struct _gc_root_buffer *prev; /* double-linked list */ struct _gc_root_buffer *next; - zend_object_handle handle; /* must be 0 for zval */ - union { - zval *pz; - const zend_object_handlers *handlers; - } u; + zend_refcounted *ref; } gc_root_buffer; -typedef struct _zval_gc_info { - zval z; - union { - gc_root_buffer *buffered; - struct _zval_gc_info *next; - } u; -} zval_gc_info; - typedef struct _zend_gc_globals { zend_bool gc_enabled; zend_bool gc_active; @@ -106,9 +89,9 @@ typedef struct _zend_gc_globals { 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; /* temporary list of zvals to free */ - zval_gc_info *free_list; - zval_gc_info *next_to_free; + zend_refcounted *zval_to_free; /* temporary list of zvals to free */ + zend_refcounted *free_list; + zend_refcounted *next_to_free; zend_uint gc_runs; zend_uint collected; @@ -140,9 +123,8 @@ extern ZEND_API zend_gc_globals gc_globals; BEGIN_EXTERN_C() ZEND_API int gc_collect_cycles(TSRMLS_D); -ZEND_API void gc_zval_possible_root(zval *zv TSRMLS_DC); -ZEND_API void gc_zobj_possible_root(zval *zv TSRMLS_DC); -ZEND_API void gc_remove_zval_from_buffer(zval *zv TSRMLS_DC); +ZEND_API void gc_zval_possible_root(zend_refcounted *ref TSRMLS_DC); +ZEND_API void gc_remove_zval_from_buffer(zend_refcounted *ref TSRMLS_DC); ZEND_API void gc_globals_ctor(TSRMLS_D); ZEND_API void gc_globals_dtor(TSRMLS_D); ZEND_API void gc_init(TSRMLS_D); @@ -152,88 +134,19 @@ END_EXTERN_C() #define GC_ZVAL_CHECK_POSSIBLE_ROOT(z) \ gc_zval_check_possible_root((z) TSRMLS_CC) -#define GC_REMOVE_FROM_BUFFER(current) \ - gc_remove_from_buffer((current) TSRMLS_CC) - -#define GC_REMOVE_ZVAL_FROM_BUFFER(z) \ - if (GC_ADDRESS(((zval_gc_info*)z)->u.buffered)) { \ - gc_remove_zval_from_buffer(z TSRMLS_CC); \ - } - -#define GC_ZOBJ_CHECK_POSSIBLE_ROOT(zobject) \ - do { \ - if (EXPECTED(EG(objects_store).object_buckets != NULL) && \ - EG(objects_store).object_buckets[Z_OBJ_HANDLE_P(zobject)].valid) { \ - gc_zobj_possible_root(zobject TSRMLS_CC); \ - } \ - } while (0) - -#define GC_REMOVE_ZOBJ_FROM_BUFFER(obj) \ - do { \ - if (GC_ADDRESS((obj)->buffered) && !GC_G(gc_active)) { \ - GC_BENCH_INC(zobj_remove_from_buffer); \ - GC_REMOVE_FROM_BUFFER(GC_ADDRESS((obj)->buffered)); \ - (obj)->buffered = NULL; \ - } \ +#define GC_REMOVE_ZVAL_FROM_BUFFER(z) do { \ + if (GC_ZVAL_ADDRESS(z)) { \ + gc_remove_zval_from_buffer(Z_COUNTED_P(z) TSRMLS_CC); \ + } \ } while (0) static zend_always_inline void gc_zval_check_possible_root(zval *z TSRMLS_DC) { - if (z->type == IS_ARRAY || z->type == IS_OBJECT) { - gc_zval_possible_root(z TSRMLS_CC); + if (Z_TYPE_P(z) == IS_ARRAY || Z_TYPE_P(z) == IS_OBJECT) { + gc_zval_possible_root(Z_COUNTED_P(z) TSRMLS_CC); } } -static zend_always_inline void gc_remove_from_buffer(gc_root_buffer *root TSRMLS_DC) -{ - root->next->prev = root->prev; - root->prev->next = root->next; - root->prev = GC_G(unused); - GC_G(unused) = root; - GC_BENCH_DEC(root_buf_length); -} - -#define ALLOC_PERMANENT_ZVAL(z) \ - do { \ - (z) = (zval*)malloc(sizeof(zval_gc_info)); \ - GC_ZVAL_INIT(z); \ - } while (0) - -/* The following macros override macros from zend_alloc.h */ -#undef ALLOC_ZVAL -#define ALLOC_ZVAL(z) \ - do { \ - (z) = (zval*)emalloc(sizeof(zval_gc_info)); \ - GC_ZVAL_INIT(z); \ - } while (0) - -#undef FREE_ZVAL -#define FREE_ZVAL(z) \ - do { \ - GC_REMOVE_ZVAL_FROM_BUFFER(z); \ - efree(z); \ - } while (0) - -#undef ALLOC_ZVAL_REL -#define ALLOC_ZVAL_REL(z) \ - do { \ - (z) = (zval*)emalloc_rel(sizeof(zval_gc_info)); \ - GC_ZVAL_INIT(z); \ - } while (0) - -#undef FREE_ZVAL_REL -#define FREE_ZVAL_REL(z) \ - do { \ - GC_REMOVE_ZVAL_FROM_BUFFER(z); \ - efree_rel(z); \ - } while (0) - -#define FREE_ZVAL_EX(z) \ - efree(z) - -#define FREE_ZVAL_REL_EX(z) \ - efree_rel(z) - #endif /* ZEND_GC_H */ /* |