mirror of
https://github.com/php/php-src.git
synced 2024-09-21 09:57:23 +00:00
Use macros to update specific parts of GC_TYPE_INFO() (direct assignments to GC_TYPE(), GC_FLAGS() and GC_INFO() are prohibited)
This commit is contained in:
parent
42022bc943
commit
6f483dc94c
@ -91,14 +91,6 @@
|
|||||||
((v) & ~GC_COLOR)
|
((v) & ~GC_COLOR)
|
||||||
#define GC_INFO_GET_COLOR(v) \
|
#define GC_INFO_GET_COLOR(v) \
|
||||||
(((zend_uintptr_t)(v)) & GC_COLOR)
|
(((zend_uintptr_t)(v)) & GC_COLOR)
|
||||||
#define GC_INFO_SET_ADDRESS(v, a) \
|
|
||||||
do {(v) = ((v) & GC_COLOR) | (a);} while (0)
|
|
||||||
#define GC_INFO_SET_COLOR(v, c) \
|
|
||||||
do {(v) = ((v) & ~GC_COLOR) | (c);} while (0)
|
|
||||||
#define GC_INFO_SET_BLACK(v) \
|
|
||||||
do {(v) = (v) & ~GC_COLOR;} while (0)
|
|
||||||
#define GC_INFO_SET_PURPLE(v) \
|
|
||||||
do {(v) = (v) | GC_COLOR;} while (0)
|
|
||||||
|
|
||||||
/* one (0) is reserved */
|
/* one (0) is reserved */
|
||||||
#define GC_ROOT_BUFFER_MAX_ENTRIES 10001
|
#define GC_ROOT_BUFFER_MAX_ENTRIES 10001
|
||||||
@ -192,16 +184,26 @@ static zend_gc_globals gc_globals;
|
|||||||
# define GC_TRACE(str)
|
# define GC_TRACE(str)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define GC_REF_SET_ADDRESS(ref, a) \
|
#define GC_REF_SET_INFO(ref, info) do { \
|
||||||
GC_INFO_SET_ADDRESS(GC_INFO(ref), a)
|
GC_TYPE_INFO(ref) = ((info) << GC_INFO_SHIFT) | \
|
||||||
|
(GC_TYPE_INFO(ref) & (GC_TYPE_MASK | GC_FLAGS_MASK)); \
|
||||||
|
} while (0)
|
||||||
|
#define GC_REF_SET_ADDRESS(ref, a) do {\
|
||||||
|
GC_TYPE_INFO(ref) = ((info) << GC_INFO_SHIFT) | \
|
||||||
|
(GC_TYPE_INFO(ref) & (GC_TYPE_MASK | GC_FLAGS_MASK | (GC_COLOR << GC_INFO_SHIFT))); \
|
||||||
|
} while (0)
|
||||||
#define GC_REF_GET_COLOR(ref) \
|
#define GC_REF_GET_COLOR(ref) \
|
||||||
GC_INFO_GET_COLOR(GC_INFO(ref))
|
GC_INFO_GET_COLOR(GC_INFO(ref))
|
||||||
#define GC_REF_SET_COLOR(ref, c) \
|
#define GC_REF_SET_COLOR(ref, c) do { \
|
||||||
do { GC_TRACE_SET_COLOR(ref, c); GC_INFO_SET_COLOR(GC_INFO(ref), c); } while (0)
|
GC_TYPE_INFO(ref) = ((c) << GC_INFO_SHIFT) | \
|
||||||
#define GC_REF_SET_BLACK(ref) \
|
(GC_TYPE_INFO(ref) & (GC_TYPE_MASK | GC_FLAGS_MASK | ~(GC_COLOR << GC_INFO_SHIFT))); \
|
||||||
do { GC_TRACE_SET_COLOR(ref, GC_BLACK); GC_INFO_SET_BLACK(GC_INFO(ref)); } while (0)
|
} while (0)
|
||||||
#define GC_REF_SET_PURPLE(ref) \
|
#define GC_REF_SET_BLACK(ref) do { \
|
||||||
do { GC_TRACE_SET_COLOR(ref, GC_PURPLE); GC_INFO_SET_PURPLE(GC_INFO(ref)); } while (0)
|
GC_TYPE_INFO(ref) &= ~(GC_COLOR << GC_INFO_SHIFT); \
|
||||||
|
} while (0)
|
||||||
|
#define GC_REF_SET_PURPLE(ref) do { \
|
||||||
|
GC_TYPE_INFO(ref) |= (GC_COLOR << GC_INFO_SHIFT); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
#if ZEND_GC_DEBUG > 1
|
#if ZEND_GC_DEBUG > 1
|
||||||
static const char *gc_color_name(uint32_t color) {
|
static const char *gc_color_name(uint32_t color) {
|
||||||
@ -402,7 +404,7 @@ ZEND_API void ZEND_FASTCALL gc_possible_root(zend_refcounted *ref)
|
|||||||
}
|
}
|
||||||
|
|
||||||
GC_TRACE_SET_COLOR(ref, GC_PURPLE);
|
GC_TRACE_SET_COLOR(ref, GC_PURPLE);
|
||||||
GC_INFO(ref) = (newRoot - GC_G(buf)) | GC_PURPLE;
|
GC_REF_SET_INFO(ref, (newRoot - GC_G(buf)) | GC_PURPLE);
|
||||||
newRoot->ref = ref;
|
newRoot->ref = ref;
|
||||||
|
|
||||||
newRoot->next = GC_G(roots).next;
|
newRoot->next = GC_G(roots).next;
|
||||||
@ -453,7 +455,7 @@ ZEND_API void ZEND_FASTCALL gc_remove_from_buffer(zend_refcounted *ref)
|
|||||||
if (GC_REF_GET_COLOR(ref) != GC_BLACK) {
|
if (GC_REF_GET_COLOR(ref) != GC_BLACK) {
|
||||||
GC_TRACE_SET_COLOR(ref, GC_PURPLE);
|
GC_TRACE_SET_COLOR(ref, GC_PURPLE);
|
||||||
}
|
}
|
||||||
GC_INFO(ref) = 0;
|
GC_REF_SET_INFO(ref, 0);
|
||||||
|
|
||||||
/* updete next root that is going to be freed */
|
/* updete next root that is going to be freed */
|
||||||
if (GC_G(next_to_free) == root) {
|
if (GC_G(next_to_free) == root) {
|
||||||
@ -797,7 +799,7 @@ static void gc_add_garbage(zend_refcounted *ref)
|
|||||||
GC_G(unused) = buf->prev;
|
GC_G(unused) = buf->prev;
|
||||||
#if 1
|
#if 1
|
||||||
/* optimization: color is already GC_BLACK (0) */
|
/* optimization: color is already GC_BLACK (0) */
|
||||||
GC_INFO(ref) = buf - GC_G(buf);
|
GC_REF_SET_INFO(ref, buf - GC_G(buf));
|
||||||
#else
|
#else
|
||||||
GC_REF_SET_ADDRESS(ref, buf - GC_G(buf));
|
GC_REF_SET_ADDRESS(ref, buf - GC_G(buf));
|
||||||
#endif
|
#endif
|
||||||
@ -806,7 +808,7 @@ static void gc_add_garbage(zend_refcounted *ref)
|
|||||||
GC_G(first_unused)++;
|
GC_G(first_unused)++;
|
||||||
#if 1
|
#if 1
|
||||||
/* optimization: color is already GC_BLACK (0) */
|
/* optimization: color is already GC_BLACK (0) */
|
||||||
GC_INFO(ref) = buf - GC_G(buf);
|
GC_REF_SET_INFO(ref, buf - GC_G(buf));
|
||||||
#else
|
#else
|
||||||
GC_REF_SET_ADDRESS(ref, buf - GC_G(buf));
|
GC_REF_SET_ADDRESS(ref, buf - GC_G(buf));
|
||||||
#endif
|
#endif
|
||||||
@ -824,7 +826,7 @@ static void gc_add_garbage(zend_refcounted *ref)
|
|||||||
buf = GC_G(additional_buffer)->buf + GC_G(additional_buffer)->used;
|
buf = GC_G(additional_buffer)->buf + GC_G(additional_buffer)->used;
|
||||||
#if 1
|
#if 1
|
||||||
/* optimization: color is already GC_BLACK (0) */
|
/* optimization: color is already GC_BLACK (0) */
|
||||||
GC_INFO(ref) = GC_ROOT_BUFFER_MAX_ENTRIES + GC_G(additional_buffer)->used;
|
GC_REF_SET_INFO(ref, GC_ROOT_BUFFER_MAX_ENTRIES + GC_G(additional_buffer)->used);
|
||||||
#else
|
#else
|
||||||
GC_REF_SET_ADDRESS(ref, GC_ROOT_BUFFER_MAX_ENTRIES) + GC_G(additional_buffer)->used;
|
GC_REF_SET_ADDRESS(ref, GC_ROOT_BUFFER_MAX_ENTRIES) + GC_G(additional_buffer)->used;
|
||||||
#endif
|
#endif
|
||||||
@ -990,7 +992,7 @@ static int gc_collect_roots(uint32_t *flags)
|
|||||||
} else {
|
} else {
|
||||||
gc_remove_from_additional_roots(current);
|
gc_remove_from_additional_roots(current);
|
||||||
}
|
}
|
||||||
GC_INFO(current->ref) = 0; /* reset GC_ADDRESS() and keep GC_BLACK */
|
GC_REF_SET_INFO(current->ref, 0); /* reset GC_ADDRESS() and keep GC_BLACK */
|
||||||
}
|
}
|
||||||
current = next;
|
current = next;
|
||||||
}
|
}
|
||||||
@ -1042,7 +1044,7 @@ tail_call:
|
|||||||
} else {
|
} else {
|
||||||
gc_remove_from_additional_roots(root);
|
gc_remove_from_additional_roots(root);
|
||||||
}
|
}
|
||||||
GC_INFO(ref) = 0;
|
GC_REF_SET_INFO(ref, 0);
|
||||||
root = NULL;
|
root = NULL;
|
||||||
} else {
|
} else {
|
||||||
GC_REMOVE_FROM_BUFFER(ref);
|
GC_REMOVE_FROM_BUFFER(ref);
|
||||||
@ -1210,7 +1212,7 @@ ZEND_API int zend_gc_collect_cycles(void)
|
|||||||
|
|
||||||
if (!(OBJ_FLAGS(obj) & IS_OBJ_DESTRUCTOR_CALLED)) {
|
if (!(OBJ_FLAGS(obj) & IS_OBJ_DESTRUCTOR_CALLED)) {
|
||||||
GC_TRACE_REF(obj, "calling destructor");
|
GC_TRACE_REF(obj, "calling destructor");
|
||||||
OBJ_FLAGS(obj) |= IS_OBJ_DESTRUCTOR_CALLED;
|
GC_ADD_FLAGS(obj, IS_OBJ_DESTRUCTOR_CALLED);
|
||||||
if (obj->handlers->dtor_obj
|
if (obj->handlers->dtor_obj
|
||||||
&& (obj->handlers->dtor_obj != zend_objects_destroy_object
|
&& (obj->handlers->dtor_obj != zend_objects_destroy_object
|
||||||
|| obj->ce->destructor)) {
|
|| obj->ce->destructor)) {
|
||||||
@ -1246,9 +1248,10 @@ ZEND_API int zend_gc_collect_cycles(void)
|
|||||||
zend_object *obj = (zend_object*)p;
|
zend_object *obj = (zend_object*)p;
|
||||||
|
|
||||||
EG(objects_store).object_buckets[obj->handle] = SET_OBJ_INVALID(obj);
|
EG(objects_store).object_buckets[obj->handle] = SET_OBJ_INVALID(obj);
|
||||||
GC_TYPE(obj) = IS_NULL;
|
GC_TYPE_INFO(obj) = IS_NULL |
|
||||||
|
(GC_TYPE_INFO(obj) & ~GC_TYPE_MASK);
|
||||||
if (!(OBJ_FLAGS(obj) & IS_OBJ_FREE_CALLED)) {
|
if (!(OBJ_FLAGS(obj) & IS_OBJ_FREE_CALLED)) {
|
||||||
OBJ_FLAGS(obj) |= IS_OBJ_FREE_CALLED;
|
GC_ADD_FLAGS(obj, IS_OBJ_FREE_CALLED);
|
||||||
if (obj->handlers->free_obj) {
|
if (obj->handlers->free_obj) {
|
||||||
GC_ADDREF(obj);
|
GC_ADDREF(obj);
|
||||||
obj->handlers->free_obj(obj);
|
obj->handlers->free_obj(obj);
|
||||||
@ -1261,7 +1264,8 @@ ZEND_API int zend_gc_collect_cycles(void)
|
|||||||
} else if (GC_TYPE(p) == IS_ARRAY) {
|
} else if (GC_TYPE(p) == IS_ARRAY) {
|
||||||
zend_array *arr = (zend_array*)p;
|
zend_array *arr = (zend_array*)p;
|
||||||
|
|
||||||
GC_TYPE(arr) = IS_NULL;
|
GC_TYPE_INFO(arr) = IS_NULL |
|
||||||
|
(GC_TYPE_INFO(arr) & ~GC_TYPE_MASK);
|
||||||
|
|
||||||
/* GC may destroy arrays with rc>1. This is valid and safe. */
|
/* GC may destroy arrays with rc>1. This is valid and safe. */
|
||||||
HT_ALLOW_COW_VIOLATION(arr);
|
HT_ALLOW_COW_VIOLATION(arr);
|
||||||
|
@ -51,7 +51,7 @@ END_EXTERN_C()
|
|||||||
|
|
||||||
static zend_always_inline void gc_check_possible_root(zend_refcounted *ref)
|
static zend_always_inline void gc_check_possible_root(zend_refcounted *ref)
|
||||||
{
|
{
|
||||||
if (GC_TYPE(ref) == IS_REFERENCE) {
|
if (GC_TYPE_INFO(ref) == IS_REFERENCE) {
|
||||||
zval *zv = &((zend_reference*)ref)->val;
|
zval *zv = &((zend_reference*)ref)->val;
|
||||||
|
|
||||||
if (!Z_REFCOUNTED_P(zv)) {
|
if (!Z_REFCOUNTED_P(zv)) {
|
||||||
|
@ -49,7 +49,7 @@ ZEND_API void ZEND_FASTCALL zend_objects_store_call_destructors(zend_objects_sto
|
|||||||
zend_object *obj = objects->object_buckets[i];
|
zend_object *obj = objects->object_buckets[i];
|
||||||
if (IS_OBJ_VALID(obj)) {
|
if (IS_OBJ_VALID(obj)) {
|
||||||
if (!(OBJ_FLAGS(obj) & IS_OBJ_DESTRUCTOR_CALLED)) {
|
if (!(OBJ_FLAGS(obj) & IS_OBJ_DESTRUCTOR_CALLED)) {
|
||||||
OBJ_FLAGS(obj) |= IS_OBJ_DESTRUCTOR_CALLED;
|
GC_ADD_FLAGS(obj, IS_OBJ_DESTRUCTOR_CALLED);
|
||||||
|
|
||||||
if (obj->handlers->dtor_obj
|
if (obj->handlers->dtor_obj
|
||||||
&& (obj->handlers->dtor_obj != zend_objects_destroy_object
|
&& (obj->handlers->dtor_obj != zend_objects_destroy_object
|
||||||
@ -74,7 +74,7 @@ ZEND_API void ZEND_FASTCALL zend_objects_store_mark_destructed(zend_objects_stor
|
|||||||
zend_object *obj = *obj_ptr;
|
zend_object *obj = *obj_ptr;
|
||||||
|
|
||||||
if (IS_OBJ_VALID(obj)) {
|
if (IS_OBJ_VALID(obj)) {
|
||||||
OBJ_FLAGS(obj) |= IS_OBJ_DESTRUCTOR_CALLED;
|
GC_ADD_FLAGS(obj, IS_OBJ_DESTRUCTOR_CALLED);
|
||||||
}
|
}
|
||||||
obj_ptr++;
|
obj_ptr++;
|
||||||
} while (obj_ptr != end);
|
} while (obj_ptr != end);
|
||||||
@ -99,7 +99,7 @@ ZEND_API void ZEND_FASTCALL zend_objects_store_free_object_storage(zend_objects_
|
|||||||
obj = *obj_ptr;
|
obj = *obj_ptr;
|
||||||
if (IS_OBJ_VALID(obj)) {
|
if (IS_OBJ_VALID(obj)) {
|
||||||
if (!(OBJ_FLAGS(obj) & IS_OBJ_FREE_CALLED)) {
|
if (!(OBJ_FLAGS(obj) & IS_OBJ_FREE_CALLED)) {
|
||||||
OBJ_FLAGS(obj) |= IS_OBJ_FREE_CALLED;
|
GC_ADD_FLAGS(obj, IS_OBJ_FREE_CALLED);
|
||||||
if (obj->handlers->free_obj && obj->handlers->free_obj != zend_object_std_dtor) {
|
if (obj->handlers->free_obj && obj->handlers->free_obj != zend_object_std_dtor) {
|
||||||
GC_ADDREF(obj);
|
GC_ADDREF(obj);
|
||||||
obj->handlers->free_obj(obj);
|
obj->handlers->free_obj(obj);
|
||||||
@ -114,7 +114,7 @@ ZEND_API void ZEND_FASTCALL zend_objects_store_free_object_storage(zend_objects_
|
|||||||
obj = *obj_ptr;
|
obj = *obj_ptr;
|
||||||
if (IS_OBJ_VALID(obj)) {
|
if (IS_OBJ_VALID(obj)) {
|
||||||
if (!(OBJ_FLAGS(obj) & IS_OBJ_FREE_CALLED)) {
|
if (!(OBJ_FLAGS(obj) & IS_OBJ_FREE_CALLED)) {
|
||||||
OBJ_FLAGS(obj) |= IS_OBJ_FREE_CALLED;
|
GC_ADD_FLAGS(obj, IS_OBJ_FREE_CALLED);
|
||||||
if (obj->handlers->free_obj) {
|
if (obj->handlers->free_obj) {
|
||||||
GC_ADDREF(obj);
|
GC_ADDREF(obj);
|
||||||
obj->handlers->free_obj(obj);
|
obj->handlers->free_obj(obj);
|
||||||
@ -165,7 +165,7 @@ ZEND_API void ZEND_FASTCALL zend_objects_store_del(zend_object *object) /* {{{ *
|
|||||||
ZEND_ASSERT(GC_REFCOUNT(object) == 0);
|
ZEND_ASSERT(GC_REFCOUNT(object) == 0);
|
||||||
|
|
||||||
if (!(OBJ_FLAGS(object) & IS_OBJ_DESTRUCTOR_CALLED)) {
|
if (!(OBJ_FLAGS(object) & IS_OBJ_DESTRUCTOR_CALLED)) {
|
||||||
OBJ_FLAGS(object) |= IS_OBJ_DESTRUCTOR_CALLED;
|
GC_ADD_FLAGS(object, IS_OBJ_DESTRUCTOR_CALLED);
|
||||||
|
|
||||||
if (object->handlers->dtor_obj
|
if (object->handlers->dtor_obj
|
||||||
&& (object->handlers->dtor_obj != zend_objects_destroy_object
|
&& (object->handlers->dtor_obj != zend_objects_destroy_object
|
||||||
@ -182,7 +182,7 @@ ZEND_API void ZEND_FASTCALL zend_objects_store_del(zend_object *object) /* {{{ *
|
|||||||
|
|
||||||
EG(objects_store).object_buckets[handle] = SET_OBJ_INVALID(object);
|
EG(objects_store).object_buckets[handle] = SET_OBJ_INVALID(object);
|
||||||
if (!(OBJ_FLAGS(object) & IS_OBJ_FREE_CALLED)) {
|
if (!(OBJ_FLAGS(object) & IS_OBJ_FREE_CALLED)) {
|
||||||
OBJ_FLAGS(object) |= IS_OBJ_FREE_CALLED;
|
GC_ADD_FLAGS(object, IS_OBJ_FREE_CALLED);
|
||||||
if (object->handlers->free_obj) {
|
if (object->handlers->free_obj) {
|
||||||
GC_ADDREF(object);
|
GC_ADDREF(object);
|
||||||
object->handlers->free_obj(object);
|
object->handlers->free_obj(object);
|
||||||
|
@ -62,7 +62,7 @@ ZEND_API void ZEND_FASTCALL zend_objects_store_del(zend_object *object);
|
|||||||
/* Called when the ctor was terminated by an exception */
|
/* Called when the ctor was terminated by an exception */
|
||||||
static zend_always_inline void zend_object_store_ctor_failed(zend_object *obj)
|
static zend_always_inline void zend_object_store_ctor_failed(zend_object *obj)
|
||||||
{
|
{
|
||||||
OBJ_FLAGS(obj) |= IS_OBJ_DESTRUCTOR_CALLED;
|
GC_ADD_FLAGS(obj, IS_OBJ_DESTRUCTOR_CALLED);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define ZEND_OBJECTS_STORE_HANDLERS 0, zend_object_std_dtor, zend_objects_destroy_object, zend_objects_clone_obj
|
#define ZEND_OBJECTS_STORE_HANDLERS 0, zend_object_std_dtor, zend_objects_destroy_object, zend_objects_clone_obj
|
||||||
|
@ -166,7 +166,7 @@ static zend_always_inline zend_string *zend_add_interned_string(zend_string *str
|
|||||||
zval val;
|
zval val;
|
||||||
|
|
||||||
GC_SET_REFCOUNT(str, 1);
|
GC_SET_REFCOUNT(str, 1);
|
||||||
GC_FLAGS(str) |= IS_STR_INTERNED | flags;
|
GC_ADD_FLAGS(str, IS_STR_INTERNED | flags);
|
||||||
|
|
||||||
ZVAL_INTERNED_STR(&val, str);
|
ZVAL_INTERNED_STR(&val, str);
|
||||||
|
|
||||||
|
@ -446,10 +446,35 @@ static zend_always_inline zend_uchar zval_get_type(const zval* pz) {
|
|||||||
#define GC_ADDREF_EX(p, rc) zend_gc_addref_ex(&(p)->gc, rc)
|
#define GC_ADDREF_EX(p, rc) zend_gc_addref_ex(&(p)->gc, rc)
|
||||||
#define GC_DELREF_EX(p, rc) zend_gc_delref_ex(&(p)->gc, rc)
|
#define GC_DELREF_EX(p, rc) zend_gc_delref_ex(&(p)->gc, rc)
|
||||||
|
|
||||||
#define GC_TYPE(p) (p)->gc.u.v.type
|
#define GC_TYPE_MASK 0x000000ff
|
||||||
#define GC_FLAGS(p) (p)->gc.u.v.flags
|
#define GC_FLAGS_MASK 0x0000ff00
|
||||||
#define GC_INFO(p) (p)->gc.u.v.gc_info
|
#define GC_INFO_MASK 0xffff0000
|
||||||
|
#define GC_FLAGS_SHIFT 8
|
||||||
|
#define GC_INFO_SHIFT 16
|
||||||
|
|
||||||
|
static zend_always_inline zend_uchar zval_gc_type(uint32_t gc_type_info) {
|
||||||
|
return (gc_type_info & GC_TYPE_MASK);
|
||||||
|
}
|
||||||
|
|
||||||
|
static zend_always_inline zend_uchar zval_gc_flags(uint32_t gc_type_info) {
|
||||||
|
return (gc_type_info >> GC_FLAGS_SHIFT) & (GC_FLAGS_MASK >> GC_FLAGS_SHIFT);
|
||||||
|
}
|
||||||
|
|
||||||
|
static zend_always_inline uint32_t zval_gc_info(uint32_t gc_type_info) {
|
||||||
|
return (gc_type_info >> GC_INFO_SHIFT);
|
||||||
|
}
|
||||||
|
|
||||||
#define GC_TYPE_INFO(p) (p)->gc.u.type_info
|
#define GC_TYPE_INFO(p) (p)->gc.u.type_info
|
||||||
|
#define GC_TYPE(p) zval_gc_type(GC_TYPE_INFO(p))
|
||||||
|
#define GC_FLAGS(p) zval_gc_flags(GC_TYPE_INFO(p))
|
||||||
|
#define GC_INFO(p) zval_gc_info(GC_TYPE_INFO(p))
|
||||||
|
|
||||||
|
#define GC_ADD_FLAGS(p, flags) do { \
|
||||||
|
GC_TYPE_INFO(p) |= (flags) << GC_FLAGS_SHIFT; \
|
||||||
|
} while (0)
|
||||||
|
#define GC_DEL_FLAGS(p, flags) do { \
|
||||||
|
GC_TYPE_INFO(p) &= ~((flags) << GC_FLAGS_SHIFT); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
#define Z_GC_TYPE(zval) GC_TYPE(Z_COUNTED(zval))
|
#define Z_GC_TYPE(zval) GC_TYPE(Z_COUNTED(zval))
|
||||||
#define Z_GC_TYPE_P(zval_p) Z_GC_TYPE(*(zval_p))
|
#define Z_GC_TYPE_P(zval_p) Z_GC_TYPE(*(zval_p))
|
||||||
@ -462,10 +487,6 @@ static zend_always_inline zend_uchar zval_get_type(const zval* pz) {
|
|||||||
#define Z_GC_TYPE_INFO(zval) GC_TYPE_INFO(Z_COUNTED(zval))
|
#define Z_GC_TYPE_INFO(zval) GC_TYPE_INFO(Z_COUNTED(zval))
|
||||||
#define Z_GC_TYPE_INFO_P(zval_p) Z_GC_TYPE_INFO(*(zval_p))
|
#define Z_GC_TYPE_INFO_P(zval_p) Z_GC_TYPE_INFO(*(zval_p))
|
||||||
|
|
||||||
#define GC_FLAGS_SHIFT 8
|
|
||||||
#define GC_INFO_SHIFT 16
|
|
||||||
#define GC_INFO_MASK 0xffff0000
|
|
||||||
|
|
||||||
/* zval.value->gc.u.v.flags (common flags) */
|
/* zval.value->gc.u.v.flags (common flags) */
|
||||||
#define GC_COLLECTABLE (1<<0)
|
#define GC_COLLECTABLE (1<<0)
|
||||||
#define GC_PROTECTED (1<<1) /* used for recursion detection */
|
#define GC_PROTECTED (1<<1) /* used for recursion detection */
|
||||||
@ -517,11 +538,11 @@ static zend_always_inline zend_uchar zval_get_type(const zval* pz) {
|
|||||||
(GC_FLAGS(p) & GC_PROTECTED)
|
(GC_FLAGS(p) & GC_PROTECTED)
|
||||||
|
|
||||||
#define GC_PROTECT_RECURSION(p) do { \
|
#define GC_PROTECT_RECURSION(p) do { \
|
||||||
GC_FLAGS(p) |= GC_PROTECTED; \
|
GC_ADD_FLAGS(p, GC_PROTECTED); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#define GC_UNPROTECT_RECURSION(p) do { \
|
#define GC_UNPROTECT_RECURSION(p) do { \
|
||||||
GC_FLAGS(p) &= ~GC_PROTECTED; \
|
GC_DEL_FLAGS(p, GC_PROTECTED); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#define Z_IS_RECURSIVE(zval) GC_IS_RECURSIVE(Z_COUNTED(zval))
|
#define Z_IS_RECURSIVE(zval) GC_IS_RECURSIVE(Z_COUNTED(zval))
|
||||||
@ -914,7 +935,7 @@ extern ZEND_API zend_bool zend_rc_debug;
|
|||||||
} \
|
} \
|
||||||
} while (0)
|
} while (0)
|
||||||
# define GC_MAKE_PERSISTENT_LOCAL(p) do { \
|
# define GC_MAKE_PERSISTENT_LOCAL(p) do { \
|
||||||
GC_FLAGS(p) |= GC_PERSISTENT_LOCAL; \
|
GC_ADD_FLAGS(p, GC_PERSISTENT_LOCAL); \
|
||||||
} while (0)
|
} while (0)
|
||||||
#else
|
#else
|
||||||
# define ZEND_RC_MOD_CHECK(p) \
|
# define ZEND_RC_MOD_CHECK(p) \
|
||||||
|
@ -480,13 +480,7 @@ zend_string *accel_new_interned_string(zend_string *str)
|
|||||||
STRTAB_COLLISION(s) = *hash_slot;
|
STRTAB_COLLISION(s) = *hash_slot;
|
||||||
*hash_slot = STRTAB_STR_TO_POS(&ZCSG(interned_strings), s);
|
*hash_slot = STRTAB_STR_TO_POS(&ZCSG(interned_strings), s);
|
||||||
GC_SET_REFCOUNT(s, 1);
|
GC_SET_REFCOUNT(s, 1);
|
||||||
#if 1
|
|
||||||
/* optimized single assignment */
|
|
||||||
GC_TYPE_INFO(s) = IS_STRING | ((IS_STR_INTERNED | IS_STR_PERMANENT) << GC_FLAGS_SHIFT);
|
GC_TYPE_INFO(s) = IS_STRING | ((IS_STR_INTERNED | IS_STR_PERMANENT) << GC_FLAGS_SHIFT);
|
||||||
#else
|
|
||||||
GC_TYPE(s) = IS_STRING;
|
|
||||||
GC_FLAGS(s) = IS_STR_INTERNED | IS_STR_PERMANENT;
|
|
||||||
#endif
|
|
||||||
ZSTR_H(s) = h;
|
ZSTR_H(s) = h;
|
||||||
ZSTR_LEN(s) = ZSTR_LEN(str);
|
ZSTR_LEN(s) = ZSTR_LEN(str);
|
||||||
memcpy(ZSTR_VAL(s), ZSTR_VAL(str), ZSTR_LEN(s) + 1);
|
memcpy(ZSTR_VAL(s), ZSTR_VAL(str), ZSTR_LEN(s) + 1);
|
||||||
|
@ -118,8 +118,8 @@ static int zend_file_cache_flock(int fd, int type)
|
|||||||
ZEND_ASSERT(IS_UNSERIALIZED(ptr)); \
|
ZEND_ASSERT(IS_UNSERIALIZED(ptr)); \
|
||||||
/* script->corrupted shows if the script in SHM or not */ \
|
/* script->corrupted shows if the script in SHM or not */ \
|
||||||
if (EXPECTED(script->corrupted)) { \
|
if (EXPECTED(script->corrupted)) { \
|
||||||
GC_FLAGS(ptr) |= IS_STR_INTERNED; \
|
GC_ADD_FLAGS(ptr, IS_STR_INTERNED); \
|
||||||
GC_FLAGS(ptr) &= ~IS_STR_PERMANENT; \
|
GC_DEL_FLAGS(ptr, IS_STR_PERMANENT); \
|
||||||
} \
|
} \
|
||||||
(ptr) = (void*)((char*)(ptr) - (char*)script->mem); \
|
(ptr) = (void*)((char*)(ptr) - (char*)script->mem); \
|
||||||
} \
|
} \
|
||||||
@ -134,10 +134,10 @@ static int zend_file_cache_flock(int fd, int type)
|
|||||||
(ptr) = (void*)((char*)buf + (size_t)(ptr)); \
|
(ptr) = (void*)((char*)buf + (size_t)(ptr)); \
|
||||||
/* script->corrupted shows if the script in SHM or not */ \
|
/* script->corrupted shows if the script in SHM or not */ \
|
||||||
if (EXPECTED(!script->corrupted)) { \
|
if (EXPECTED(!script->corrupted)) { \
|
||||||
GC_FLAGS(ptr) |= IS_STR_INTERNED | IS_STR_PERMANENT; \
|
GC_ADD_FLAGS(ptr, IS_STR_INTERNED | IS_STR_PERMANENT); \
|
||||||
} else { \
|
} else { \
|
||||||
GC_FLAGS(ptr) |= IS_STR_INTERNED; \
|
GC_ADD_FLAGS(ptr, IS_STR_INTERNED); \
|
||||||
GC_FLAGS(ptr) &= ~IS_STR_PERMANENT; \
|
GC_DEL_FLAGS(ptr, IS_STR_PERMANENT); \
|
||||||
} \
|
} \
|
||||||
} \
|
} \
|
||||||
} \
|
} \
|
||||||
@ -241,8 +241,8 @@ static void *zend_file_cache_unserialize_interned(zend_string *str, int in_shm)
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
ret = str;
|
ret = str;
|
||||||
GC_FLAGS(ret) |= IS_STR_INTERNED;
|
GC_ADD_FLAGS(ret, IS_STR_INTERNED);
|
||||||
GC_FLAGS(ret) &= ~IS_STR_PERMANENT;
|
GC_DEL_FLAGS(ret, IS_STR_PERMANENT);
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -36,13 +36,15 @@
|
|||||||
#ifdef HAVE_OPCACHE_FILE_CACHE
|
#ifdef HAVE_OPCACHE_FILE_CACHE
|
||||||
#define zend_set_str_gc_flags(str) do { \
|
#define zend_set_str_gc_flags(str) do { \
|
||||||
if (ZCG(accel_directives).file_cache_only) { \
|
if (ZCG(accel_directives).file_cache_only) { \
|
||||||
GC_FLAGS(str) = IS_STR_INTERNED; \
|
GC_TYPE_INFO(str) = IS_STRING | (IS_STR_INTERNED << GC_FLAGS_SHIFT); \
|
||||||
} else { \
|
} else { \
|
||||||
GC_FLAGS(str) = IS_STR_INTERNED | IS_STR_PERMANENT; \
|
GC_TYPE_INFO(str) = IS_STRING | ((IS_STR_INTERNED | IS_STR_PERMANENT) << GC_FLAGS_SHIFT); \
|
||||||
} \
|
} \
|
||||||
} while (0)
|
} while (0)
|
||||||
#else
|
#else
|
||||||
#define zend_set_str_gc_flags(str) GC_FLAGS(str) = IS_STR_INTERNED | IS_STR_PERMANENT
|
#define zend_set_str_gc_flags(str) do {\
|
||||||
|
GC_TYPE_INFO(str) = IS_STRING | ((IS_STR_INTERNED | IS_STR_PERMANENT) << GC_FLAGS_SHIFT); \
|
||||||
|
} while (0)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define zend_accel_store_string(str) do { \
|
#define zend_accel_store_string(str) do { \
|
||||||
@ -301,7 +303,7 @@ static void zend_persist_zval(zval *z)
|
|||||||
/* make immutable array */
|
/* make immutable array */
|
||||||
Z_TYPE_FLAGS_P(z) = 0;
|
Z_TYPE_FLAGS_P(z) = 0;
|
||||||
GC_SET_REFCOUNT(Z_COUNTED_P(z), 2);
|
GC_SET_REFCOUNT(Z_COUNTED_P(z), 2);
|
||||||
GC_FLAGS(Z_COUNTED_P(z)) |= IS_ARRAY_IMMUTABLE;
|
GC_ADD_FLAGS(Z_COUNTED_P(z), IS_ARRAY_IMMUTABLE);
|
||||||
HT_FLAGS(Z_ARRVAL_P(z)) |= HASH_FLAG_STATIC_KEYS;
|
HT_FLAGS(Z_ARRVAL_P(z)) |= HASH_FLAG_STATIC_KEYS;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -223,13 +223,13 @@ PHPAPI void var_destroy(php_unserialize_data_t *var_hashx)
|
|||||||
BG(serialize_lock)++;
|
BG(serialize_lock)++;
|
||||||
if (call_user_function_ex(CG(function_table), zv, &wakeup_name, &retval, 0, 0, 1, NULL) == FAILURE || Z_ISUNDEF(retval)) {
|
if (call_user_function_ex(CG(function_table), zv, &wakeup_name, &retval, 0, 0, 1, NULL) == FAILURE || Z_ISUNDEF(retval)) {
|
||||||
wakeup_failed = 1;
|
wakeup_failed = 1;
|
||||||
OBJ_FLAGS(Z_OBJ_P(zv)) |= IS_OBJ_DESTRUCTOR_CALLED;
|
GC_ADD_FLAGS(Z_OBJ_P(zv), IS_OBJ_DESTRUCTOR_CALLED);
|
||||||
}
|
}
|
||||||
BG(serialize_lock)--;
|
BG(serialize_lock)--;
|
||||||
|
|
||||||
zval_ptr_dtor(&retval);
|
zval_ptr_dtor(&retval);
|
||||||
} else {
|
} else {
|
||||||
OBJ_FLAGS(Z_OBJ_P(zv)) |= IS_OBJ_DESTRUCTOR_CALLED;
|
GC_ADD_FLAGS(Z_OBJ_P(zv), IS_OBJ_DESTRUCTOR_CALLED);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -603,7 +603,7 @@ static inline int object_common2(UNSERIALIZE_PARAMETER, zend_long elements)
|
|||||||
if (!process_nested_data(UNSERIALIZE_PASSTHRU, ht, elements, 1)) {
|
if (!process_nested_data(UNSERIALIZE_PASSTHRU, ht, elements, 1)) {
|
||||||
if (has_wakeup) {
|
if (has_wakeup) {
|
||||||
ZVAL_DEREF(rval);
|
ZVAL_DEREF(rval);
|
||||||
OBJ_FLAGS(Z_OBJ_P(rval)) |= IS_OBJ_DESTRUCTOR_CALLED;
|
GC_ADD_FLAGS(Z_OBJ_P(rval), IS_OBJ_DESTRUCTOR_CALLED);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -221,13 +221,13 @@ PHPAPI void var_destroy(php_unserialize_data_t *var_hashx)
|
|||||||
BG(serialize_lock)++;
|
BG(serialize_lock)++;
|
||||||
if (call_user_function_ex(CG(function_table), zv, &wakeup_name, &retval, 0, 0, 1, NULL) == FAILURE || Z_ISUNDEF(retval)) {
|
if (call_user_function_ex(CG(function_table), zv, &wakeup_name, &retval, 0, 0, 1, NULL) == FAILURE || Z_ISUNDEF(retval)) {
|
||||||
wakeup_failed = 1;
|
wakeup_failed = 1;
|
||||||
OBJ_FLAGS(Z_OBJ_P(zv)) |= IS_OBJ_DESTRUCTOR_CALLED;
|
GC_ADD_FLAGS(Z_OBJ_P(zv), IS_OBJ_DESTRUCTOR_CALLED);
|
||||||
}
|
}
|
||||||
BG(serialize_lock)--;
|
BG(serialize_lock)--;
|
||||||
|
|
||||||
zval_ptr_dtor(&retval);
|
zval_ptr_dtor(&retval);
|
||||||
} else {
|
} else {
|
||||||
OBJ_FLAGS(Z_OBJ_P(zv)) |= IS_OBJ_DESTRUCTOR_CALLED;
|
GC_ADD_FLAGS(Z_OBJ_P(zv), IS_OBJ_DESTRUCTOR_CALLED);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -607,7 +607,7 @@ static inline int object_common2(UNSERIALIZE_PARAMETER, zend_long elements)
|
|||||||
if (!process_nested_data(UNSERIALIZE_PASSTHRU, ht, elements, 1)) {
|
if (!process_nested_data(UNSERIALIZE_PASSTHRU, ht, elements, 1)) {
|
||||||
if (has_wakeup) {
|
if (has_wakeup) {
|
||||||
ZVAL_DEREF(rval);
|
ZVAL_DEREF(rval);
|
||||||
OBJ_FLAGS(Z_OBJ_P(rval)) |= IS_OBJ_DESTRUCTOR_CALLED;
|
GC_ADD_FLAGS(Z_OBJ_P(rval), IS_OBJ_DESTRUCTOR_CALLED);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user