diff --git a/Zend/zend.c b/Zend/zend.c index 045d25134f8c9..fac88181d4e30 100644 --- a/Zend/zend.c +++ b/Zend/zend.c @@ -119,6 +119,7 @@ static ZEND_INI_MH(OnUpdateErrorReporting) /* {{{ */ } /* }}} */ +#ifndef USE_LIBGC static ZEND_INI_MH(OnUpdateGCEnabled) /* {{{ */ { bool val; @@ -139,7 +140,7 @@ static ZEND_INI_DISP(zend_gc_enabled_displayer_cb) /* {{{ */ } } /* }}} */ - +#endif static ZEND_INI_MH(OnUpdateScriptEncoding) /* {{{ */ { @@ -262,7 +263,9 @@ ZEND_INI_BEGIN() ZEND_INI_ENTRY("error_reporting", NULL, ZEND_INI_ALL, OnUpdateErrorReporting) STD_ZEND_INI_BOOLEAN("fatal_error_backtraces", "1", ZEND_INI_ALL, OnUpdateBool, fatal_error_backtrace_on, zend_executor_globals, executor_globals) STD_ZEND_INI_ENTRY("zend.assertions", "1", ZEND_INI_ALL, OnUpdateAssertions, assertions, zend_executor_globals, executor_globals) +#ifndef USE_LIBGC ZEND_INI_ENTRY3_EX("zend.enable_gc", "1", ZEND_INI_ALL, OnUpdateGCEnabled, NULL, NULL, NULL, zend_gc_enabled_displayer_cb) +#endif STD_ZEND_INI_BOOLEAN("zend.multibyte", "0", ZEND_INI_PERDIR, OnUpdateBool, multibyte, zend_compiler_globals, compiler_globals) ZEND_INI_ENTRY("zend.script_encoding", NULL, ZEND_INI_ALL, OnUpdateScriptEncoding) STD_ZEND_INI_BOOLEAN("zend.detect_unicode", "1", ZEND_INI_ALL, OnUpdateBool, detect_unicode, zend_compiler_globals, compiler_globals) diff --git a/Zend/zend_alloc.h b/Zend/zend_alloc.h index 264e13848d1b7..c416b11690c67 100644 --- a/Zend/zend_alloc.h +++ b/Zend/zend_alloc.h @@ -62,6 +62,147 @@ typedef struct _zend_mm_debug_info { BEGIN_EXTERN_C() +#ifdef USE_LIBGC + +#if ZEND_DEBUG && !defined(GC_DEBUG) +# define GC_DEBUG +#endif +#ifdef GC_H +# error gc/gh.h included before zend_alloc.h +#endif +#include +#include + +typedef struct _zend_mm_heap zend_mm_heap; + +ZEND_API void* ZEND_FASTCALL _emalloc(size_t size ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC); +ZEND_API void ZEND_FASTCALL _efree(void *ptr ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC); +ZEND_API void* ZEND_FASTCALL _safe_emalloc(size_t nmemb, size_t size, size_t offset ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC); +ZEND_API void* ZEND_FASTCALL _ecalloc(size_t nmemb, size_t size ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC); +ZEND_API void* ZEND_FASTCALL _safe_erealloc(void *ptr, size_t nmemb, size_t size, size_t offset ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC); +ZEND_API char *_estrdup(const char *s ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC); +ZEND_API char* _estrndup(const char *s, size_t len ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC); +ZEND_API void* ZEND_FASTCALL _safe_emalloc_atomic(size_t nmemb, size_t size, size_t offset ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC); + +ZEND_API char* ZEND_FASTCALL zend_strndup(const char *s, size_t length); + +ZEND_API zend_result zend_set_memory_limit(size_t memory_limit); +ZEND_API size_t zend_memory_usage(bool real_usage); +ZEND_API size_t zend_memory_peak_usage(bool real_usage); + +ZEND_API size_t zend_mm_gc(zend_mm_heap *heap); + +ZEND_API void shutdown_memory_manager(bool silent, bool full_shutdown); +ZEND_API void init_memory_manager(void); +ZEND_API void start_memory_manager(void); +ZEND_API void prepare_memory_manager(void); + +ZEND_API bool is_zend_ptr(const void *ptr); + +#define is_zend_mm() false +#define zend_memory_reset_peak_usage() do { } while (0) +#define zend_alloc_in_memory_limit_error_reporting() false +#define refresh_memory_manager() do { } while (0) + +#define emalloc(size) GC_MALLOC(size) +#define emalloc_large(size) GC_MALLOC(size) +#define emalloc_huge(size) GC_MALLOC(size) +#define safe_emalloc(nmemb, size, offset) _safe_emalloc(nmemb, size, offset ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC) +#define efree(ptr) ((void)(ptr)) +#define efree_large(ptr) ((void)(ptr)) +#define efree_huge(ptr) ((void)(ptr)) +#define ecalloc(nmemb, size) _ecalloc(nmemb, size ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC) +#define erealloc(ptr, size) GC_REALLOC(ptr, size) +#define erealloc2(ptr, size, copy_size) GC_REALLOC(ptr, size) +#define safe_erealloc(ptr, nmemb, size, offset) _safe_erealloc(ptr, nmemb, size, offset ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC) +#define erealloc_recoverable(ptr, size) GC_REALLOC(ptr, size) +#define erealloc2_recoverable(ptr, size, copy_size) GC_REALLOC(ptr, size) +#define estrdup(s) _estrdup(s ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC) +#define estrndup(s, length) _estrndup(s, length ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC) +#define emalloc_atomic(size) GC_MALLOC_ATOMIC(size) +#define safe_emalloc_atomic(nmemb, size, offset) _safe_emalloc_atomic(nmemb, size, offset ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC) + +#define emalloc_rel(size) emalloc(size) +#define safe_emalloc_rel(nmemb, size, offset) safe_emalloc(nmemb, size, offset) +#define efree_rel(ptr) efree(ptr) +#define ecalloc_rel(nmemb, size) ecalloc(nmemb, size) +#define erealloc_rel(ptr, size) erealloc(ptr, size) +#define erealloc2_rel(ptr, size, copy_size) erealloc2(ptr, size, copy_size) +#define erealloc_recoverable_rel(ptr, size) erealloc_recoverable(ptr, size) +#define erealloc2_recoverable_rel(ptr, size, copy_size) erealloc2_recoverable(ptr, size, copy_size) +#define safe_erealloc_rel(ptr, nmemb, size, offset) safe_erealloc(ptr, nmemb, size, offset) +#define estrdup_rel(s) estrdup(s) +#define estrndup_rel(s, length) estrndup(s, length) + +#define efree_size(ptr, size) +#define efree_size_rel(ptr, size) + +#define pemalloc(size, persistent) emalloc(size) +#define safe_pemalloc(nmemb, size, offset, persistent) safe_emalloc(nmemb, size, offset) +#define pefree(ptr, persistent) efree(ptr) +#define pefree_size(ptr, size, persistent) efree_size(ptr, size) +#define pecalloc(nmemb, size, persistent) ecalloc(nmemb, size) +#define perealloc(ptr, size, persistent) erealloc(ptr, size) +#define perealloc2(ptr, size, copy_size, persistent) erealloc2(ptr, size, copy_size) +#define safe_perealloc(ptr, nmemb, size, offset, persistent) safe_erealloc(ptr, nmemb, size, offset) +#define perealloc_recoverable(ptr, size, persistent) erealloc_recoverable(ptr, size) +#define perealloc2_recoverable(ptr, size, persistent) erealloc2_recoverable(ptr, size) +#define pestrdup(s, persistent) estrdup(s) +#define pestrndup(s, length, persistent) estrndup(s, length) +#define pemalloc_atomic(size, persistent) emalloc_atomic(size) +#define safe_pemalloc_atomic(nmemb, size, offset, persistent) safe_emalloc_atomic(nmemb, size, offset) + +#define pemalloc_rel(size, persistent) pemalloc(size, persistent) +#define pefree_rel(ptr, persistent) pefree(ptr, persistent) +#define pecalloc_rel(nmemb, size, persistent) pecalloc(nmemb, size, persistent) +#define perealloc_rel(ptr, size, persistent) perealloc(ptr, size, persistent) +#define perealloc2_rel(ptr, size, copy_size, persistent) perealloc2(ptr, size, copy_size, persistent) +#define perealloc_recoverable_rel(ptr, size, persistent) perealloc_recoverable(ptr, size, persistent) +#define perealloc2_recoverable_rel(ptr, size, copy_size, persistent) perealloc2_recoverable(ptr, size, copy_size, persistent) +#define pestrdup_rel(s, persistent) pestrdup(s, persistent) + +/* fast cache for HashTables */ +#define ALLOC_HASHTABLE(ht) \ + (ht) = (HashTable *) emalloc(sizeof(HashTable)) + +#define FREE_HASHTABLE(ht) \ + efree_size(ht, sizeof(HashTable)) + +#define ALLOC_HASHTABLE_REL(ht) \ + (ht) = (HashTable *) emalloc_rel(sizeof(HashTable)) + +#define FREE_HASHTABLE_REL(ht) \ + efree_size_rel(ht, sizeof(HashTable)) + +// TODO: should fix call site instead +#define malloc(size) emalloc(size) +#define free(size) efree(size) +#define realloc(ptr, size) erealloc(ptr, size) +#define calloc(nmemb, size) ecalloc(nmemb, size) +#define strdup(s) estrdup(s) +#define strndup(s) estrndup(s) + +/* Hide ptr from libgc */ +#define MASK_PTR(ptr) ((uintptr_t)(ptr) | (1ULL<<63)) +#define UNMASK_PTR(ptr) ((uintptr_t)(ptr) & ~(1ULL<<63)) + +#include "zend_alloc_sizes.h" + +/* _emalloc() & _efree() specialization */ +# if !ZEND_DEBUG +# define _ZEND_BIN_ALLOCATOR_DEF(_num, _size, _elements, _pages, x, y) \ + ZEND_API ZEND_ATTRIBUTE_MALLOC void* ZEND_FASTCALL _emalloc_ ## _size(void); + +ZEND_MM_BINS_INFO(_ZEND_BIN_ALLOCATOR_DEF, x, y) + +# define _ZEND_BIN_DEALLOCATOR_DEF(_num, _size, _elements, _pages, x, y) \ + ZEND_API void ZEND_FASTCALL _efree_ ## _size(void *); + +ZEND_MM_BINS_INFO(_ZEND_BIN_DEALLOCATOR_DEF, x, y) +# endif + +#else /* USE_LIBGC */ + ZEND_API ZEND_ATTRIBUTE_MALLOC char* ZEND_FASTCALL zend_strndup(const char *s, size_t length); ZEND_API ZEND_ATTRIBUTE_MALLOC void* ZEND_FASTCALL _emalloc(size_t size ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC) ZEND_ATTRIBUTE_ALLOC_SIZE(1); @@ -408,6 +549,8 @@ static void apc_init_heap(void) size_t zend_mm_globals_size(void); #endif +#endif /* LIBGC */ + END_EXTERN_C() #endif diff --git a/Zend/zend_alloc_libgc.c b/Zend/zend_alloc_libgc.c new file mode 100644 index 0000000000000..b3177b2f72e36 --- /dev/null +++ b/Zend/zend_alloc_libgc.c @@ -0,0 +1,238 @@ + +#include "zend.h" +#include "zend_multiply.h" +#include "zend_alloc.h" +#include "zend_atomic.h" +#include "zend_globals_macros.h" +#include "zend_globals.h" + +ZEND_API void* ZEND_FASTCALL _emalloc(size_t size ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC) +{ + return GC_MALLOC(size); +} + +ZEND_API void ZEND_FASTCALL _efree(void *ptr ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC) +{ + (void)ptr; +} + +ZEND_API void* ZEND_FASTCALL _safe_emalloc(size_t nmemb, size_t size, size_t offset ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC) +{ + return GC_MALLOC(zend_safe_address_guarded(nmemb, size, offset)); +} + +ZEND_API void* ZEND_FASTCALL _safe_emalloc_atomic(size_t nmemb, size_t size, size_t offset ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC) +{ + return GC_MALLOC_ATOMIC(zend_safe_address_guarded(nmemb, size, offset)); +} + +ZEND_API void* ZEND_FASTCALL _ecalloc(size_t nmemb, size_t size ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC) +{ + return GC_MALLOC(zend_safe_address_guarded(nmemb, size, 0)); +} + +ZEND_API void* ZEND_FASTCALL _safe_erealloc(void *ptr, size_t nmemb, size_t size, size_t offset ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC) +{ + return erealloc(ptr, zend_safe_address_guarded(nmemb, size, offset)); +} + +ZEND_API char *_estrdup(const char *s ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC) +{ + size_t length = strlen(s); + if (UNEXPECTED(length + 1 == 0)) { + zend_error_noreturn(E_ERROR, "Possible integer overflow in memory allocation (1 * %zu + 1)", length); + } + char *p = GC_MALLOC_ATOMIC(length+1); + memcpy(p, s, length+1); + return p; +} + +ZEND_API char* _estrndup(const char *s, size_t length ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC) +{ + if (UNEXPECTED(length + 1 == 0)) { + zend_error_noreturn(E_ERROR, "Possible integer overflow in memory allocation (1 * %zu + 1)", length); + } + char *p = GC_MALLOC_ATOMIC(length+1); + memcpy(p, s, length); + p[length] = 0; + return p; +} + +static ZEND_COLD ZEND_NORETURN void zend_out_of_memory(void) +{ + fprintf(stderr, "Out of memory\n"); + exit(1); +} + +ZEND_API char* ZEND_FASTCALL zend_strndup(const char *s, size_t length) +{ + char *p; + + if (UNEXPECTED(length + 1 == 0)) { + zend_error_noreturn(E_ERROR, "Possible integer overflow in memory allocation (1 * %zu + 1)", length); + } + p = (char *) GC_MALLOC(length + 1); + if (UNEXPECTED(p == NULL)) { + zend_out_of_memory(); + } + if (EXPECTED(length)) { + memcpy(p, s, length); + } + p[length] = 0; + return p; +} + +/* Called once per collection when there are objects to be finalized */ +static void GC_CALLBACK zend_finalizer_notifier_proc(void) +{ + zend_atomic_bool_store_ex(&EG(pending_finalizations), true); + zend_atomic_bool_store_ex(&EG(vm_interrupt), true); +} + +static size_t peak_usage = 0; + +static size_t zend_gc_query_mm_usage(void) +{ + GC_word heap_size; + GC_word free_size; + GC_word unmapped_bytes; + GC_word bytes_since_gc; + GC_word total_bytes; + GC_get_heap_usage_safe(&heap_size, &free_size, &unmapped_bytes, + &bytes_since_gc, &total_bytes); + return heap_size - free_size; +} + +static void GC_CALLBACK zend_gc_on_collection_event_proc(GC_EventType event_type) +{ + if (event_type == GC_EVENT_START) { + peak_usage = MAX(peak_usage, zend_gc_query_mm_usage()); + } +} + +static bool memory_manager_initialized = false; + +ZEND_API void init_memory_manager(void) +{ + const char *tmp = getenv("GC_INCREMENTAL"); + if (tmp && ZEND_ATOL(tmp)) { + GC_enable_incremental(); + } + + /* Queue objects for finalization even if they are reachable from other + * queued objects. + * After queuing, all objects reachable from them are marked + * (considered reachable). + * Objects queued for finalization are reachable via GC_fnlz_roots until the + * finalizer is invoked. */ + GC_set_java_finalization(1); + + GC_set_finalize_on_demand(1); + GC_set_finalizer_notifier(zend_finalizer_notifier_proc); + + ZEND_ASSERT(!GC_is_init_called() && "init_memory_manager() must be called before any allocation"); + GC_set_handle_fork(1); + + ZEND_ASSERT(GC_get_all_interior_pointers()); + + GC_set_on_collection_event(zend_gc_on_collection_event_proc); + + /* Set a lower bound to the minimum bytes allocated since last GC before a + * run is triggered automatically. */ + tmp = getenv("GC_MIN_BYTES_ALLOCD"); + if (tmp) { + GC_set_min_bytes_allocd(ZEND_ATOL(tmp)); + } + + GC_word allocd_bytes_per_finalizer = 0; + tmp = getenv("GC_ALLOC_BYTES_PER_FINALIZER"); + if (tmp) { + allocd_bytes_per_finalizer = ZEND_ATOL(tmp); + } + GC_set_allocd_bytes_per_finalizer(allocd_bytes_per_finalizer); + + memory_manager_initialized = true; +} + +ZEND_API void start_memory_manager(void) +{ + ZEND_ASSERT(memory_manager_initialized && "init_memory_manager() was not called"); +} + +ZEND_API void shutdown_memory_manager(bool silent, bool full_shutdown) +{ + // The best time to force a collection might be just after + // php_request_startup(), as this is when the live set is the smallest. + // GC_gcollect(); + + /* We should have unregistered all finalizers at this point */ + ZEND_ASSERT(!GC_should_invoke_finalizers()); + + peak_usage = 0; +} + +ZEND_API void prepare_memory_manager(void) +{ + /* Run GC when the live set is likely to be the smallest */ + const char *tmp = getenv("GC_AFTER_STARTUP"); + if (tmp && ZEND_ATOL(tmp)) { + GC_gcollect(); + } +} + +ZEND_API zend_result zend_set_memory_limit(size_t memory_limit) +{ + return SUCCESS; +} + +ZEND_API size_t zend_memory_usage(bool real_usage) +{ + GC_alloc_lock(); + size_t usage = zend_gc_query_mm_usage(); + GC_alloc_unlock(); + + return usage; +} + +ZEND_API size_t zend_memory_peak_usage(bool real_usage) +{ + GC_alloc_lock(); + peak_usage = MAX(peak_usage, zend_gc_query_mm_usage()); + GC_alloc_unlock(); + + return peak_usage; +} + +ZEND_API size_t zend_mm_gc(zend_mm_heap *heap) +{ + GC_gcollect_and_unmap(); + return 0; +} + +ZEND_API bool is_zend_ptr(const void *ptr) +{ + return false; +} + +#if ZEND_DEBUG +void zend_mm_print_backtrace(void *ptr) +{ + GC_print_backtrace(ptr); +} +#endif + +#if !ZEND_DEBUG +# define _ZEND_BIN_ALLOCATOR(_num, _size, _elements, _pages, _min_size, y) \ + ZEND_API void* ZEND_FASTCALL _emalloc_ ## _size(void) { \ + return GC_MALLOC(_size); \ + } + +ZEND_MM_BINS_INFO(_ZEND_BIN_ALLOCATOR, ZEND_MM_MIN_USEABLE_BIN_SIZE, y) + +# define _ZEND_BIN_FREE(_num, _size, _elements, _pages, _min_size, y) \ + ZEND_API void ZEND_FASTCALL _efree_ ## _size(void *ptr) { \ + GC_FREE(ptr); \ + } + +ZEND_MM_BINS_INFO(_ZEND_BIN_FREE, ZEND_MM_MIN_USEABLE_BIN_SIZE, y) +#endif diff --git a/Zend/zend_builtin_functions.c b/Zend/zend_builtin_functions.c index b25925b89f7f9..113f50355bcd8 100644 --- a/Zend/zend_builtin_functions.c +++ b/Zend/zend_builtin_functions.c @@ -157,7 +157,11 @@ ZEND_FUNCTION(gc_mem_caches) { ZEND_PARSE_PARAMETERS_NONE(); +#if USE_LIBGC + RETURN_LONG(zend_mm_gc(NULL)); +#else RETURN_LONG(zend_mm_gc(zend_mm_get_heap())); +#endif } /* }}} */ @@ -167,7 +171,13 @@ ZEND_FUNCTION(gc_collect_cycles) { ZEND_PARSE_PARAMETERS_NONE(); +#if USE_LIBGC + GC_gcollect(); + GC_invoke_finalizers(); + RETURN_LONG(0); +#else RETURN_LONG(gc_collect_cycles()); +#endif } /* }}} */ diff --git a/Zend/zend_closures.c b/Zend/zend_closures.c index 22fd30463726f..9f92f583e2a73 100644 --- a/Zend/zend_closures.c +++ b/Zend/zend_closures.c @@ -168,7 +168,7 @@ ZEND_METHOD(Closure, call) zend_call_function(&fci, &fci_cache); /* copied upon generator creation */ - GC_DELREF(&closure->std); + GC_DELREF_OBJ(&closure->std); } else { zend_closure *fake_closure; zend_function *my_function; diff --git a/Zend/zend_exceptions.c b/Zend/zend_exceptions.c index 0b0945aac0f44..5752fd8b533b5 100644 --- a/Zend/zend_exceptions.c +++ b/Zend/zend_exceptions.c @@ -24,6 +24,7 @@ #include "zend_builtin_functions.h" #include "zend_interfaces.h" #include "zend_exceptions.h" +#include "zend_types.h" #include "zend_vm.h" #include "zend_dtrace.h" #include "zend_smart_str.h" @@ -350,7 +351,7 @@ ZEND_API zend_result zend_update_exception_properties(INTERNAL_FUNCTION_PARAMETE } if (previous) { - Z_ADDREF_P(previous); + GC_ADDREF_OBJ(Z_OBJ_P(previous)); zend_update_property_num_checked(zend_ce_exception, Z_OBJ_P(object), ZEND_EXCEPTION_PREVIOUS_OFF, ZSTR_KNOWN(ZEND_STR_PREVIOUS), previous); if (UNEXPECTED(EG(exception))) { return FAILURE; diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c index 1bd79e5283046..56023b9ebe90a 100644 --- a/Zend/zend_execute.c +++ b/Zend/zend_execute.c @@ -1641,7 +1641,7 @@ static zend_never_inline void zend_binary_assign_op_obj_dim(zend_object *obj, zv zval *z; zval rv, res; - GC_ADDREF(obj); + GC_ADDREF_OBJ(obj); if (property && UNEXPECTED(Z_ISUNDEF_P(property))) { property = ZVAL_UNDEFINED_OP2(); } @@ -1665,7 +1665,7 @@ static zend_never_inline void zend_binary_assign_op_obj_dim(zend_object *obj, zv } } FREE_OP((opline+1)->op1_type, (opline+1)->op1.var); - if (UNEXPECTED(GC_DELREF(obj) == 0)) { + if (UNEXPECTED(GC_DELREF_OBJ(obj) == 0)) { zend_objects_store_del(obj); } } @@ -2346,7 +2346,7 @@ static zend_never_inline void zend_post_incdec_overloaded_property(zend_object * zval *z; zval z_copy; - GC_ADDREF(object); + GC_ADDREF_OBJ(object); z =object->handlers->read_property(object, name, BP_VAR_R, cache_slot, &rv); if (UNEXPECTED(EG(exception))) { OBJ_RELEASE(object); @@ -2375,7 +2375,7 @@ static zend_never_inline void zend_pre_incdec_overloaded_property(zend_object *o zval *z; zval z_copy; - GC_ADDREF(object); + GC_ADDREF_OBJ(object); z = object->handlers->read_property(object, name, BP_VAR_R, cache_slot, &rv); if (UNEXPECTED(EG(exception))) { OBJ_RELEASE(object); @@ -2407,7 +2407,7 @@ static zend_never_inline void zend_assign_op_overloaded_property(zend_object *ob zval *z; zval rv, res; - GC_ADDREF(object); + GC_ADDREF_OBJ(object); z = object->handlers->read_property(object, name, BP_VAR_R, cache_slot, &rv); if (UNEXPECTED(EG(exception))) { OBJ_RELEASE(object); @@ -2939,7 +2939,7 @@ static zend_always_inline void zend_fetch_dimension_address(zval *result, zval * ZVAL_UNDEF(result); } else if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { zend_object *obj = Z_OBJ_P(container); - GC_ADDREF(obj); + GC_ADDREF_OBJ(obj); if (ZEND_CONST_COND(dim_type == IS_CV, dim != NULL) && UNEXPECTED(Z_TYPE_P(dim) == IS_UNDEF)) { dim = ZVAL_UNDEFINED_OP2(); } else if (dim_type == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { @@ -2972,7 +2972,7 @@ static zend_always_inline void zend_fetch_dimension_address(zval *result, zval * ZEND_ASSERT(EG(exception) && "read_dimension() returned NULL without exception"); ZVAL_UNDEF(result); } - if (UNEXPECTED(GC_DELREF(obj) == 0)) { + if (UNEXPECTED(GC_DELREF_OBJ(obj) == 0)) { zend_objects_store_del(obj); } } else { @@ -3144,7 +3144,7 @@ static zend_always_inline void zend_fetch_dimension_address_read(zval *result, z } else if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { zend_object *obj = Z_OBJ_P(container); - GC_ADDREF(obj); + GC_ADDREF_OBJ(obj); if (ZEND_CONST_COND(dim_type == IS_CV, 1) && UNEXPECTED(Z_TYPE_P(dim) == IS_UNDEF)) { dim = ZVAL_UNDEFINED_OP2(); } @@ -3163,7 +3163,7 @@ static zend_always_inline void zend_fetch_dimension_address_read(zval *result, z } else { ZVAL_NULL(result); } - if (UNEXPECTED(GC_DELREF(obj) == 0)) { + if (UNEXPECTED(GC_DELREF_OBJ(obj) == 0)) { zend_objects_store_del(obj); } } else { @@ -5129,7 +5129,7 @@ static zend_never_inline zend_execute_data *zend_init_dynamic_call_object(zend_o call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_DYNAMIC; if (object) { call_info |= ZEND_CALL_RELEASE_THIS | ZEND_CALL_HAS_THIS; - GC_ADDREF(object); /* For $this pointer */ + GC_ADDREF_OBJ(object); /* For $this pointer */ object_or_called_scope = object; } } @@ -5218,7 +5218,7 @@ static zend_never_inline zend_execute_data *zend_init_dynamic_call_array(zend_ar object_or_called_scope = object->ce; } else { call_info |= ZEND_CALL_RELEASE_THIS | ZEND_CALL_HAS_THIS; - GC_ADDREF(object); /* For $this pointer */ + GC_ADDREF_OBJ(object); /* For $this pointer */ object_or_called_scope = object; } } diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index 06618b3a9ded2..085c5008d5247 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -212,7 +212,7 @@ static int zval_call_destructor(zval *zv) /* {{{ */ if (Z_TYPE_P(zv) == IS_INDIRECT) { zv = Z_INDIRECT_P(zv); } - if (Z_TYPE_P(zv) == IS_OBJECT && Z_REFCOUNT_P(zv) == 1) { + if (Z_TYPE_P(zv) == IS_OBJECT) { return ZEND_HASH_APPLY_REMOVE; } else { return ZEND_HASH_APPLY_KEEP; @@ -264,6 +264,9 @@ void shutdown_destructors(void) /* {{{ */ /* if we couldn't destruct cleanly, mark all objects as destructed anyway */ zend_objects_store_mark_destructed(&EG(objects_store)); } zend_end_try(); + + GC_invoke_finalizers(); + ZEND_ASSERT(!GC_should_invoke_finalizers()); } /* }}} */ @@ -484,6 +487,9 @@ void shutdown_executor(void) /* {{{ */ } destroy_op_array(&func->op_array); zend_string_release_ex(key, 0); +#ifdef USE_LIBGC + Z_PTR_P(zv) = NULL; +#endif } ZEND_HASH_MAP_FOREACH_END_DEL(); ZEND_HASH_MAP_REVERSE_FOREACH_STR_KEY_VAL(EG(class_table), key, zv) { @@ -492,6 +498,9 @@ void shutdown_executor(void) /* {{{ */ } destroy_zend_class(zv); zend_string_release_ex(key, 0); +#ifdef USE_LIBGC + Z_PTR_P(zv) = NULL; +#endif } ZEND_HASH_MAP_FOREACH_END_DEL(); } @@ -499,6 +508,7 @@ void shutdown_executor(void) /* {{{ */ EG(symtable_cache_ptr)--; zend_hash_destroy(*EG(symtable_cache_ptr)); FREE_HASHTABLE(*EG(symtable_cache_ptr)); + *EG(symtable_cache_ptr) = NULL; } zend_hash_destroy(&EG(included_files)); diff --git a/Zend/zend_gc.c b/Zend/zend_gc.c index e15f97ecfe802..05370b9496c4d 100644 --- a/Zend/zend_gc.c +++ b/Zend/zend_gc.c @@ -1891,10 +1891,10 @@ static zend_always_inline zend_result gc_call_destructors(uint32_t idx, uint32_t zend_object *obj = (zend_object*)p; GC_TRACE_REF(obj, "calling destructor"); GC_ADD_FLAGS(obj, IS_OBJ_DESTRUCTOR_CALLED); - GC_ADDREF(obj); + GC_ADDREF_OBJ(obj); obj->handlers->dtor_obj(obj); GC_TRACE_REF(obj, "returned from destructor"); - GC_DELREF(obj); + GC_DELREF_OBJ(obj); if (UNEXPECTED(fiber != NULL && GC_G(dtor_fiber) != fiber)) { /* We resumed after suspension */ gc_check_possible_root((zend_refcounted*)&obj->gc); @@ -2107,9 +2107,9 @@ ZEND_API int zend_gc_collect_cycles(void) current->ref = GC_MAKE_GARBAGE(((char*)obj) - obj->handlers->offset); if (!(OBJ_FLAGS(obj) & IS_OBJ_FREE_CALLED)) { GC_ADD_FLAGS(obj, IS_OBJ_FREE_CALLED); - GC_ADDREF(obj); + GC_ADDREF_OBJ(obj); obj->handlers->free_obj(obj); - GC_DELREF(obj); + GC_DELREF_OBJ(obj); } ZEND_OBJECTS_STORE_ADD_TO_FREE_LIST(obj->handle); @@ -2325,7 +2325,7 @@ static ZEND_FUNCTION(gc_destructor_fiber) if (GC_G(dtor_fiber) == fiber) { GC_G(dtor_fiber) = NULL; } - GC_DELREF(&fiber->std); + GC_DELREF_OBJ(&fiber->std); gc_check_possible_root((zend_refcounted*)&fiber->std.gc); return; } diff --git a/Zend/zend_gc.h b/Zend/zend_gc.h index 06f550647bd79..79fa2eb020dcd 100644 --- a/Zend/zend_gc.h +++ b/Zend/zend_gc.h @@ -87,6 +87,7 @@ size_t zend_gc_globals_size(void); static zend_always_inline void gc_check_possible_root(zend_refcounted *ref) { +#ifndef USE_LIBGC if (EXPECTED(GC_TYPE_INFO(ref) == GC_REFERENCE)) { zval *zv = &((zend_reference*)ref)->val; @@ -98,14 +99,17 @@ static zend_always_inline void gc_check_possible_root(zend_refcounted *ref) if (UNEXPECTED(GC_MAY_LEAK(ref))) { gc_possible_root(ref); } +#endif } static zend_always_inline void gc_check_possible_root_no_ref(zend_refcounted *ref) { ZEND_ASSERT(GC_TYPE_INFO(ref) != GC_REFERENCE); +#ifndef USE_LIBGC if (UNEXPECTED(GC_MAY_LEAK(ref))) { gc_possible_root(ref); } +#endif } /* These APIs can be used to simplify object get_gc implementations diff --git a/Zend/zend_globals.h b/Zend/zend_globals.h index 48b978b535014..5e06dba120fbf 100644 --- a/Zend/zend_globals.h +++ b/Zend/zend_globals.h @@ -219,6 +219,7 @@ struct _zend_executor_globals { zend_atomic_bool vm_interrupt; zend_atomic_bool timed_out; + zend_atomic_bool pending_finalizations; HashTable *in_autoload; diff --git a/Zend/zend_hash.c b/Zend/zend_hash.c index d460c40b79714..220e40289fcf7 100644 --- a/Zend/zend_hash.c +++ b/Zend/zend_hash.c @@ -445,6 +445,9 @@ ZEND_API void ZEND_FASTCALL zend_hash_discard(HashTable *ht, uint32_t nNumUsed) p--; if (UNEXPECTED(Z_TYPE(p->val) == IS_UNDEF)) continue; ht->nNumOfElements--; +#ifdef USE_LIBGC + ZVAL_UNDEF(&p->val); +#endif /* Collision pointers always directed from higher to lower buckets */ #if 0 if (!(Z_NEXT(p->val) == HT_INVALID_IDX || HT_HASH_TO_BUCKET_EX(arData, Z_NEXT(p->val)) < p)) { diff --git a/Zend/zend_iterators.c b/Zend/zend_iterators.c index 64dbb0541a80d..e9a8a05be718d 100644 --- a/Zend/zend_iterators.c +++ b/Zend/zend_iterators.c @@ -89,7 +89,7 @@ ZEND_API void zend_iterator_init(zend_object_iterator *iter) ZEND_API void zend_iterator_dtor(zend_object_iterator *iter) { - if (GC_DELREF(&iter->std) > 0) { + if (GC_DELREF_OBJ(&iter->std) > 0) { return; } diff --git a/Zend/zend_language_parser.y b/Zend/zend_language_parser.y index e4d61006fe12f..4b24973e8e6b4 100644 --- a/Zend/zend_language_parser.y +++ b/Zend/zend_language_parser.y @@ -27,15 +27,14 @@ #include "zend_constants.h" #include "zend_language_scanner.h" #include "zend_exceptions.h" +#include "zend_alloc.h" #define YYSIZE_T size_t #define yytnamerr zend_yytnamerr static YYSIZE_T zend_yytnamerr(char*, const char*); -#ifdef _MSC_VER -#define YYMALLOC malloc -#define YYFREE free -#endif +#define YYMALLOC(size) emalloc(size) +#define YYFREE(ptr) free(ptr) } %code requires { diff --git a/Zend/zend_lazy_objects.c b/Zend/zend_lazy_objects.c index cf00804eda33b..f447857ee12f0 100644 --- a/Zend/zend_lazy_objects.c +++ b/Zend/zend_lazy_objects.c @@ -66,6 +66,7 @@ typedef struct _zend_lazy_object_info { int lazy_properties_count; } zend_lazy_object_info; +#ifndef USE_LIBGC /* zend_hash dtor_func_t for zend_lazy_objects_store.infos */ static void zend_lazy_object_info_dtor_func(zval *pElement) { @@ -81,25 +82,80 @@ static void zend_lazy_object_info_dtor_func(zval *pElement) efree(info); } +#endif void zend_lazy_objects_init(zend_lazy_objects_store *store) { +#ifdef USE_LIBGC + zend_hash_init(&store->infos, 8, NULL, NULL, false); +#else zend_hash_init(&store->infos, 8, NULL, zend_lazy_object_info_dtor_func, false); +#endif } void zend_lazy_objects_destroy(zend_lazy_objects_store *store) { +#ifdef USE_LIBGC + ZEND_HASH_FOREACH_VAL(&store->infos, zval *zv) { + if (Z_PTR_P(zv)) { + if (GC_unregister_long_link(&Z_PTR_P(zv)) != 1) { + ZEND_UNREACHABLE(); + } + } + } ZEND_HASH_FOREACH_END(); +#else ZEND_ASSERT(zend_hash_num_elements(&store->infos) == 0 || CG(unclean_shutdown)); zend_hash_destroy(&store->infos); +#endif +} + +static void zlo_move_links(Bucket *prev_buckets) +{ + if (HT_IS_PACKED(&EG(lazy_objects_store).infos)) { + zval *zvs = EG(lazy_objects_store).infos.arPacked; + zval *prev_zvs = (zval*)prev_buckets; + for (uint32_t i = 0, l = EG(lazy_objects_store).infos.nNumUsed - 1; i < l; i++) { + if (!Z_ISUNDEF(zvs[i])) { + if (GC_move_long_link(&Z_PTR(prev_zvs[i]), &Z_PTR(zvs[i])) != GC_SUCCESS) { + ZEND_UNREACHABLE(); + } + } + } + } else { + Bucket *buckets = EG(lazy_objects_store).infos.arData; + for (uint32_t i = 0, l = EG(lazy_objects_store).infos.nNumUsed - 1; i < l; i++) { + if (!Z_ISUNDEF(buckets[i].val)) { + if (GC_move_long_link(&Z_PTR(prev_buckets[i].val), &Z_PTR(buckets[i].val)) != GC_SUCCESS) { + ZEND_UNREACHABLE(); + } + } + } + } } static void zend_lazy_object_set_info(const zend_object *obj, zend_lazy_object_info *info) { ZEND_ASSERT(zend_object_is_lazy(obj)); +#ifdef USE_LIBGC + Bucket *prev_buckets = EG(lazy_objects_store).infos.arData; + zval *zv = zend_hash_index_lookup(&EG(lazy_objects_store).infos, obj->handle); + ZEND_ASSERT(Z_TYPE_P(zv) == IS_NULL || (Z_TYPE_P(zv) == IS_PTR && Z_PTR_P(zv) == NULL)); + ZVAL_PTR(zv, info); + + if (UNEXPECTED(EG(lazy_objects_store).infos.arData != prev_buckets)) { + zlo_move_links(prev_buckets); + } + + if (GC_REGISTER_LONG_LINK_SAFE(&Z_PTR_P(zv), + GC_base((char*)obj - obj->handlers->offset)) != GC_SUCCESS) { + ZEND_UNREACHABLE(); + } +#else zval *zv = zend_hash_index_add_new_ptr(&EG(lazy_objects_store).infos, obj->handle, info); ZEND_ASSERT(zv); (void)zv; +#endif } static zend_lazy_object_info* zend_lazy_object_get_info(const zend_object *obj) @@ -161,8 +217,17 @@ zend_lazy_object_flags_t zend_lazy_object_get_flags(const zend_object *obj) void zend_lazy_object_del_info(const zend_object *obj) { +#ifdef USE_LIBGC + zval *zv = zend_hash_index_find(&EG(lazy_objects_store).infos, obj->handle); + ZEND_ASSERT(zv && Z_TYPE_P(zv) == IS_PTR && Z_PTR_P(zv) != NULL); + Z_PTR_P(zv) = NULL; + if (GC_unregister_long_link(&Z_PTR_P(zv)) != 1) { + ZEND_UNREACHABLE(); + } +#else zend_result res = zend_hash_index_del(&EG(lazy_objects_store).infos, obj->handle); ZEND_ASSERT(res == SUCCESS); +#endif } bool zend_lazy_object_decr_lazy_props(const zend_object *obj) @@ -301,9 +366,9 @@ ZEND_API zend_object *zend_object_make_lazy(zend_object *obj, if (obj->handlers->dtor_obj != zend_objects_destroy_object || obj->ce->destructor) { GC_ADD_FLAGS(obj, IS_OBJ_DESTRUCTOR_CALLED); - GC_ADDREF(obj); + GC_ADDREF_OBJ(obj); obj->handlers->dtor_obj(obj); - GC_DELREF(obj); + GC_DELREF_OBJ(obj); if (EG(exception)) { return NULL; } @@ -472,7 +537,7 @@ static zend_object *zend_lazy_object_init_proxy(zend_object *obj) ZEND_ASSERT(!zend_lazy_object_initialized(obj)); /* Prevent object from being released during initialization */ - GC_ADDREF(obj); + GC_ADDREF_OBJ(obj); zend_lazy_object_info *info = zend_lazy_object_get_info(obj); @@ -545,7 +610,7 @@ static zend_object *zend_lazy_object_init_proxy(zend_object *obj) instance = Z_OBJ(retval); exit: - if (UNEXPECTED(GC_DELREF(obj) == 0)) { + if (UNEXPECTED(GC_DELREF_OBJ(obj) == 0)) { zend_throw_error(NULL, "Lazy object was released during initialization"); zend_objects_store_del(obj); instance = NULL; @@ -586,7 +651,7 @@ ZEND_API zend_object *zend_lazy_object_init(zend_object *obj) } /* Prevent object from being released during initialization */ - GC_ADDREF(obj); + GC_ADDREF_OBJ(obj); zend_fcall_info_cache *initializer = zend_lazy_object_get_initializer_fcc(obj); @@ -661,7 +726,7 @@ ZEND_API zend_object *zend_lazy_object_init(zend_object *obj) instance = obj; exit: - if (UNEXPECTED(GC_DELREF(obj) == 0)) { + if (UNEXPECTED(GC_DELREF_OBJ(obj) == 0)) { zend_throw_error(NULL, "Lazy object was released during initialization"); zend_objects_store_del(obj); instance = NULL; diff --git a/Zend/zend_object_handlers.c b/Zend/zend_object_handlers.c index cca69e5d792c9..ad943a4bb1b56 100644 --- a/Zend/zend_object_handlers.c +++ b/Zend/zend_object_handlers.c @@ -330,10 +330,10 @@ static ZEND_COLD zend_never_inline void zend_forbidden_dynamic_property( static ZEND_COLD zend_never_inline bool zend_deprecated_dynamic_property( zend_object *obj, const zend_string *member) { - GC_ADDREF(obj); + GC_ADDREF_OBJ(obj); zend_error(E_DEPRECATED, "Creation of dynamic property %s::$%s is deprecated", ZSTR_VAL(obj->ce->name), ZSTR_VAL(member)); - if (UNEXPECTED(GC_DELREF(obj) == 0)) { + if (UNEXPECTED(GC_DELREF_OBJ(obj) == 0)) { zend_class_entry *ce = obj->ce; zend_objects_store_del(obj); if (!EG(exception)) { @@ -1079,9 +1079,9 @@ ZEND_API zval *zend_std_write_property(zend_object *zobj, zend_string *name, zva typed_property: ZVAL_COPY_VALUE(&tmp, value); // Increase refcount to prevent object from being released in __toString() - GC_ADDREF(zobj); + GC_ADDREF_OBJ(zobj); bool type_matched = zend_verify_property_type(prop_info, &tmp, property_uses_strict_types()); - if (UNEXPECTED(GC_DELREF(zobj) == 0)) { + if (UNEXPECTED(GC_DELREF_OBJ(zobj) == 0)) { zend_object_released_while_assigning_to_property_error(prop_info); zend_objects_store_del(zobj); zval_ptr_dtor(&tmp); @@ -1290,7 +1290,7 @@ ZEND_API zval *zend_std_read_dimension(zend_object *object, zval *offset, int ty ZVAL_COPY_DEREF(&tmp_offset, offset); } - GC_ADDREF(object); + GC_ADDREF_OBJ(object); if (type == BP_VAR_IS) { zend_call_known_instance_method_with_1_params(funcs->zf_offsetexists, object, rv, &tmp_offset); if (UNEXPECTED(Z_ISUNDEF_P(rv))) { @@ -1338,7 +1338,7 @@ ZEND_API void zend_std_write_dimension(zend_object *object, zval *offset, zval * } else { ZVAL_COPY_DEREF(&tmp_offset, offset); } - GC_ADDREF(object); + GC_ADDREF_OBJ(object); zend_call_known_instance_method_with_2_params(funcs->zf_offsetset, object, NULL, &tmp_offset, value); OBJ_RELEASE(object); zval_ptr_dtor(&tmp_offset); @@ -1358,7 +1358,7 @@ ZEND_API int zend_std_has_dimension(zend_object *object, zval *offset, int check zend_class_arrayaccess_funcs *funcs = ce->arrayaccess_funcs_ptr; if (EXPECTED(funcs)) { ZVAL_COPY_DEREF(&tmp_offset, offset); - GC_ADDREF(object); + GC_ADDREF_OBJ(object); zend_call_known_instance_method_with_1_params(funcs->zf_offsetexists, object, &retval, &tmp_offset); result = i_zend_is_true(&retval); zval_ptr_dtor(&retval); @@ -1611,7 +1611,7 @@ ZEND_API void zend_std_unset_dimension(zend_object *object, zval *offset) /* {{{ zend_class_arrayaccess_funcs *funcs = ce->arrayaccess_funcs_ptr; if (EXPECTED(funcs)) { ZVAL_COPY_DEREF(&tmp_offset, offset); - GC_ADDREF(object); + GC_ADDREF_OBJ(object); zend_call_known_instance_method_with_1_params(funcs->zf_offsetunset, object, NULL, &tmp_offset); OBJ_RELEASE(object); zval_ptr_dtor(&tmp_offset); diff --git a/Zend/zend_objects.c b/Zend/zend_objects.c index 4b4187f423859..80135cfeaf63c 100644 --- a/Zend/zend_objects.c +++ b/Zend/zend_objects.c @@ -20,6 +20,7 @@ #include "zend.h" #include "zend_globals.h" +#include "zend_types.h" #include "zend_variables.h" #include "zend_API.h" #include "zend_interfaces.h" @@ -145,7 +146,7 @@ ZEND_API void zend_objects_destroy_object(zend_object *object) } } - GC_ADDREF(object); + GC_ADDREF_OBJ(object); /* Make sure that destructors are protected from previously thrown exceptions. * For example, if an exception was thrown in a function and when the function's diff --git a/Zend/zend_objects_API.c b/Zend/zend_objects_API.c index c19873cf3be30..b25eadfa446f1 100644 --- a/Zend/zend_objects_API.c +++ b/Zend/zend_objects_API.c @@ -20,11 +20,26 @@ #include "zend.h" #include "zend_globals.h" +#include "zend_objects.h" +#include "zend_portability.h" #include "zend_variables.h" #include "zend_API.h" #include "zend_objects_API.h" #include "zend_fibers.h" +#ifdef USE_LIBGC +# define USE_FINALIZERS 1 +# define ALL_FINALIZERS 1 +# define USE_LONG_LINKS 1 + +# if USE_FINALIZERS +static void zend_object_dtor_finalizer(void *ptr, void *data); +static void zend_object_free_finalizer(void *ptr, void *data); +# endif +#endif + +static void ZEND_FASTCALL zend_objects_store_del_ex(zend_object *object, bool from_finalizer); + ZEND_API void ZEND_FASTCALL zend_objects_store_init(zend_objects_store *objects, uint32_t init_size) { objects->object_buckets = (zend_object **) emalloc(init_size * sizeof(zend_object*)); @@ -40,22 +55,75 @@ ZEND_API void ZEND_FASTCALL zend_objects_store_destroy(zend_objects_store *objec objects->object_buckets = NULL; } +#ifdef USE_LIBGC +void ZEND_FASTCALL zend_objects_store_set_weakref_finalizer(zend_object *object) +{ +# if USE_FINALIZERS + if ((object->handlers->dtor_obj != zend_objects_destroy_object + || object->ce->destructor) + && !(OBJ_FLAGS(object) & IS_OBJ_DESTRUCTOR_CALLED) + ) { + /* Do nothing: object already has a finalizer */ +# if ZEND_DEBUG + /* Check that object already has a finalizer */ + GC_finalization_proc ofn; + GC_REGISTER_FINALIZER_NO_ORDER((char*)object - object->handlers->offset, + zend_object_dtor_finalizer, (void*)GC_HIDE_POINTER(object), &ofn, NULL); + ZEND_ASSERT(ofn == zend_object_dtor_finalizer); +# endif + } else if (ALL_FINALIZERS + || object->handlers->free_obj != zend_object_std_dtor) { + /* Do nothing: object already has a finalizer */ +# if ZEND_DEBUG + /* Check that object already has a finalizer */ + GC_finalization_proc ofn; + GC_REGISTER_FINALIZER_NO_ORDER((char*)object - object->handlers->offset, + zend_object_free_finalizer, (void*)GC_HIDE_POINTER(object), &ofn, NULL); + ZEND_ASSERT(ofn == zend_object_dtor_finalizer); +# endif + } else { + GC_REGISTER_FINALIZER_NO_ORDER((char*)object - object->handlers->offset, + zend_object_free_finalizer, (void*)GC_HIDE_POINTER(object), NULL, NULL); + zend_object *placeholder = EG(objects_store).object_buckets[object->handle]; + if (IS_OBJ_PLACEHOLDER(placeholder)) { + EG(objects_store).object_buckets[object->handle] = (zend_object*)MASK_PTR(object); + } + } +# endif +} +#endif + ZEND_API void ZEND_FASTCALL zend_objects_store_call_destructors(zend_objects_store *objects) { EG(flags) |= EG_FLAGS_OBJECT_STORE_NO_REUSE; if (objects->top > 1) { uint32_t i; for (i = 1; i < objects->top; i++) { - zend_object *obj = objects->object_buckets[i]; + zend_object *obj = (zend_object*)UNMASK_PTR(objects->object_buckets[i]); if (IS_OBJ_VALID(obj)) { +#ifdef USE_LIBGC +# if USE_FINALIZERS + GC_finalization_proc finalizer; + if (ALL_FINALIZERS + || obj->handlers->free_obj != zend_object_std_dtor + || (OBJ_FLAGS(obj) & IS_OBJ_WEAKLY_REFERENCED)) { + finalizer = zend_object_free_finalizer; + } else { + finalizer = NULL; /* unregister */ + } + GC_REGISTER_FINALIZER_NO_ORDER((char*)obj - obj->handlers->offset, + finalizer, (void*)GC_HIDE_POINTER(obj), NULL, NULL); +# endif +#endif + if (!(OBJ_FLAGS(obj) & IS_OBJ_DESTRUCTOR_CALLED)) { GC_ADD_FLAGS(obj, IS_OBJ_DESTRUCTOR_CALLED); if (obj->handlers->dtor_obj != zend_objects_destroy_object || obj->ce->destructor) { - GC_ADDREF(obj); + GC_ADDREF_OBJ(obj); obj->handlers->dtor_obj(obj); - GC_DELREF(obj); + GC_DELREF_OBJ(obj); } } } @@ -70,10 +138,24 @@ ZEND_API void ZEND_FASTCALL zend_objects_store_mark_destructed(zend_objects_stor zend_object **end = objects->object_buckets + objects->top; do { - zend_object *obj = *obj_ptr; + zend_object *obj = (zend_object*)UNMASK_PTR(*obj_ptr); if (IS_OBJ_VALID(obj)) { GC_ADD_FLAGS(obj, IS_OBJ_DESTRUCTOR_CALLED); +#ifdef USE_LIBGC +# if USE_FINALIZERS + GC_finalization_proc finalizer = NULL; + if (ALL_FINALIZERS + || obj->handlers->free_obj != zend_object_std_dtor + || (OBJ_FLAGS(obj) & IS_OBJ_WEAKLY_REFERENCED)) { + finalizer = zend_object_free_finalizer; + } else { + finalizer = NULL; /* unregister */ + } + GC_REGISTER_FINALIZER_NO_ORDER((char*)obj - obj->handlers->offset, + finalizer, (void*)GC_HIDE_POINTER(obj), NULL, NULL); +# endif +#endif } obj_ptr++; } while (obj_ptr != end); @@ -96,15 +178,21 @@ ZEND_API void ZEND_FASTCALL zend_objects_store_free_object_storage(zend_objects_ if (fast_shutdown) { do { obj_ptr--; - obj = *obj_ptr; + obj = (zend_object*)UNMASK_PTR(*obj_ptr); if (IS_OBJ_VALID(obj)) { if (!(OBJ_FLAGS(obj) & IS_OBJ_FREE_CALLED)) { GC_ADD_FLAGS(obj, IS_OBJ_FREE_CALLED); if (obj->handlers->free_obj != zend_object_std_dtor || (OBJ_FLAGS(obj) & IS_OBJ_WEAKLY_REFERENCED) ) { - GC_ADDREF(obj); + GC_ADDREF_OBJ(obj); obj->handlers->free_obj(obj); +#ifdef USE_LIBGC +# if USE_FINALIZERS + GC_REGISTER_FINALIZER_NO_ORDER((char*)obj - obj->handlers->offset, + NULL /* Unregister finalizer */, NULL, NULL, NULL); +# endif +#endif } } } @@ -112,12 +200,18 @@ ZEND_API void ZEND_FASTCALL zend_objects_store_free_object_storage(zend_objects_ } else { do { obj_ptr--; - obj = *obj_ptr; + obj = (zend_object*)UNMASK_PTR(*obj_ptr); if (IS_OBJ_VALID(obj)) { if (!(OBJ_FLAGS(obj) & IS_OBJ_FREE_CALLED)) { GC_ADD_FLAGS(obj, IS_OBJ_FREE_CALLED); - GC_ADDREF(obj); + GC_ADDREF_OBJ(obj); obj->handlers->free_obj(obj); +#ifdef USE_LIBGC +# if USE_FINALIZERS + GC_REGISTER_FINALIZER_NO_ORDER((char*)obj - obj->handlers->offset, + NULL /* Unregister finalizer */, NULL, NULL, NULL); +# endif +#endif } } } while (obj_ptr != end); @@ -126,22 +220,127 @@ ZEND_API void ZEND_FASTCALL zend_objects_store_free_object_storage(zend_objects_ /* Store objects API */ -static ZEND_COLD zend_never_inline void ZEND_FASTCALL zend_objects_store_put_cold(zend_object *object) +static ZEND_COLD zend_never_inline void ZEND_FASTCALL zend_objects_store_put_cold(zend_object *object, void *bucket_value) { int handle; uint32_t new_size = 2 * EG(objects_store).size; +#ifdef USE_LIBGC +# if USE_LONG_LINKS + uint32_t free_list_head = -1; + + if (!(EG(flags) & EG_FLAGS_OBJECT_STORE_NO_REUSE)) { + ZEND_ASSERT(EG(objects_store).free_list_head == -1); + for (uint32_t i = 1, l = EG(objects_store).size; i < l; i++) { + if (EG(objects_store).object_buckets[i] == NULL) { + SET_OBJ_BUCKET_NUMBER(EG(objects_store).object_buckets[i], free_list_head); + free_list_head = i; + } + } + EG(objects_store).free_list_head = free_list_head; + } - EG(objects_store).object_buckets = (zend_object **) erealloc(EG(objects_store).object_buckets, new_size * sizeof(zend_object*)); - /* Assign size after realloc, in case it fails */ - EG(objects_store).size = new_size; - handle = EG(objects_store).top++; + if (free_list_head != -1) { + handle = free_list_head; + EG(objects_store).free_list_head = GET_OBJ_BUCKET_NUMBER(EG(objects_store).object_buckets[handle]); + object->handle = handle; + EG(objects_store).object_buckets[handle] = (zend_object*)MASK_PTR(bucket_value); + } else +# endif +#endif + { +#ifdef USE_LIBGC +#if USE_LONG_LINKS + zend_object **orig_buckets = EG(objects_store).object_buckets; +# endif +#endif + EG(objects_store).object_buckets = (zend_object **) erealloc(EG(objects_store).object_buckets, new_size * sizeof(zend_object*)); + +#ifdef USE_LIBGC +# if USE_LONG_LINKS + /* Move links from old buckets to new ones */ + if (orig_buckets != EG(objects_store).object_buckets) { + for (uint32_t i = 0, l = EG(objects_store).size; i < l; i++) { + if (IS_OBJ_VALID(EG(objects_store).object_buckets[i]) || IS_OBJ_PLACEHOLDER(EG(objects_store).object_buckets[i])) { + if (GC_move_long_link((void**)&orig_buckets[i], + (void**)&EG(objects_store).object_buckets[i]) != GC_SUCCESS) { + ZEND_UNREACHABLE(); + } + } + } + } +# endif +#endif + + /* Assign size after realloc, in case it fails */ + EG(objects_store).size = new_size; + handle = EG(objects_store).top++; + + } object->handle = handle; - EG(objects_store).object_buckets[handle] = object; + EG(objects_store).object_buckets[handle] = (zend_object*)MASK_PTR(bucket_value); +#ifdef USE_LIBGC +# if USE_LONG_LINKS + if (IS_OBJ_PLACEHOLDER(bucket_value)) { + if (GC_REGISTER_LONG_LINK((void**)&EG(objects_store).object_buckets[handle], + (char*)object - object->handlers->offset) != GC_SUCCESS) { + ZEND_UNREACHABLE(); + } + } +# endif +#endif +} + +#ifdef USE_LIBGC +# if USE_FINALIZERS +static void zend_object_free_finalizer(void *ptr, void *data) +{ + zend_objects_store_del_ex((zend_object*)GC_REVEAL_POINTER(data), true); } +static void zend_object_dtor_finalizer(void *ptr, void *data) +{ + zend_object *object = (zend_object*)GC_REVEAL_POINTER(data); + + if (!(OBJ_FLAGS(object) & IS_OBJ_DESTRUCTOR_CALLED)) { + GC_ADD_FLAGS(object, IS_OBJ_DESTRUCTOR_CALLED); + + if (object->handlers->dtor_obj != zend_objects_destroy_object + || object->ce->destructor) { + object->handlers->dtor_obj(object); + } + } + + if (ALL_FINALIZERS + || object->handlers->free_obj != zend_object_std_dtor + || (OBJ_FLAGS(object) & IS_OBJ_WEAKLY_REFERENCED)) { + GC_REGISTER_FINALIZER_NO_ORDER((char*)object - object->handlers->offset, + zend_object_free_finalizer, (void*)GC_HIDE_POINTER(object), NULL, NULL); + } +} +# endif +#endif + ZEND_API void ZEND_FASTCALL zend_objects_store_put(zend_object *object) { int handle; + void *bucket_value = object; + +#ifdef USE_LIBGC +# if USE_FINALIZERS + if (object->handlers->dtor_obj != zend_objects_destroy_object + || object->ce->destructor) { + GC_REGISTER_FINALIZER_NO_ORDER((char*)object - object->handlers->offset, + zend_object_dtor_finalizer, (void*)GC_HIDE_POINTER(object), NULL, NULL); + } else if (ALL_FINALIZERS + || object->handlers->free_obj != zend_object_std_dtor) { + GC_REGISTER_FINALIZER_NO_ORDER((char*)object - object->handlers->offset, + zend_object_free_finalizer, (void*)GC_HIDE_POINTER(object), NULL, NULL); + } else +# endif + { + bucket_value = SET_OBJ_PLACEHOLDER(SET_OBJ_INVALID(object)); + } +#endif /* When in shutdown sequence - do not reuse previously freed handles, to make sure * the dtors for newly created objects are called in zend_objects_store_call_destructors() loop @@ -150,24 +349,48 @@ ZEND_API void ZEND_FASTCALL zend_objects_store_put(zend_object *object) handle = EG(objects_store).free_list_head; EG(objects_store).free_list_head = GET_OBJ_BUCKET_NUMBER(EG(objects_store).object_buckets[handle]); } else if (UNEXPECTED(EG(objects_store).top == EG(objects_store).size)) { - zend_objects_store_put_cold(object); + zend_objects_store_put_cold(object, bucket_value); return; } else { handle = EG(objects_store).top++; } object->handle = handle; - EG(objects_store).object_buckets[handle] = object; + EG(objects_store).object_buckets[handle] = (zend_object*) MASK_PTR(bucket_value); +#ifdef USE_LIBGC +# if USE_LONG_LINKS + if (IS_OBJ_PLACEHOLDER(bucket_value)) { + if (GC_REGISTER_LONG_LINK((void**)&EG(objects_store).object_buckets[handle], + (char*)object - object->handlers->offset) != GC_SUCCESS) { + ZEND_UNREACHABLE(); + } + } +# endif +#endif } -ZEND_API void ZEND_FASTCALL zend_objects_store_del(zend_object *object) /* {{{ */ +static void ZEND_FASTCALL zend_objects_store_del_ex(zend_object *object, bool from_finalizer) /* {{{ */ { - ZEND_ASSERT(GC_REFCOUNT(object) == 0); + uint32_t handle = object->handle; - /* GC might have released this object already. */ - if (UNEXPECTED(GC_TYPE(object) == IS_NULL)) { + ZEND_ASSERT(handle != 0); + + if (!IS_OBJ_VALID(EG(objects_store).object_buckets[handle])) { + // Object is being deleted already return; } + EG(objects_store).object_buckets[handle] = (zend_object*)MASK_PTR(SET_OBJ_INVALID(object)); + + /* No need to unregister link explicitly if we also don't add to free list bellow +#ifdef USE_LIBGC +# if USE_LONG_LINKS + if (GC_unregister_long_link((void**)&EG(objects_store).object_buckets[handle]) != 1) { + ZEND_UNREACHABLE(); + } +# endif +#endif + */ + /* Make sure we hold a reference count during the destructor call otherwise, when the destructor ends the storage might be freed when the refcount reaches 0 a second time @@ -179,30 +402,42 @@ ZEND_API void ZEND_FASTCALL zend_objects_store_del(zend_object *object) /* {{{ * || object->ce->destructor) { GC_SET_REFCOUNT(object, 1); object->handlers->dtor_obj(object); - GC_DELREF(object); + GC_DELREF_OBJ(object); } } - if (GC_REFCOUNT(object) == 0) { - uint32_t handle = object->handle; + if (!(IS_OBJECT_EX & (IS_TYPE_REFCOUNTED << Z_TYPE_FLAGS_SHIFT)) || GC_REFCOUNT(object) == 0) { void *ptr; ZEND_ASSERT(EG(objects_store).object_buckets != NULL); - ZEND_ASSERT(IS_OBJ_VALID(EG(objects_store).object_buckets[handle])); - EG(objects_store).object_buckets[handle] = SET_OBJ_INVALID(object); if (!(OBJ_FLAGS(object) & IS_OBJ_FREE_CALLED)) { GC_ADD_FLAGS(object, IS_OBJ_FREE_CALLED); - GC_SET_REFCOUNT(object, 1); object->handlers->free_obj(object); } ptr = ((char*)object) - object->handlers->offset; GC_REMOVE_FROM_BUFFER(object); efree(ptr); +#if !defined(USE_LIBGC) || !defined(USE_LONG_LINKS) ZEND_OBJECTS_STORE_ADD_TO_FREE_LIST(handle); +#endif + } + +#ifdef USE_LIBGC +# if USE_FINALIZERS + if (!from_finalizer) { + GC_REGISTER_FINALIZER_NO_ORDER((char*)object - object->handlers->offset, + NULL /* Unregister */, NULL, NULL, NULL); } +# endif +#endif } /* }}} */ +ZEND_API void ZEND_FASTCALL zend_objects_store_del(zend_object *object) /* {{{ */ +{ + zend_objects_store_del_ex(object, false); +} + ZEND_API ZEND_COLD zend_property_info *zend_get_property_info_for_slot_slow(zend_object *obj, zval *slot) { uintptr_t offset = OBJ_PROP_SLOT_TO_OFFSET(obj, slot); diff --git a/Zend/zend_objects_API.h b/Zend/zend_objects_API.h index 86c3a49f8c8c5..18299f317a65f 100644 --- a/Zend/zend_objects_API.h +++ b/Zend/zend_objects_API.h @@ -25,16 +25,19 @@ #include "zend_alloc.h" #include "zend_compile.h" /* For zend_property_info */ -#define OBJ_BUCKET_INVALID (1<<0) - -#define IS_OBJ_VALID(o) (!(((uintptr_t)(o)) & OBJ_BUCKET_INVALID)) +#define OBJ_BUCKET_INVALID (1<<0) /* Object may have been freed already */ +#define OBJ_BUCKET_PLACEHOLDER (1<<1) /* Bucket is a placeholder that will be cleared by GC */ +#define IS_OBJ_VALID(o) (o && !(((uintptr_t)(o)) & OBJ_BUCKET_INVALID)) #define SET_OBJ_INVALID(o) ((zend_object*)((((uintptr_t)(o)) | OBJ_BUCKET_INVALID))) -#define GET_OBJ_BUCKET_NUMBER(o) (((intptr_t)(o)) >> 1) +#define IS_OBJ_PLACEHOLDER(o) (((uintptr_t)(o)) & OBJ_BUCKET_PLACEHOLDER) +#define SET_OBJ_PLACEHOLDER(o) ((zend_object*)((((uintptr_t)(o)) | OBJ_BUCKET_PLACEHOLDER))) + +#define GET_OBJ_BUCKET_NUMBER(o) (((intptr_t)(o)) >> 2) #define SET_OBJ_BUCKET_NUMBER(o, n) do { \ - (o) = (zend_object*)((((uintptr_t)(n)) << 1) | OBJ_BUCKET_INVALID); \ + (o) = (zend_object*)((((uintptr_t)(n)) << 2) | OBJ_BUCKET_INVALID); \ } while (0) #define ZEND_OBJECTS_STORE_ADD_TO_FREE_LIST(h) do { \ @@ -73,6 +76,10 @@ END_EXTERN_C() static zend_always_inline void zend_object_release(zend_object *obj) { + if (!(IS_OBJECT_EX & (IS_TYPE_REFCOUNTED << Z_TYPE_FLAGS_SHIFT))) { + return; + } + if (GC_DELREF(obj) == 0) { zend_objects_store_del(obj); } else if (UNEXPECTED(GC_MAY_LEAK((zend_refcounted*)obj))) { @@ -149,4 +156,8 @@ static zend_always_inline bool zend_check_method_accessible(const zend_function return true; } +#ifdef USE_LIBGC +void ZEND_FASTCALL zend_objects_store_set_weakref_finalizer(zend_object *object); +#endif + #endif /* ZEND_OBJECTS_H */ diff --git a/Zend/zend_stream.c b/Zend/zend_stream.c index 8e11841ad2658..bd879896134ac 100644 --- a/Zend/zend_stream.c +++ b/Zend/zend_stream.c @@ -161,7 +161,7 @@ ZEND_API zend_result zend_stream_fixup(zend_file_handle *file_handle, char **buf if (file_size) { ssize_t read; size_t size = 0; - *buf = safe_emalloc(1, file_size, ZEND_MMAP_AHEAD); + *buf = safe_emalloc_atomic(1, file_size, ZEND_MMAP_AHEAD); while ((read = zend_stream_read(file_handle, *buf + size, file_size - size)) > 0) { size += read; } @@ -174,7 +174,7 @@ ZEND_API zend_result zend_stream_fixup(zend_file_handle *file_handle, char **buf } else { size_t size = 0, remain = 4*1024; ssize_t read; - *buf = emalloc(remain); + *buf = emalloc_atomic(remain); while ((read = zend_stream_read(file_handle, *buf + size, remain)) > 0) { size += read; diff --git a/Zend/zend_string.h b/Zend/zend_string.h index 87f221125202c..182f137d761a3 100644 --- a/Zend/zend_string.h +++ b/Zend/zend_string.h @@ -164,7 +164,7 @@ static zend_always_inline uint32_t zend_string_delref(zend_string *s) static zend_always_inline zend_string *zend_string_alloc(size_t len, bool persistent) { - zend_string *ret = (zend_string *)pemalloc(ZEND_MM_ALIGNED_SIZE(_ZSTR_STRUCT_SIZE(len)), persistent); + zend_string *ret = (zend_string *)pemalloc_atomic(ZEND_MM_ALIGNED_SIZE(_ZSTR_STRUCT_SIZE(len)), persistent); GC_SET_REFCOUNT(ret, 1); GC_TYPE_INFO(ret) = GC_STRING | ((persistent ? IS_STR_PERSISTENT : 0) << GC_FLAGS_SHIFT); @@ -175,7 +175,7 @@ static zend_always_inline zend_string *zend_string_alloc(size_t len, bool persis static zend_always_inline zend_string *zend_string_safe_alloc(size_t n, size_t m, size_t l, bool persistent) { - zend_string *ret = (zend_string *)safe_pemalloc(n, m, ZEND_MM_ALIGNED_SIZE(_ZSTR_STRUCT_SIZE(l)), persistent); + zend_string *ret = (zend_string *)safe_pemalloc_atomic(n, m, ZEND_MM_ALIGNED_SIZE(_ZSTR_STRUCT_SIZE(l)), persistent); GC_SET_REFCOUNT(ret, 1); GC_TYPE_INFO(ret) = GC_STRING | ((persistent ? IS_STR_PERSISTENT : 0) << GC_FLAGS_SHIFT); diff --git a/Zend/zend_types.h b/Zend/zend_types.h index a3d3e4da6362d..08ac4f790979d 100644 --- a/Zend/zend_types.h +++ b/Zend/zend_types.h @@ -728,6 +728,8 @@ static zend_always_inline uint8_t zval_get_type(const zval* pz) { #define GC_SET_REFCOUNT(p, rc) zend_gc_set_refcount(&(p)->gc, rc) #define GC_ADDREF(p) zend_gc_addref(&(p)->gc) #define GC_DELREF(p) zend_gc_delref(&(p)->gc) +#define GC_ADDREF_OBJ(p) zend_gc_addref_obj(&(p)->gc) +#define GC_DELREF_OBJ(p) zend_gc_delref_obj(&(p)->gc) #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_TRY_ADDREF(p) zend_gc_try_addref(&(p)->gc) @@ -838,7 +840,11 @@ static zend_always_inline uint32_t zval_gc_info(uint32_t gc_type_info) { #define IS_STRING_EX (IS_STRING | (IS_TYPE_REFCOUNTED << Z_TYPE_FLAGS_SHIFT)) #define IS_ARRAY_EX (IS_ARRAY | (IS_TYPE_REFCOUNTED << Z_TYPE_FLAGS_SHIFT) | (IS_TYPE_COLLECTABLE << Z_TYPE_FLAGS_SHIFT)) -#define IS_OBJECT_EX (IS_OBJECT | (IS_TYPE_REFCOUNTED << Z_TYPE_FLAGS_SHIFT) | (IS_TYPE_COLLECTABLE << Z_TYPE_FLAGS_SHIFT)) +#ifdef USE_LIBGC +# define IS_OBJECT_EX IS_OBJECT +#else +# define IS_OBJECT_EX (IS_OBJECT | (IS_TYPE_REFCOUNTED << Z_TYPE_FLAGS_SHIFT) | (IS_TYPE_COLLECTABLE << Z_TYPE_FLAGS_SHIFT)) +#endif #define IS_RESOURCE_EX (IS_RESOURCE | (IS_TYPE_REFCOUNTED << Z_TYPE_FLAGS_SHIFT)) #define IS_REFERENCE_EX (IS_REFERENCE | (IS_TYPE_REFCOUNTED << Z_TYPE_FLAGS_SHIFT) | (IS_TYPE_COLLECTABLE << Z_TYPE_FLAGS_SHIFT)) @@ -1077,9 +1083,16 @@ static zend_always_inline uint32_t zval_gc_info(uint32_t gc_type_info) { #define Z_PTR(zval) (zval).value.ptr #define Z_PTR_P(zval_p) Z_PTR(*(zval_p)) -#define ZVAL_UNDEF(z) do { \ +#ifdef USE_LIBGC +# define ZVAL_UNDEF(z) do { \ + Z_TYPE_INFO_P(z) = IS_UNDEF; \ + Z_PTR_P(z) = NULL; \ + } while (0) +#else +# define ZVAL_UNDEF(z) do { \ Z_TYPE_INFO_P(z) = IS_UNDEF; \ } while (0) +#endif #define ZVAL_NULL(z) do { \ Z_TYPE_INFO_P(z) = IS_NULL; \ @@ -1365,6 +1378,13 @@ static zend_always_inline uint32_t zend_gc_addref(zend_refcounted_h *p) { return ++(p->refcount); } +static zend_always_inline uint32_t zend_gc_addref_obj(zend_refcounted_h *p) { + if (!(IS_OBJECT_EX & (IS_TYPE_REFCOUNTED << Z_TYPE_FLAGS_SHIFT))) { + return 2; + } + return zend_gc_addref(p); +} + static zend_always_inline void zend_gc_try_addref(zend_refcounted_h *p) { if (!(p->u.type_info & GC_IMMUTABLE)) { ZEND_RC_MOD_CHECK(p); @@ -1381,10 +1401,18 @@ static zend_always_inline void zend_gc_try_delref(zend_refcounted_h *p) { static zend_always_inline uint32_t zend_gc_delref(zend_refcounted_h *p) { ZEND_ASSERT(p->refcount > 0); + ZEND_ASSERT(GC_TYPE((zend_refcounted*)p) != IS_OBJECT || (IS_OBJECT_EX & (IS_TYPE_REFCOUNTED << Z_TYPE_FLAGS_SHIFT))); ZEND_RC_MOD_CHECK(p); return --(p->refcount); } +static zend_always_inline uint32_t zend_gc_delref_obj(zend_refcounted_h *p) { + if (IS_OBJECT_EX & (IS_TYPE_REFCOUNTED << Z_TYPE_FLAGS_SHIFT)) { + return zend_gc_delref(p); + } + return 2; +} + static zend_always_inline uint32_t zend_gc_addref_ex(zend_refcounted_h *p, uint32_t rc) { ZEND_RC_MOD_CHECK(p); p->refcount += rc; diff --git a/Zend/zend_variables.c b/Zend/zend_variables.c index 00f10b08f80ab..11e292c4d0ecd 100644 --- a/Zend/zend_variables.c +++ b/Zend/zend_variables.c @@ -45,7 +45,7 @@ static const zend_rc_dtor_func_t zend_rc_dtor_func[] = { [IS_DOUBLE] = (zend_rc_dtor_func_t)zend_empty_destroy, [IS_STRING] = (zend_rc_dtor_func_t)zend_string_destroy, [IS_ARRAY] = (zend_rc_dtor_func_t)zend_array_destroy, - [IS_OBJECT] = (zend_rc_dtor_func_t)zend_objects_store_del, + [IS_OBJECT] = (zend_rc_dtor_func_t)zend_empty_destroy, [IS_RESOURCE] = (zend_rc_dtor_func_t)zend_list_free, [IS_REFERENCE] = (zend_rc_dtor_func_t)zend_reference_destroy, [IS_CONSTANT_AST] = (zend_rc_dtor_func_t)zend_ast_ref_destroy diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index 3d6463d064873..4342cc8016487 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -23,6 +23,7 @@ * php zend_vm_gen.php */ +#include "zend_types.h" ZEND_VM_HELPER(zend_add_helper, ANY, ANY, zval *op_1, zval *op_2) { USE_OPLINE @@ -2733,7 +2734,7 @@ ZEND_VM_C_LABEL(try_assign_dim_array): if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { zend_object *obj = Z_OBJ_P(object_ptr); - GC_ADDREF(obj); + GC_ADDREF_OBJ(obj); dim = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R); if (OP2_TYPE == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { dim = ZVAL_UNDEFINED_OP2(); @@ -2751,7 +2752,7 @@ ZEND_VM_C_LABEL(try_assign_dim_array): zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC); FREE_OP_DATA(); - if (UNEXPECTED(GC_DELREF(obj) == 0)) { + if (UNEXPECTED(GC_DELREF_OBJ(obj) == 0)) { zend_objects_store_del(obj); } } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { @@ -3692,7 +3693,7 @@ ZEND_VM_HOT_OBJ_HANDLER(112, ZEND_INIT_METHOD_CALL, CONST|TMPVAR|UNUSED|THIS|CV, CACHE_POLYMORPHIC_PTR(opline->result.num, called_scope, fbc); } if ((OP1_TYPE & (IS_VAR|IS_TMP_VAR)) && UNEXPECTED(obj != orig_obj)) { - GC_ADDREF(obj); /* For $this pointer */ + GC_ADDREF_OBJ(obj); /* For $this pointer */ if (GC_DELREF(orig_obj) == 0) { zend_objects_store_del(orig_obj); } @@ -3708,7 +3709,7 @@ ZEND_VM_HOT_OBJ_HANDLER(112, ZEND_INIT_METHOD_CALL, CONST|TMPVAR|UNUSED|THIS|CV, call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS; if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_STATIC) != 0)) { - if ((OP1_TYPE & (IS_VAR|IS_TMP_VAR)) && GC_DELREF(obj) == 0) { + if ((OP1_TYPE & (IS_VAR|IS_TMP_VAR)) && GC_DELREF_OBJ(obj) == 0) { zend_objects_store_del(obj); if (UNEXPECTED(EG(exception))) { HANDLE_EXCEPTION(); @@ -3719,7 +3720,7 @@ ZEND_VM_HOT_OBJ_HANDLER(112, ZEND_INIT_METHOD_CALL, CONST|TMPVAR|UNUSED|THIS|CV, call_info = ZEND_CALL_NESTED_FUNCTION; } else if (OP1_TYPE & (IS_VAR|IS_TMP_VAR|IS_CV)) { if (OP1_TYPE == IS_CV) { - GC_ADDREF(obj); /* For $this pointer */ + GC_ADDREF_OBJ(obj); /* For $this pointer */ } /* CV may be changed indirectly (e.g. when it's a reference) */ call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS | ZEND_CALL_RELEASE_THIS; @@ -4695,7 +4696,7 @@ ZEND_VM_HANDLER(139, ZEND_GENERATOR_CREATE, ANY, ANY) /* Bug #72523 */ || UNEXPECTED(zend_execute_ex != execute_ex))) { ZEND_ADD_CALL_FLAG_EX(call_info, ZEND_CALL_RELEASE_THIS); - Z_ADDREF(gen_execute_data->This); + GC_ADDREF_OBJ(Z_OBJ(gen_execute_data->This)); } ZEND_ADD_CALL_FLAG_EX(call_info, (ZEND_CALL_TOP_FUNCTION | ZEND_CALL_ALLOCATED | ZEND_CALL_GENERATOR)); Z_TYPE_INFO(gen_execute_data->This) = call_info; @@ -5994,7 +5995,7 @@ ZEND_VM_HANDLER(68, ZEND_NEW, UNUSED|CLASS_FETCH|CONST|VAR, UNUSED|CACHE_SLOT, N constructor, opline->extended_value, Z_OBJ_P(result)); - Z_ADDREF_P(result); + GC_ADDREF_OBJ(Z_OBJ_P(result)); } call->prev_execute_data = EX(call); @@ -8527,7 +8528,7 @@ ZEND_VM_C_LABEL(yield_from_try_again): if (ce == zend_ce_generator) { zend_generator *new_gen = (zend_generator *) Z_OBJ_P(val); - Z_ADDREF_P(val); + GC_ADDREF_OBJ(Z_OBJ_P(val)); FREE_OP1(); if (UNEXPECTED(new_gen->execute_data == NULL)) { @@ -9198,7 +9199,7 @@ ZEND_VM_HOT_HANDLER(184, ZEND_FETCH_THIS, UNUSED, UNUSED) zval *result = EX_VAR(opline->result.var); ZVAL_OBJ(result, Z_OBJ(EX(This))); - Z_ADDREF_P(result); + GC_ADDREF_OBJ(Z_OBJ_P(result)); ZEND_VM_NEXT_OPCODE(); } else { ZEND_VM_DISPATCH_TO_HELPER(zend_this_not_in_object_context_helper); @@ -10504,25 +10505,32 @@ ZEND_VM_HELPER(zend_interrupt_helper, ANY, ANY) { zend_atomic_bool_store_ex(&EG(vm_interrupt), false); SAVE_OPLINE(); + bool expected = true; if (zend_atomic_bool_load_ex(&EG(timed_out))) { zend_timeout(); + ZEND_VM_CONTINUE(); } else if (zend_interrupt_function) { zend_interrupt_function(execute_data); - if (EG(exception)) { - /* We have to UNDEF result, because ZEND_HANDLE_EXCEPTION is going to free it */ - const zend_op *throw_op = EG(opline_before_exception); +#ifdef USE_LIBGC + } else if (zend_atomic_bool_compare_exchange_ex(&EG(pending_finalizations), &expected, false)) { + GC_invoke_finalizers(); +#endif + } else { + ZEND_VM_CONTINUE(); + } + if (EG(exception)) { + /* We have to UNDEF result, because ZEND_HANDLE_EXCEPTION is going to free it */ + const zend_op *throw_op = EG(opline_before_exception); - if (throw_op - && throw_op->result_type & (IS_TMP_VAR|IS_VAR) - && throw_op->opcode != ZEND_ADD_ARRAY_ELEMENT - && throw_op->opcode != ZEND_ADD_ARRAY_UNPACK - && throw_op->opcode != ZEND_ROPE_INIT - && throw_op->opcode != ZEND_ROPE_ADD) { - ZVAL_UNDEF(ZEND_CALL_VAR(EG(current_execute_data), throw_op->result.var)); + if (throw_op + && throw_op->result_type & (IS_TMP_VAR|IS_VAR) + && throw_op->opcode != ZEND_ADD_ARRAY_ELEMENT + && throw_op->opcode != ZEND_ADD_ARRAY_UNPACK + && throw_op->opcode != ZEND_ROPE_INIT + && throw_op->opcode != ZEND_ROPE_ADD) { + ZVAL_UNDEF(ZEND_CALL_VAR(EG(current_execute_data), throw_op->result.var)); - } } - ZEND_VM_ENTER(); } - ZEND_VM_CONTINUE(); + ZEND_VM_ENTER(); } diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index e1a94fd07a11a..31ce79e0bc914 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -2344,7 +2344,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_GENERATOR_CRE /* Bug #72523 */ || UNEXPECTED(zend_execute_ex != execute_ex))) { ZEND_ADD_CALL_FLAG_EX(call_info, ZEND_CALL_RELEASE_THIS); - Z_ADDREF(gen_execute_data->This); + GC_ADDREF_OBJ(Z_OBJ(gen_execute_data->This)); } ZEND_ADD_CALL_FLAG_EX(call_info, (ZEND_CALL_TOP_FUNCTION | ZEND_CALL_ALLOCATED | ZEND_CALL_GENERATOR)); Z_TYPE_INFO(gen_execute_data->This) = call_info; @@ -3982,27 +3982,34 @@ static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV { zend_atomic_bool_store_ex(&EG(vm_interrupt), false); SAVE_OPLINE(); + bool expected = true; if (zend_atomic_bool_load_ex(&EG(timed_out))) { zend_timeout(); + ZEND_VM_CONTINUE(); } else if (zend_interrupt_function) { zend_interrupt_function(execute_data); - if (EG(exception)) { - /* We have to UNDEF result, because ZEND_HANDLE_EXCEPTION is going to free it */ - const zend_op *throw_op = EG(opline_before_exception); +#ifdef USE_LIBGC + } else if (zend_atomic_bool_compare_exchange_ex(&EG(pending_finalizations), &expected, false)) { + GC_invoke_finalizers(); +#endif + } else { + ZEND_VM_CONTINUE(); + } + if (EG(exception)) { + /* We have to UNDEF result, because ZEND_HANDLE_EXCEPTION is going to free it */ + const zend_op *throw_op = EG(opline_before_exception); - if (throw_op - && throw_op->result_type & (IS_TMP_VAR|IS_VAR) - && throw_op->opcode != ZEND_ADD_ARRAY_ELEMENT - && throw_op->opcode != ZEND_ADD_ARRAY_UNPACK - && throw_op->opcode != ZEND_ROPE_INIT - && throw_op->opcode != ZEND_ROPE_ADD) { - ZVAL_UNDEF(ZEND_CALL_VAR(EG(current_execute_data), throw_op->result.var)); + if (throw_op + && throw_op->result_type & (IS_TMP_VAR|IS_VAR) + && throw_op->opcode != ZEND_ADD_ARRAY_ELEMENT + && throw_op->opcode != ZEND_ADD_ARRAY_UNPACK + && throw_op->opcode != ZEND_ROPE_INIT + && throw_op->opcode != ZEND_ROPE_ADD) { + ZVAL_UNDEF(ZEND_CALL_VAR(EG(current_execute_data), throw_op->result.var)); - } } - ZEND_VM_ENTER(); } - ZEND_VM_CONTINUE(); + ZEND_VM_ENTER(); } static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INIT_FCALL_BY_NAME_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { @@ -5864,7 +5871,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_YIELD_FROM_SP if (ce == zend_ce_generator) { zend_generator *new_gen = (zend_generator *) Z_OBJ_P(val); - Z_ADDREF_P(val); + GC_ADDREF_OBJ(Z_OBJ_P(val)); if (UNEXPECTED(new_gen->execute_data == NULL)) { zend_throw_error(NULL, "Generator passed to yield from was aborted without proper return and is unable to continue"); @@ -7289,7 +7296,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ CACHE_POLYMORPHIC_PTR(opline->result.num, called_scope, fbc); } if ((IS_CONST & (IS_VAR|IS_TMP_VAR)) && UNEXPECTED(obj != orig_obj)) { - GC_ADDREF(obj); /* For $this pointer */ + GC_ADDREF_OBJ(obj); /* For $this pointer */ if (GC_DELREF(orig_obj) == 0) { zend_objects_store_del(orig_obj); } @@ -7305,7 +7312,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS; if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_STATIC) != 0)) { - if ((IS_CONST & (IS_VAR|IS_TMP_VAR)) && GC_DELREF(obj) == 0) { + if ((IS_CONST & (IS_VAR|IS_TMP_VAR)) && GC_DELREF_OBJ(obj) == 0) { zend_objects_store_del(obj); if (UNEXPECTED(EG(exception))) { HANDLE_EXCEPTION(); @@ -7316,7 +7323,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ call_info = ZEND_CALL_NESTED_FUNCTION; } else if (IS_CONST & (IS_VAR|IS_TMP_VAR|IS_CV)) { if (IS_CONST == IS_CV) { - GC_ADDREF(obj); /* For $this pointer */ + GC_ADDREF_OBJ(obj); /* For $this pointer */ } /* CV may be changed indirectly (e.g. when it's a reference) */ call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS | ZEND_CALL_RELEASE_THIS; @@ -9919,7 +9926,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ CACHE_POLYMORPHIC_PTR(opline->result.num, called_scope, fbc); } if ((IS_CONST & (IS_VAR|IS_TMP_VAR)) && UNEXPECTED(obj != orig_obj)) { - GC_ADDREF(obj); /* For $this pointer */ + GC_ADDREF_OBJ(obj); /* For $this pointer */ if (GC_DELREF(orig_obj) == 0) { zend_objects_store_del(orig_obj); } @@ -9935,7 +9942,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS; if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_STATIC) != 0)) { - if ((IS_CONST & (IS_VAR|IS_TMP_VAR)) && GC_DELREF(obj) == 0) { + if ((IS_CONST & (IS_VAR|IS_TMP_VAR)) && GC_DELREF_OBJ(obj) == 0) { zend_objects_store_del(obj); if (UNEXPECTED(EG(exception))) { HANDLE_EXCEPTION(); @@ -9946,7 +9953,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ call_info = ZEND_CALL_NESTED_FUNCTION; } else if (IS_CONST & (IS_VAR|IS_TMP_VAR|IS_CV)) { if (IS_CONST == IS_CV) { - GC_ADDREF(obj); /* For $this pointer */ + GC_ADDREF_OBJ(obj); /* For $this pointer */ } /* CV may be changed indirectly (e.g. when it's a reference) */ call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS | ZEND_CALL_RELEASE_THIS; @@ -11082,7 +11089,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_NEW_SPEC_CONS constructor, opline->extended_value, Z_OBJ_P(result)); - Z_ADDREF_P(result); + GC_ADDREF_OBJ(Z_OBJ_P(result)); } call->prev_execute_data = EX(call); @@ -12412,7 +12419,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ CACHE_POLYMORPHIC_PTR(opline->result.num, called_scope, fbc); } if ((IS_CONST & (IS_VAR|IS_TMP_VAR)) && UNEXPECTED(obj != orig_obj)) { - GC_ADDREF(obj); /* For $this pointer */ + GC_ADDREF_OBJ(obj); /* For $this pointer */ if (GC_DELREF(orig_obj) == 0) { zend_objects_store_del(orig_obj); } @@ -12428,7 +12435,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS; if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_STATIC) != 0)) { - if ((IS_CONST & (IS_VAR|IS_TMP_VAR)) && GC_DELREF(obj) == 0) { + if ((IS_CONST & (IS_VAR|IS_TMP_VAR)) && GC_DELREF_OBJ(obj) == 0) { zend_objects_store_del(obj); if (UNEXPECTED(EG(exception))) { HANDLE_EXCEPTION(); @@ -12439,7 +12446,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ call_info = ZEND_CALL_NESTED_FUNCTION; } else if (IS_CONST & (IS_VAR|IS_TMP_VAR|IS_CV)) { if (IS_CONST == IS_CV) { - GC_ADDREF(obj); /* For $this pointer */ + GC_ADDREF_OBJ(obj); /* For $this pointer */ } /* CV may be changed indirectly (e.g. when it's a reference) */ call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS | ZEND_CALL_RELEASE_THIS; @@ -15605,7 +15612,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_YIELD_FROM_SP if (ce == zend_ce_generator) { zend_generator *new_gen = (zend_generator *) Z_OBJ_P(val); - Z_ADDREF_P(val); + GC_ADDREF_OBJ(Z_OBJ_P(val)); zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); if (UNEXPECTED(new_gen->execute_data == NULL)) { @@ -16895,7 +16902,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INIT_METHOD_C CACHE_POLYMORPHIC_PTR(opline->result.num, called_scope, fbc); } if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_TMP_VAR)) && UNEXPECTED(obj != orig_obj)) { - GC_ADDREF(obj); /* For $this pointer */ + GC_ADDREF_OBJ(obj); /* For $this pointer */ if (GC_DELREF(orig_obj) == 0) { zend_objects_store_del(orig_obj); } @@ -16911,7 +16918,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INIT_METHOD_C call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS; if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_STATIC) != 0)) { - if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_TMP_VAR)) && GC_DELREF(obj) == 0) { + if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_TMP_VAR)) && GC_DELREF_OBJ(obj) == 0) { zend_objects_store_del(obj); if (UNEXPECTED(EG(exception))) { HANDLE_EXCEPTION(); @@ -16922,7 +16929,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INIT_METHOD_C call_info = ZEND_CALL_NESTED_FUNCTION; } else if ((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_TMP_VAR|IS_CV)) { if ((IS_TMP_VAR|IS_VAR) == IS_CV) { - GC_ADDREF(obj); /* For $this pointer */ + GC_ADDREF_OBJ(obj); /* For $this pointer */ } /* CV may be changed indirectly (e.g. when it's a reference) */ call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS | ZEND_CALL_RELEASE_THIS; @@ -18388,7 +18395,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INIT_METHOD_C CACHE_POLYMORPHIC_PTR(opline->result.num, called_scope, fbc); } if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_TMP_VAR)) && UNEXPECTED(obj != orig_obj)) { - GC_ADDREF(obj); /* For $this pointer */ + GC_ADDREF_OBJ(obj); /* For $this pointer */ if (GC_DELREF(orig_obj) == 0) { zend_objects_store_del(orig_obj); } @@ -18404,7 +18411,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INIT_METHOD_C call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS; if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_STATIC) != 0)) { - if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_TMP_VAR)) && GC_DELREF(obj) == 0) { + if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_TMP_VAR)) && GC_DELREF_OBJ(obj) == 0) { zend_objects_store_del(obj); if (UNEXPECTED(EG(exception))) { HANDLE_EXCEPTION(); @@ -18415,7 +18422,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INIT_METHOD_C call_info = ZEND_CALL_NESTED_FUNCTION; } else if ((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_TMP_VAR|IS_CV)) { if ((IS_TMP_VAR|IS_VAR) == IS_CV) { - GC_ADDREF(obj); /* For $this pointer */ + GC_ADDREF_OBJ(obj); /* For $this pointer */ } /* CV may be changed indirectly (e.g. when it's a reference) */ call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS | ZEND_CALL_RELEASE_THIS; @@ -19795,7 +19802,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INIT_METHOD_C CACHE_POLYMORPHIC_PTR(opline->result.num, called_scope, fbc); } if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_TMP_VAR)) && UNEXPECTED(obj != orig_obj)) { - GC_ADDREF(obj); /* For $this pointer */ + GC_ADDREF_OBJ(obj); /* For $this pointer */ if (GC_DELREF(orig_obj) == 0) { zend_objects_store_del(orig_obj); } @@ -19811,7 +19818,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INIT_METHOD_C call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS; if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_STATIC) != 0)) { - if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_TMP_VAR)) && GC_DELREF(obj) == 0) { + if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_TMP_VAR)) && GC_DELREF_OBJ(obj) == 0) { zend_objects_store_del(obj); if (UNEXPECTED(EG(exception))) { HANDLE_EXCEPTION(); @@ -19822,7 +19829,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INIT_METHOD_C call_info = ZEND_CALL_NESTED_FUNCTION; } else if ((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_TMP_VAR|IS_CV)) { if ((IS_TMP_VAR|IS_VAR) == IS_CV) { - GC_ADDREF(obj); /* For $this pointer */ + GC_ADDREF_OBJ(obj); /* For $this pointer */ } /* CV may be changed indirectly (e.g. when it's a reference) */ call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS | ZEND_CALL_RELEASE_THIS; @@ -24823,7 +24830,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_DIM_SP if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { zend_object *obj = Z_OBJ_P(object_ptr); - GC_ADDREF(obj); + GC_ADDREF_OBJ(obj); dim = RT_CONSTANT(opline, opline->op2); if (IS_CONST == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { dim = ZVAL_UNDEFINED_OP2(); @@ -24840,7 +24847,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_DIM_SP zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC); - if (UNEXPECTED(GC_DELREF(obj) == 0)) { + if (UNEXPECTED(GC_DELREF_OBJ(obj) == 0)) { zend_objects_store_del(obj); } } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { @@ -24975,7 +24982,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_DIM_SP if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { zend_object *obj = Z_OBJ_P(object_ptr); - GC_ADDREF(obj); + GC_ADDREF_OBJ(obj); dim = RT_CONSTANT(opline, opline->op2); if (IS_CONST == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { dim = ZVAL_UNDEFINED_OP2(); @@ -24993,7 +25000,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_DIM_SP zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC); zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); - if (UNEXPECTED(GC_DELREF(obj) == 0)) { + if (UNEXPECTED(GC_DELREF_OBJ(obj) == 0)) { zend_objects_store_del(obj); } } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { @@ -25128,7 +25135,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_DIM_SP if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { zend_object *obj = Z_OBJ_P(object_ptr); - GC_ADDREF(obj); + GC_ADDREF_OBJ(obj); dim = RT_CONSTANT(opline, opline->op2); if (IS_CONST == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { dim = ZVAL_UNDEFINED_OP2(); @@ -25146,7 +25153,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_DIM_SP zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC); zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); - if (UNEXPECTED(GC_DELREF(obj) == 0)) { + if (UNEXPECTED(GC_DELREF_OBJ(obj) == 0)) { zend_objects_store_del(obj); } } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { @@ -25281,7 +25288,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_DIM_SP if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { zend_object *obj = Z_OBJ_P(object_ptr); - GC_ADDREF(obj); + GC_ADDREF_OBJ(obj); dim = RT_CONSTANT(opline, opline->op2); if (IS_CONST == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { dim = ZVAL_UNDEFINED_OP2(); @@ -25298,7 +25305,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_DIM_SP zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC); - if (UNEXPECTED(GC_DELREF(obj) == 0)) { + if (UNEXPECTED(GC_DELREF_OBJ(obj) == 0)) { zend_objects_store_del(obj); } } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { @@ -27829,7 +27836,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_DIM_SP if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { zend_object *obj = Z_OBJ_P(object_ptr); - GC_ADDREF(obj); + GC_ADDREF_OBJ(obj); dim = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { dim = ZVAL_UNDEFINED_OP2(); @@ -27846,7 +27853,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_DIM_SP zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC); - if (UNEXPECTED(GC_DELREF(obj) == 0)) { + if (UNEXPECTED(GC_DELREF_OBJ(obj) == 0)) { zend_objects_store_del(obj); } } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { @@ -27981,7 +27988,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_DIM_SP if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { zend_object *obj = Z_OBJ_P(object_ptr); - GC_ADDREF(obj); + GC_ADDREF_OBJ(obj); dim = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { dim = ZVAL_UNDEFINED_OP2(); @@ -27999,7 +28006,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_DIM_SP zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC); zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); - if (UNEXPECTED(GC_DELREF(obj) == 0)) { + if (UNEXPECTED(GC_DELREF_OBJ(obj) == 0)) { zend_objects_store_del(obj); } } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { @@ -28134,7 +28141,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_DIM_SP if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { zend_object *obj = Z_OBJ_P(object_ptr); - GC_ADDREF(obj); + GC_ADDREF_OBJ(obj); dim = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { dim = ZVAL_UNDEFINED_OP2(); @@ -28152,7 +28159,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_DIM_SP zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC); zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); - if (UNEXPECTED(GC_DELREF(obj) == 0)) { + if (UNEXPECTED(GC_DELREF_OBJ(obj) == 0)) { zend_objects_store_del(obj); } } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { @@ -28287,7 +28294,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_DIM_SP if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { zend_object *obj = Z_OBJ_P(object_ptr); - GC_ADDREF(obj); + GC_ADDREF_OBJ(obj); dim = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { dim = ZVAL_UNDEFINED_OP2(); @@ -28304,7 +28311,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_DIM_SP zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC); - if (UNEXPECTED(GC_DELREF(obj) == 0)) { + if (UNEXPECTED(GC_DELREF_OBJ(obj) == 0)) { zend_objects_store_del(obj); } } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { @@ -29414,7 +29421,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_DIM_SP if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { zend_object *obj = Z_OBJ_P(object_ptr); - GC_ADDREF(obj); + GC_ADDREF_OBJ(obj); dim = NULL; if (IS_UNUSED == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { dim = ZVAL_UNDEFINED_OP2(); @@ -29431,7 +29438,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_DIM_SP zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC); - if (UNEXPECTED(GC_DELREF(obj) == 0)) { + if (UNEXPECTED(GC_DELREF_OBJ(obj) == 0)) { zend_objects_store_del(obj); } } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { @@ -29566,7 +29573,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_DIM_SP if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { zend_object *obj = Z_OBJ_P(object_ptr); - GC_ADDREF(obj); + GC_ADDREF_OBJ(obj); dim = NULL; if (IS_UNUSED == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { dim = ZVAL_UNDEFINED_OP2(); @@ -29584,7 +29591,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_DIM_SP zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC); zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); - if (UNEXPECTED(GC_DELREF(obj) == 0)) { + if (UNEXPECTED(GC_DELREF_OBJ(obj) == 0)) { zend_objects_store_del(obj); } } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { @@ -29719,7 +29726,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_DIM_SP if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { zend_object *obj = Z_OBJ_P(object_ptr); - GC_ADDREF(obj); + GC_ADDREF_OBJ(obj); dim = NULL; if (IS_UNUSED == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { dim = ZVAL_UNDEFINED_OP2(); @@ -29737,7 +29744,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_DIM_SP zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC); zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); - if (UNEXPECTED(GC_DELREF(obj) == 0)) { + if (UNEXPECTED(GC_DELREF_OBJ(obj) == 0)) { zend_objects_store_del(obj); } } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { @@ -29872,7 +29879,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_DIM_SP if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { zend_object *obj = Z_OBJ_P(object_ptr); - GC_ADDREF(obj); + GC_ADDREF_OBJ(obj); dim = NULL; if (IS_UNUSED == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { dim = ZVAL_UNDEFINED_OP2(); @@ -29889,7 +29896,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_DIM_SP zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC); - if (UNEXPECTED(GC_DELREF(obj) == 0)) { + if (UNEXPECTED(GC_DELREF_OBJ(obj) == 0)) { zend_objects_store_del(obj); } } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { @@ -30631,7 +30638,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_NEW_SPEC_VAR_ constructor, opline->extended_value, Z_OBJ_P(result)); - Z_ADDREF_P(result); + GC_ADDREF_OBJ(Z_OBJ_P(result)); } call->prev_execute_data = EX(call); @@ -32183,7 +32190,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_DIM_SP if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { zend_object *obj = Z_OBJ_P(object_ptr); - GC_ADDREF(obj); + GC_ADDREF_OBJ(obj); dim = EX_VAR(opline->op2.var); if (IS_CV == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { dim = ZVAL_UNDEFINED_OP2(); @@ -32200,7 +32207,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_DIM_SP zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC); - if (UNEXPECTED(GC_DELREF(obj) == 0)) { + if (UNEXPECTED(GC_DELREF_OBJ(obj) == 0)) { zend_objects_store_del(obj); } } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { @@ -32335,7 +32342,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_DIM_SP if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { zend_object *obj = Z_OBJ_P(object_ptr); - GC_ADDREF(obj); + GC_ADDREF_OBJ(obj); dim = EX_VAR(opline->op2.var); if (IS_CV == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { dim = ZVAL_UNDEFINED_OP2(); @@ -32353,7 +32360,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_DIM_SP zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC); zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); - if (UNEXPECTED(GC_DELREF(obj) == 0)) { + if (UNEXPECTED(GC_DELREF_OBJ(obj) == 0)) { zend_objects_store_del(obj); } } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { @@ -32488,7 +32495,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_DIM_SP if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { zend_object *obj = Z_OBJ_P(object_ptr); - GC_ADDREF(obj); + GC_ADDREF_OBJ(obj); dim = EX_VAR(opline->op2.var); if (IS_CV == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { dim = ZVAL_UNDEFINED_OP2(); @@ -32506,7 +32513,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_DIM_SP zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC); zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); - if (UNEXPECTED(GC_DELREF(obj) == 0)) { + if (UNEXPECTED(GC_DELREF_OBJ(obj) == 0)) { zend_objects_store_del(obj); } } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { @@ -32641,7 +32648,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_DIM_SP if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { zend_object *obj = Z_OBJ_P(object_ptr); - GC_ADDREF(obj); + GC_ADDREF_OBJ(obj); dim = EX_VAR(opline->op2.var); if (IS_CV == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { dim = ZVAL_UNDEFINED_OP2(); @@ -32658,7 +32665,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_DIM_SP zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC); - if (UNEXPECTED(GC_DELREF(obj) == 0)) { + if (UNEXPECTED(GC_DELREF_OBJ(obj) == 0)) { zend_objects_store_del(obj); } } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { @@ -35114,7 +35121,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_I CACHE_POLYMORPHIC_PTR(opline->result.num, called_scope, fbc); } if ((IS_UNUSED & (IS_VAR|IS_TMP_VAR)) && UNEXPECTED(obj != orig_obj)) { - GC_ADDREF(obj); /* For $this pointer */ + GC_ADDREF_OBJ(obj); /* For $this pointer */ if (GC_DELREF(orig_obj) == 0) { zend_objects_store_del(orig_obj); } @@ -35130,7 +35137,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_I call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS; if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_STATIC) != 0)) { - if ((IS_UNUSED & (IS_VAR|IS_TMP_VAR)) && GC_DELREF(obj) == 0) { + if ((IS_UNUSED & (IS_VAR|IS_TMP_VAR)) && GC_DELREF_OBJ(obj) == 0) { zend_objects_store_del(obj); if (UNEXPECTED(EG(exception))) { HANDLE_EXCEPTION(); @@ -35141,7 +35148,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_I call_info = ZEND_CALL_NESTED_FUNCTION; } else if (IS_UNUSED & (IS_VAR|IS_TMP_VAR|IS_CV)) { if (IS_UNUSED == IS_CV) { - GC_ADDREF(obj); /* For $this pointer */ + GC_ADDREF_OBJ(obj); /* For $this pointer */ } /* CV may be changed indirectly (e.g. when it's a reference) */ call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS | ZEND_CALL_RELEASE_THIS; @@ -37298,7 +37305,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INIT_METHOD_C CACHE_POLYMORPHIC_PTR(opline->result.num, called_scope, fbc); } if ((IS_UNUSED & (IS_VAR|IS_TMP_VAR)) && UNEXPECTED(obj != orig_obj)) { - GC_ADDREF(obj); /* For $this pointer */ + GC_ADDREF_OBJ(obj); /* For $this pointer */ if (GC_DELREF(orig_obj) == 0) { zend_objects_store_del(orig_obj); } @@ -37314,7 +37321,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INIT_METHOD_C call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS; if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_STATIC) != 0)) { - if ((IS_UNUSED & (IS_VAR|IS_TMP_VAR)) && GC_DELREF(obj) == 0) { + if ((IS_UNUSED & (IS_VAR|IS_TMP_VAR)) && GC_DELREF_OBJ(obj) == 0) { zend_objects_store_del(obj); if (UNEXPECTED(EG(exception))) { HANDLE_EXCEPTION(); @@ -37325,7 +37332,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INIT_METHOD_C call_info = ZEND_CALL_NESTED_FUNCTION; } else if (IS_UNUSED & (IS_VAR|IS_TMP_VAR|IS_CV)) { if (IS_UNUSED == IS_CV) { - GC_ADDREF(obj); /* For $this pointer */ + GC_ADDREF_OBJ(obj); /* For $this pointer */ } /* CV may be changed indirectly (e.g. when it's a reference) */ call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS | ZEND_CALL_RELEASE_THIS; @@ -38097,7 +38104,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_NEW_SPEC_UNUS constructor, opline->extended_value, Z_OBJ_P(result)); - Z_ADDREF_P(result); + GC_ADDREF_OBJ(Z_OBJ_P(result)); } call->prev_execute_data = EX(call); @@ -38254,7 +38261,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_F zval *result = EX_VAR(opline->result.var); ZVAL_OBJ(result, Z_OBJ(EX(This))); - Z_ADDREF_P(result); + GC_ADDREF_OBJ(Z_OBJ_P(result)); ZEND_VM_NEXT_OPCODE(); } else { ZEND_VM_TAIL_CALL(zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); @@ -39944,7 +39951,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INIT_METHOD_C CACHE_POLYMORPHIC_PTR(opline->result.num, called_scope, fbc); } if ((IS_UNUSED & (IS_VAR|IS_TMP_VAR)) && UNEXPECTED(obj != orig_obj)) { - GC_ADDREF(obj); /* For $this pointer */ + GC_ADDREF_OBJ(obj); /* For $this pointer */ if (GC_DELREF(orig_obj) == 0) { zend_objects_store_del(orig_obj); } @@ -39960,7 +39967,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INIT_METHOD_C call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS; if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_STATIC) != 0)) { - if ((IS_UNUSED & (IS_VAR|IS_TMP_VAR)) && GC_DELREF(obj) == 0) { + if ((IS_UNUSED & (IS_VAR|IS_TMP_VAR)) && GC_DELREF_OBJ(obj) == 0) { zend_objects_store_del(obj); if (UNEXPECTED(EG(exception))) { HANDLE_EXCEPTION(); @@ -39971,7 +39978,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INIT_METHOD_C call_info = ZEND_CALL_NESTED_FUNCTION; } else if (IS_UNUSED & (IS_VAR|IS_TMP_VAR|IS_CV)) { if (IS_UNUSED == IS_CV) { - GC_ADDREF(obj); /* For $this pointer */ + GC_ADDREF_OBJ(obj); /* For $this pointer */ } /* CV may be changed indirectly (e.g. when it's a reference) */ call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS | ZEND_CALL_RELEASE_THIS; @@ -41609,7 +41616,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_YIELD_FROM_SP if (ce == zend_ce_generator) { zend_generator *new_gen = (zend_generator *) Z_OBJ_P(val); - Z_ADDREF_P(val); + GC_ADDREF_OBJ(Z_OBJ_P(val)); if (UNEXPECTED(new_gen->execute_data == NULL)) { zend_throw_error(NULL, "Generator passed to yield from was aborted without proper return and is unable to continue"); @@ -44121,7 +44128,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_DIM_SP if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { zend_object *obj = Z_OBJ_P(object_ptr); - GC_ADDREF(obj); + GC_ADDREF_OBJ(obj); dim = RT_CONSTANT(opline, opline->op2); if (IS_CONST == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { dim = ZVAL_UNDEFINED_OP2(); @@ -44138,7 +44145,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_DIM_SP zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC); - if (UNEXPECTED(GC_DELREF(obj) == 0)) { + if (UNEXPECTED(GC_DELREF_OBJ(obj) == 0)) { zend_objects_store_del(obj); } } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { @@ -44273,7 +44280,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_DIM_SP if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { zend_object *obj = Z_OBJ_P(object_ptr); - GC_ADDREF(obj); + GC_ADDREF_OBJ(obj); dim = RT_CONSTANT(opline, opline->op2); if (IS_CONST == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { dim = ZVAL_UNDEFINED_OP2(); @@ -44291,7 +44298,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_DIM_SP zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC); zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); - if (UNEXPECTED(GC_DELREF(obj) == 0)) { + if (UNEXPECTED(GC_DELREF_OBJ(obj) == 0)) { zend_objects_store_del(obj); } } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { @@ -44426,7 +44433,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_DIM_SP if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { zend_object *obj = Z_OBJ_P(object_ptr); - GC_ADDREF(obj); + GC_ADDREF_OBJ(obj); dim = RT_CONSTANT(opline, opline->op2); if (IS_CONST == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { dim = ZVAL_UNDEFINED_OP2(); @@ -44444,7 +44451,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_DIM_SP zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC); zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); - if (UNEXPECTED(GC_DELREF(obj) == 0)) { + if (UNEXPECTED(GC_DELREF_OBJ(obj) == 0)) { zend_objects_store_del(obj); } } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { @@ -44579,7 +44586,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_DIM_SP if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { zend_object *obj = Z_OBJ_P(object_ptr); - GC_ADDREF(obj); + GC_ADDREF_OBJ(obj); dim = RT_CONSTANT(opline, opline->op2); if (IS_CONST == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { dim = ZVAL_UNDEFINED_OP2(); @@ -44596,7 +44603,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_DIM_SP zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC); - if (UNEXPECTED(GC_DELREF(obj) == 0)) { + if (UNEXPECTED(GC_DELREF_OBJ(obj) == 0)) { zend_objects_store_del(obj); } } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { @@ -45019,7 +45026,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_I CACHE_POLYMORPHIC_PTR(opline->result.num, called_scope, fbc); } if ((IS_CV & (IS_VAR|IS_TMP_VAR)) && UNEXPECTED(obj != orig_obj)) { - GC_ADDREF(obj); /* For $this pointer */ + GC_ADDREF_OBJ(obj); /* For $this pointer */ if (GC_DELREF(orig_obj) == 0) { zend_objects_store_del(orig_obj); } @@ -45035,7 +45042,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_I call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS; if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_STATIC) != 0)) { - if ((IS_CV & (IS_VAR|IS_TMP_VAR)) && GC_DELREF(obj) == 0) { + if ((IS_CV & (IS_VAR|IS_TMP_VAR)) && GC_DELREF_OBJ(obj) == 0) { zend_objects_store_del(obj); if (UNEXPECTED(EG(exception))) { HANDLE_EXCEPTION(); @@ -45046,7 +45053,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_I call_info = ZEND_CALL_NESTED_FUNCTION; } else if (IS_CV & (IS_VAR|IS_TMP_VAR|IS_CV)) { if (IS_CV == IS_CV) { - GC_ADDREF(obj); /* For $this pointer */ + GC_ADDREF_OBJ(obj); /* For $this pointer */ } /* CV may be changed indirectly (e.g. when it's a reference) */ call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS | ZEND_CALL_RELEASE_THIS; @@ -48074,7 +48081,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_DIM_SP if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { zend_object *obj = Z_OBJ_P(object_ptr); - GC_ADDREF(obj); + GC_ADDREF_OBJ(obj); dim = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { dim = ZVAL_UNDEFINED_OP2(); @@ -48091,7 +48098,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_DIM_SP zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC); - if (UNEXPECTED(GC_DELREF(obj) == 0)) { + if (UNEXPECTED(GC_DELREF_OBJ(obj) == 0)) { zend_objects_store_del(obj); } } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { @@ -48226,7 +48233,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_DIM_SP if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { zend_object *obj = Z_OBJ_P(object_ptr); - GC_ADDREF(obj); + GC_ADDREF_OBJ(obj); dim = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { dim = ZVAL_UNDEFINED_OP2(); @@ -48244,7 +48251,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_DIM_SP zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC); zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); - if (UNEXPECTED(GC_DELREF(obj) == 0)) { + if (UNEXPECTED(GC_DELREF_OBJ(obj) == 0)) { zend_objects_store_del(obj); } } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { @@ -48379,7 +48386,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_DIM_SP if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { zend_object *obj = Z_OBJ_P(object_ptr); - GC_ADDREF(obj); + GC_ADDREF_OBJ(obj); dim = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { dim = ZVAL_UNDEFINED_OP2(); @@ -48397,7 +48404,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_DIM_SP zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC); zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); - if (UNEXPECTED(GC_DELREF(obj) == 0)) { + if (UNEXPECTED(GC_DELREF_OBJ(obj) == 0)) { zend_objects_store_del(obj); } } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { @@ -48532,7 +48539,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_DIM_SP if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { zend_object *obj = Z_OBJ_P(object_ptr); - GC_ADDREF(obj); + GC_ADDREF_OBJ(obj); dim = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { dim = ZVAL_UNDEFINED_OP2(); @@ -48549,7 +48556,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_DIM_SP zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC); - if (UNEXPECTED(GC_DELREF(obj) == 0)) { + if (UNEXPECTED(GC_DELREF_OBJ(obj) == 0)) { zend_objects_store_del(obj); } } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { @@ -48914,7 +48921,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INIT_METHOD_C CACHE_POLYMORPHIC_PTR(opline->result.num, called_scope, fbc); } if ((IS_CV & (IS_VAR|IS_TMP_VAR)) && UNEXPECTED(obj != orig_obj)) { - GC_ADDREF(obj); /* For $this pointer */ + GC_ADDREF_OBJ(obj); /* For $this pointer */ if (GC_DELREF(orig_obj) == 0) { zend_objects_store_del(orig_obj); } @@ -48930,7 +48937,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INIT_METHOD_C call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS; if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_STATIC) != 0)) { - if ((IS_CV & (IS_VAR|IS_TMP_VAR)) && GC_DELREF(obj) == 0) { + if ((IS_CV & (IS_VAR|IS_TMP_VAR)) && GC_DELREF_OBJ(obj) == 0) { zend_objects_store_del(obj); if (UNEXPECTED(EG(exception))) { HANDLE_EXCEPTION(); @@ -48941,7 +48948,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INIT_METHOD_C call_info = ZEND_CALL_NESTED_FUNCTION; } else if (IS_CV & (IS_VAR|IS_TMP_VAR|IS_CV)) { if (IS_CV == IS_CV) { - GC_ADDREF(obj); /* For $this pointer */ + GC_ADDREF_OBJ(obj); /* For $this pointer */ } /* CV may be changed indirectly (e.g. when it's a reference) */ call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS | ZEND_CALL_RELEASE_THIS; @@ -50117,7 +50124,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_DIM_SP if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { zend_object *obj = Z_OBJ_P(object_ptr); - GC_ADDREF(obj); + GC_ADDREF_OBJ(obj); dim = NULL; if (IS_UNUSED == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { dim = ZVAL_UNDEFINED_OP2(); @@ -50134,7 +50141,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_DIM_SP zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC); - if (UNEXPECTED(GC_DELREF(obj) == 0)) { + if (UNEXPECTED(GC_DELREF_OBJ(obj) == 0)) { zend_objects_store_del(obj); } } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { @@ -50269,7 +50276,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_DIM_SP if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { zend_object *obj = Z_OBJ_P(object_ptr); - GC_ADDREF(obj); + GC_ADDREF_OBJ(obj); dim = NULL; if (IS_UNUSED == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { dim = ZVAL_UNDEFINED_OP2(); @@ -50287,7 +50294,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_DIM_SP zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC); zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); - if (UNEXPECTED(GC_DELREF(obj) == 0)) { + if (UNEXPECTED(GC_DELREF_OBJ(obj) == 0)) { zend_objects_store_del(obj); } } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { @@ -50422,7 +50429,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_DIM_SP if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { zend_object *obj = Z_OBJ_P(object_ptr); - GC_ADDREF(obj); + GC_ADDREF_OBJ(obj); dim = NULL; if (IS_UNUSED == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { dim = ZVAL_UNDEFINED_OP2(); @@ -50440,7 +50447,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_DIM_SP zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC); zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); - if (UNEXPECTED(GC_DELREF(obj) == 0)) { + if (UNEXPECTED(GC_DELREF_OBJ(obj) == 0)) { zend_objects_store_del(obj); } } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { @@ -50575,7 +50582,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_DIM_SP if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { zend_object *obj = Z_OBJ_P(object_ptr); - GC_ADDREF(obj); + GC_ADDREF_OBJ(obj); dim = NULL; if (IS_UNUSED == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { dim = ZVAL_UNDEFINED_OP2(); @@ -50592,7 +50599,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_DIM_SP zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC); - if (UNEXPECTED(GC_DELREF(obj) == 0)) { + if (UNEXPECTED(GC_DELREF_OBJ(obj) == 0)) { zend_objects_store_del(obj); } } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { @@ -53574,7 +53581,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_DIM_SP if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { zend_object *obj = Z_OBJ_P(object_ptr); - GC_ADDREF(obj); + GC_ADDREF_OBJ(obj); dim = EX_VAR(opline->op2.var); if (IS_CV == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { dim = ZVAL_UNDEFINED_OP2(); @@ -53591,7 +53598,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_DIM_SP zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC); - if (UNEXPECTED(GC_DELREF(obj) == 0)) { + if (UNEXPECTED(GC_DELREF_OBJ(obj) == 0)) { zend_objects_store_del(obj); } } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { @@ -53726,7 +53733,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_DIM_SP if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { zend_object *obj = Z_OBJ_P(object_ptr); - GC_ADDREF(obj); + GC_ADDREF_OBJ(obj); dim = EX_VAR(opline->op2.var); if (IS_CV == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { dim = ZVAL_UNDEFINED_OP2(); @@ -53744,7 +53751,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_DIM_SP zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC); zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); - if (UNEXPECTED(GC_DELREF(obj) == 0)) { + if (UNEXPECTED(GC_DELREF_OBJ(obj) == 0)) { zend_objects_store_del(obj); } } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { @@ -53879,7 +53886,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_DIM_SP if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { zend_object *obj = Z_OBJ_P(object_ptr); - GC_ADDREF(obj); + GC_ADDREF_OBJ(obj); dim = EX_VAR(opline->op2.var); if (IS_CV == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { dim = ZVAL_UNDEFINED_OP2(); @@ -53897,7 +53904,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_DIM_SP zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC); zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); - if (UNEXPECTED(GC_DELREF(obj) == 0)) { + if (UNEXPECTED(GC_DELREF_OBJ(obj) == 0)) { zend_objects_store_del(obj); } } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { @@ -54032,7 +54039,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_DIM_SP if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { zend_object *obj = Z_OBJ_P(object_ptr); - GC_ADDREF(obj); + GC_ADDREF_OBJ(obj); dim = EX_VAR(opline->op2.var); if (IS_CV == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { dim = ZVAL_UNDEFINED_OP2(); @@ -54049,7 +54056,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_DIM_SP zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC); - if (UNEXPECTED(GC_DELREF(obj) == 0)) { + if (UNEXPECTED(GC_DELREF_OBJ(obj) == 0)) { zend_objects_store_del(obj); } } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { @@ -54510,7 +54517,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INIT_METHOD_C CACHE_POLYMORPHIC_PTR(opline->result.num, called_scope, fbc); } if ((IS_CV & (IS_VAR|IS_TMP_VAR)) && UNEXPECTED(obj != orig_obj)) { - GC_ADDREF(obj); /* For $this pointer */ + GC_ADDREF_OBJ(obj); /* For $this pointer */ if (GC_DELREF(orig_obj) == 0) { zend_objects_store_del(orig_obj); } @@ -54526,7 +54533,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INIT_METHOD_C call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS; if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_STATIC) != 0)) { - if ((IS_CV & (IS_VAR|IS_TMP_VAR)) && GC_DELREF(obj) == 0) { + if ((IS_CV & (IS_VAR|IS_TMP_VAR)) && GC_DELREF_OBJ(obj) == 0) { zend_objects_store_del(obj); if (UNEXPECTED(EG(exception))) { HANDLE_EXCEPTION(); @@ -54537,7 +54544,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INIT_METHOD_C call_info = ZEND_CALL_NESTED_FUNCTION; } else if (IS_CV & (IS_VAR|IS_TMP_VAR|IS_CV)) { if (IS_CV == IS_CV) { - GC_ADDREF(obj); /* For $this pointer */ + GC_ADDREF_OBJ(obj); /* For $this pointer */ } /* CV may be changed indirectly (e.g. when it's a reference) */ call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS | ZEND_CALL_RELEASE_THIS; @@ -56751,7 +56758,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_GENERATOR_CREATE_S /* Bug #72523 */ || UNEXPECTED(zend_execute_ex != execute_ex))) { ZEND_ADD_CALL_FLAG_EX(call_info, ZEND_CALL_RELEASE_THIS); - Z_ADDREF(gen_execute_data->This); + GC_ADDREF_OBJ(Z_OBJ(gen_execute_data->This)); } ZEND_ADD_CALL_FLAG_EX(call_info, (ZEND_CALL_TOP_FUNCTION | ZEND_CALL_ALLOCATED | ZEND_CALL_GENERATOR)); Z_TYPE_INFO(gen_execute_data->This) = call_info; @@ -58273,27 +58280,34 @@ static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV zend { zend_atomic_bool_store_ex(&EG(vm_interrupt), false); SAVE_OPLINE(); + bool expected = true; if (zend_atomic_bool_load_ex(&EG(timed_out))) { zend_timeout(); + ZEND_VM_CONTINUE(); } else if (zend_interrupt_function) { zend_interrupt_function(execute_data); - if (EG(exception)) { - /* We have to UNDEF result, because ZEND_HANDLE_EXCEPTION is going to free it */ - const zend_op *throw_op = EG(opline_before_exception); +#ifdef USE_LIBGC + } else if (zend_atomic_bool_compare_exchange_ex(&EG(pending_finalizations), &expected, false)) { + GC_invoke_finalizers(); +#endif + } else { + ZEND_VM_CONTINUE(); + } + if (EG(exception)) { + /* We have to UNDEF result, because ZEND_HANDLE_EXCEPTION is going to free it */ + const zend_op *throw_op = EG(opline_before_exception); - if (throw_op - && throw_op->result_type & (IS_TMP_VAR|IS_VAR) - && throw_op->opcode != ZEND_ADD_ARRAY_ELEMENT - && throw_op->opcode != ZEND_ADD_ARRAY_UNPACK - && throw_op->opcode != ZEND_ROPE_INIT - && throw_op->opcode != ZEND_ROPE_ADD) { - ZVAL_UNDEF(ZEND_CALL_VAR(EG(current_execute_data), throw_op->result.var)); + if (throw_op + && throw_op->result_type & (IS_TMP_VAR|IS_VAR) + && throw_op->opcode != ZEND_ADD_ARRAY_ELEMENT + && throw_op->opcode != ZEND_ADD_ARRAY_UNPACK + && throw_op->opcode != ZEND_ROPE_INIT + && throw_op->opcode != ZEND_ROPE_ADD) { + ZVAL_UNDEF(ZEND_CALL_VAR(EG(current_execute_data), throw_op->result.var)); - } } - ZEND_VM_ENTER(); } - ZEND_VM_CONTINUE(); + ZEND_VM_ENTER(); } static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_FCALL_BY_NAME_SPEC_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { @@ -60155,7 +60169,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_YIELD_FROM_SPEC_CO if (ce == zend_ce_generator) { zend_generator *new_gen = (zend_generator *) Z_OBJ_P(val); - Z_ADDREF_P(val); + GC_ADDREF_OBJ(Z_OBJ_P(val)); if (UNEXPECTED(new_gen->execute_data == NULL)) { zend_throw_error(NULL, "Generator passed to yield from was aborted without proper return and is unable to continue"); @@ -61580,7 +61594,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_ CACHE_POLYMORPHIC_PTR(opline->result.num, called_scope, fbc); } if ((IS_CONST & (IS_VAR|IS_TMP_VAR)) && UNEXPECTED(obj != orig_obj)) { - GC_ADDREF(obj); /* For $this pointer */ + GC_ADDREF_OBJ(obj); /* For $this pointer */ if (GC_DELREF(orig_obj) == 0) { zend_objects_store_del(orig_obj); } @@ -61596,7 +61610,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_ call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS; if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_STATIC) != 0)) { - if ((IS_CONST & (IS_VAR|IS_TMP_VAR)) && GC_DELREF(obj) == 0) { + if ((IS_CONST & (IS_VAR|IS_TMP_VAR)) && GC_DELREF_OBJ(obj) == 0) { zend_objects_store_del(obj); if (UNEXPECTED(EG(exception))) { HANDLE_EXCEPTION(); @@ -61607,7 +61621,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_ call_info = ZEND_CALL_NESTED_FUNCTION; } else if (IS_CONST & (IS_VAR|IS_TMP_VAR|IS_CV)) { if (IS_CONST == IS_CV) { - GC_ADDREF(obj); /* For $this pointer */ + GC_ADDREF_OBJ(obj); /* For $this pointer */ } /* CV may be changed indirectly (e.g. when it's a reference) */ call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS | ZEND_CALL_RELEASE_THIS; @@ -64210,7 +64224,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_ CACHE_POLYMORPHIC_PTR(opline->result.num, called_scope, fbc); } if ((IS_CONST & (IS_VAR|IS_TMP_VAR)) && UNEXPECTED(obj != orig_obj)) { - GC_ADDREF(obj); /* For $this pointer */ + GC_ADDREF_OBJ(obj); /* For $this pointer */ if (GC_DELREF(orig_obj) == 0) { zend_objects_store_del(orig_obj); } @@ -64226,7 +64240,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_ call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS; if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_STATIC) != 0)) { - if ((IS_CONST & (IS_VAR|IS_TMP_VAR)) && GC_DELREF(obj) == 0) { + if ((IS_CONST & (IS_VAR|IS_TMP_VAR)) && GC_DELREF_OBJ(obj) == 0) { zend_objects_store_del(obj); if (UNEXPECTED(EG(exception))) { HANDLE_EXCEPTION(); @@ -64237,7 +64251,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_ call_info = ZEND_CALL_NESTED_FUNCTION; } else if (IS_CONST & (IS_VAR|IS_TMP_VAR|IS_CV)) { if (IS_CONST == IS_CV) { - GC_ADDREF(obj); /* For $this pointer */ + GC_ADDREF_OBJ(obj); /* For $this pointer */ } /* CV may be changed indirectly (e.g. when it's a reference) */ call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS | ZEND_CALL_RELEASE_THIS; @@ -65273,7 +65287,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_NEW_SPEC_CONST_UNU constructor, opline->extended_value, Z_OBJ_P(result)); - Z_ADDREF_P(result); + GC_ADDREF_OBJ(Z_OBJ_P(result)); } call->prev_execute_data = EX(call); @@ -66603,7 +66617,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_ CACHE_POLYMORPHIC_PTR(opline->result.num, called_scope, fbc); } if ((IS_CONST & (IS_VAR|IS_TMP_VAR)) && UNEXPECTED(obj != orig_obj)) { - GC_ADDREF(obj); /* For $this pointer */ + GC_ADDREF_OBJ(obj); /* For $this pointer */ if (GC_DELREF(orig_obj) == 0) { zend_objects_store_del(orig_obj); } @@ -66619,7 +66633,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_ call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS; if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_STATIC) != 0)) { - if ((IS_CONST & (IS_VAR|IS_TMP_VAR)) && GC_DELREF(obj) == 0) { + if ((IS_CONST & (IS_VAR|IS_TMP_VAR)) && GC_DELREF_OBJ(obj) == 0) { zend_objects_store_del(obj); if (UNEXPECTED(EG(exception))) { HANDLE_EXCEPTION(); @@ -66630,7 +66644,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_ call_info = ZEND_CALL_NESTED_FUNCTION; } else if (IS_CONST & (IS_VAR|IS_TMP_VAR|IS_CV)) { if (IS_CONST == IS_CV) { - GC_ADDREF(obj); /* For $this pointer */ + GC_ADDREF_OBJ(obj); /* For $this pointer */ } /* CV may be changed indirectly (e.g. when it's a reference) */ call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS | ZEND_CALL_RELEASE_THIS; @@ -69796,7 +69810,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_YIELD_FROM_SPEC_TM if (ce == zend_ce_generator) { zend_generator *new_gen = (zend_generator *) Z_OBJ_P(val); - Z_ADDREF_P(val); + GC_ADDREF_OBJ(Z_OBJ_P(val)); zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); if (UNEXPECTED(new_gen->execute_data == NULL)) { @@ -71086,7 +71100,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_METHOD_CALL_S CACHE_POLYMORPHIC_PTR(opline->result.num, called_scope, fbc); } if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_TMP_VAR)) && UNEXPECTED(obj != orig_obj)) { - GC_ADDREF(obj); /* For $this pointer */ + GC_ADDREF_OBJ(obj); /* For $this pointer */ if (GC_DELREF(orig_obj) == 0) { zend_objects_store_del(orig_obj); } @@ -71102,7 +71116,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_METHOD_CALL_S call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS; if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_STATIC) != 0)) { - if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_TMP_VAR)) && GC_DELREF(obj) == 0) { + if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_TMP_VAR)) && GC_DELREF_OBJ(obj) == 0) { zend_objects_store_del(obj); if (UNEXPECTED(EG(exception))) { HANDLE_EXCEPTION(); @@ -71113,7 +71127,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_METHOD_CALL_S call_info = ZEND_CALL_NESTED_FUNCTION; } else if ((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_TMP_VAR|IS_CV)) { if ((IS_TMP_VAR|IS_VAR) == IS_CV) { - GC_ADDREF(obj); /* For $this pointer */ + GC_ADDREF_OBJ(obj); /* For $this pointer */ } /* CV may be changed indirectly (e.g. when it's a reference) */ call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS | ZEND_CALL_RELEASE_THIS; @@ -72579,7 +72593,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_METHOD_CALL_S CACHE_POLYMORPHIC_PTR(opline->result.num, called_scope, fbc); } if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_TMP_VAR)) && UNEXPECTED(obj != orig_obj)) { - GC_ADDREF(obj); /* For $this pointer */ + GC_ADDREF_OBJ(obj); /* For $this pointer */ if (GC_DELREF(orig_obj) == 0) { zend_objects_store_del(orig_obj); } @@ -72595,7 +72609,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_METHOD_CALL_S call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS; if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_STATIC) != 0)) { - if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_TMP_VAR)) && GC_DELREF(obj) == 0) { + if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_TMP_VAR)) && GC_DELREF_OBJ(obj) == 0) { zend_objects_store_del(obj); if (UNEXPECTED(EG(exception))) { HANDLE_EXCEPTION(); @@ -72606,7 +72620,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_METHOD_CALL_S call_info = ZEND_CALL_NESTED_FUNCTION; } else if ((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_TMP_VAR|IS_CV)) { if ((IS_TMP_VAR|IS_VAR) == IS_CV) { - GC_ADDREF(obj); /* For $this pointer */ + GC_ADDREF_OBJ(obj); /* For $this pointer */ } /* CV may be changed indirectly (e.g. when it's a reference) */ call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS | ZEND_CALL_RELEASE_THIS; @@ -73886,7 +73900,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_METHOD_CALL_S CACHE_POLYMORPHIC_PTR(opline->result.num, called_scope, fbc); } if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_TMP_VAR)) && UNEXPECTED(obj != orig_obj)) { - GC_ADDREF(obj); /* For $this pointer */ + GC_ADDREF_OBJ(obj); /* For $this pointer */ if (GC_DELREF(orig_obj) == 0) { zend_objects_store_del(orig_obj); } @@ -73902,7 +73916,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_METHOD_CALL_S call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS; if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_STATIC) != 0)) { - if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_TMP_VAR)) && GC_DELREF(obj) == 0) { + if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_TMP_VAR)) && GC_DELREF_OBJ(obj) == 0) { zend_objects_store_del(obj); if (UNEXPECTED(EG(exception))) { HANDLE_EXCEPTION(); @@ -73913,7 +73927,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_METHOD_CALL_S call_info = ZEND_CALL_NESTED_FUNCTION; } else if ((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_TMP_VAR|IS_CV)) { if ((IS_TMP_VAR|IS_VAR) == IS_CV) { - GC_ADDREF(obj); /* For $this pointer */ + GC_ADDREF_OBJ(obj); /* For $this pointer */ } /* CV may be changed indirectly (e.g. when it's a reference) */ call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS | ZEND_CALL_RELEASE_THIS; @@ -78914,7 +78928,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_DIM_SPEC_VA if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { zend_object *obj = Z_OBJ_P(object_ptr); - GC_ADDREF(obj); + GC_ADDREF_OBJ(obj); dim = RT_CONSTANT(opline, opline->op2); if (IS_CONST == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { dim = ZVAL_UNDEFINED_OP2(); @@ -78931,7 +78945,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_DIM_SPEC_VA zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC); - if (UNEXPECTED(GC_DELREF(obj) == 0)) { + if (UNEXPECTED(GC_DELREF_OBJ(obj) == 0)) { zend_objects_store_del(obj); } } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { @@ -79066,7 +79080,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_DIM_SPEC_VA if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { zend_object *obj = Z_OBJ_P(object_ptr); - GC_ADDREF(obj); + GC_ADDREF_OBJ(obj); dim = RT_CONSTANT(opline, opline->op2); if (IS_CONST == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { dim = ZVAL_UNDEFINED_OP2(); @@ -79084,7 +79098,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_DIM_SPEC_VA zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC); zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); - if (UNEXPECTED(GC_DELREF(obj) == 0)) { + if (UNEXPECTED(GC_DELREF_OBJ(obj) == 0)) { zend_objects_store_del(obj); } } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { @@ -79219,7 +79233,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_DIM_SPEC_VA if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { zend_object *obj = Z_OBJ_P(object_ptr); - GC_ADDREF(obj); + GC_ADDREF_OBJ(obj); dim = RT_CONSTANT(opline, opline->op2); if (IS_CONST == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { dim = ZVAL_UNDEFINED_OP2(); @@ -79237,7 +79251,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_DIM_SPEC_VA zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC); zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); - if (UNEXPECTED(GC_DELREF(obj) == 0)) { + if (UNEXPECTED(GC_DELREF_OBJ(obj) == 0)) { zend_objects_store_del(obj); } } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { @@ -79372,7 +79386,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_DIM_SPEC_VA if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { zend_object *obj = Z_OBJ_P(object_ptr); - GC_ADDREF(obj); + GC_ADDREF_OBJ(obj); dim = RT_CONSTANT(opline, opline->op2); if (IS_CONST == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { dim = ZVAL_UNDEFINED_OP2(); @@ -79389,7 +79403,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_DIM_SPEC_VA zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC); - if (UNEXPECTED(GC_DELREF(obj) == 0)) { + if (UNEXPECTED(GC_DELREF_OBJ(obj) == 0)) { zend_objects_store_del(obj); } } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { @@ -81920,7 +81934,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_DIM_SPEC_VA if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { zend_object *obj = Z_OBJ_P(object_ptr); - GC_ADDREF(obj); + GC_ADDREF_OBJ(obj); dim = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { dim = ZVAL_UNDEFINED_OP2(); @@ -81937,7 +81951,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_DIM_SPEC_VA zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC); - if (UNEXPECTED(GC_DELREF(obj) == 0)) { + if (UNEXPECTED(GC_DELREF_OBJ(obj) == 0)) { zend_objects_store_del(obj); } } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { @@ -82072,7 +82086,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_DIM_SPEC_VA if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { zend_object *obj = Z_OBJ_P(object_ptr); - GC_ADDREF(obj); + GC_ADDREF_OBJ(obj); dim = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { dim = ZVAL_UNDEFINED_OP2(); @@ -82090,7 +82104,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_DIM_SPEC_VA zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC); zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); - if (UNEXPECTED(GC_DELREF(obj) == 0)) { + if (UNEXPECTED(GC_DELREF_OBJ(obj) == 0)) { zend_objects_store_del(obj); } } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { @@ -82225,7 +82239,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_DIM_SPEC_VA if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { zend_object *obj = Z_OBJ_P(object_ptr); - GC_ADDREF(obj); + GC_ADDREF_OBJ(obj); dim = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { dim = ZVAL_UNDEFINED_OP2(); @@ -82243,7 +82257,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_DIM_SPEC_VA zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC); zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); - if (UNEXPECTED(GC_DELREF(obj) == 0)) { + if (UNEXPECTED(GC_DELREF_OBJ(obj) == 0)) { zend_objects_store_del(obj); } } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { @@ -82378,7 +82392,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_DIM_SPEC_VA if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { zend_object *obj = Z_OBJ_P(object_ptr); - GC_ADDREF(obj); + GC_ADDREF_OBJ(obj); dim = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { dim = ZVAL_UNDEFINED_OP2(); @@ -82395,7 +82409,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_DIM_SPEC_VA zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC); - if (UNEXPECTED(GC_DELREF(obj) == 0)) { + if (UNEXPECTED(GC_DELREF_OBJ(obj) == 0)) { zend_objects_store_del(obj); } } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { @@ -83505,7 +83519,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_DIM_SPEC_VA if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { zend_object *obj = Z_OBJ_P(object_ptr); - GC_ADDREF(obj); + GC_ADDREF_OBJ(obj); dim = NULL; if (IS_UNUSED == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { dim = ZVAL_UNDEFINED_OP2(); @@ -83522,7 +83536,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_DIM_SPEC_VA zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC); - if (UNEXPECTED(GC_DELREF(obj) == 0)) { + if (UNEXPECTED(GC_DELREF_OBJ(obj) == 0)) { zend_objects_store_del(obj); } } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { @@ -83657,7 +83671,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_DIM_SPEC_VA if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { zend_object *obj = Z_OBJ_P(object_ptr); - GC_ADDREF(obj); + GC_ADDREF_OBJ(obj); dim = NULL; if (IS_UNUSED == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { dim = ZVAL_UNDEFINED_OP2(); @@ -83675,7 +83689,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_DIM_SPEC_VA zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC); zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); - if (UNEXPECTED(GC_DELREF(obj) == 0)) { + if (UNEXPECTED(GC_DELREF_OBJ(obj) == 0)) { zend_objects_store_del(obj); } } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { @@ -83810,7 +83824,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_DIM_SPEC_VA if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { zend_object *obj = Z_OBJ_P(object_ptr); - GC_ADDREF(obj); + GC_ADDREF_OBJ(obj); dim = NULL; if (IS_UNUSED == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { dim = ZVAL_UNDEFINED_OP2(); @@ -83828,7 +83842,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_DIM_SPEC_VA zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC); zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); - if (UNEXPECTED(GC_DELREF(obj) == 0)) { + if (UNEXPECTED(GC_DELREF_OBJ(obj) == 0)) { zend_objects_store_del(obj); } } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { @@ -83963,7 +83977,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_DIM_SPEC_VA if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { zend_object *obj = Z_OBJ_P(object_ptr); - GC_ADDREF(obj); + GC_ADDREF_OBJ(obj); dim = NULL; if (IS_UNUSED == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { dim = ZVAL_UNDEFINED_OP2(); @@ -83980,7 +83994,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_DIM_SPEC_VA zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC); - if (UNEXPECTED(GC_DELREF(obj) == 0)) { + if (UNEXPECTED(GC_DELREF_OBJ(obj) == 0)) { zend_objects_store_del(obj); } } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { @@ -84722,7 +84736,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_NEW_SPEC_VAR_UNUSE constructor, opline->extended_value, Z_OBJ_P(result)); - Z_ADDREF_P(result); + GC_ADDREF_OBJ(Z_OBJ_P(result)); } call->prev_execute_data = EX(call); @@ -86274,7 +86288,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_DIM_SPEC_VA if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { zend_object *obj = Z_OBJ_P(object_ptr); - GC_ADDREF(obj); + GC_ADDREF_OBJ(obj); dim = EX_VAR(opline->op2.var); if (IS_CV == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { dim = ZVAL_UNDEFINED_OP2(); @@ -86291,7 +86305,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_DIM_SPEC_VA zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC); - if (UNEXPECTED(GC_DELREF(obj) == 0)) { + if (UNEXPECTED(GC_DELREF_OBJ(obj) == 0)) { zend_objects_store_del(obj); } } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { @@ -86426,7 +86440,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_DIM_SPEC_VA if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { zend_object *obj = Z_OBJ_P(object_ptr); - GC_ADDREF(obj); + GC_ADDREF_OBJ(obj); dim = EX_VAR(opline->op2.var); if (IS_CV == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { dim = ZVAL_UNDEFINED_OP2(); @@ -86444,7 +86458,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_DIM_SPEC_VA zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC); zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); - if (UNEXPECTED(GC_DELREF(obj) == 0)) { + if (UNEXPECTED(GC_DELREF_OBJ(obj) == 0)) { zend_objects_store_del(obj); } } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { @@ -86579,7 +86593,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_DIM_SPEC_VA if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { zend_object *obj = Z_OBJ_P(object_ptr); - GC_ADDREF(obj); + GC_ADDREF_OBJ(obj); dim = EX_VAR(opline->op2.var); if (IS_CV == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { dim = ZVAL_UNDEFINED_OP2(); @@ -86597,7 +86611,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_DIM_SPEC_VA zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC); zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); - if (UNEXPECTED(GC_DELREF(obj) == 0)) { + if (UNEXPECTED(GC_DELREF_OBJ(obj) == 0)) { zend_objects_store_del(obj); } } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { @@ -86732,7 +86746,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_DIM_SPEC_VA if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { zend_object *obj = Z_OBJ_P(object_ptr); - GC_ADDREF(obj); + GC_ADDREF_OBJ(obj); dim = EX_VAR(opline->op2.var); if (IS_CV == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { dim = ZVAL_UNDEFINED_OP2(); @@ -86749,7 +86763,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_DIM_SPEC_VA zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC); - if (UNEXPECTED(GC_DELREF(obj) == 0)) { + if (UNEXPECTED(GC_DELREF_OBJ(obj) == 0)) { zend_objects_store_del(obj); } } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { @@ -89205,7 +89219,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_M CACHE_POLYMORPHIC_PTR(opline->result.num, called_scope, fbc); } if ((IS_UNUSED & (IS_VAR|IS_TMP_VAR)) && UNEXPECTED(obj != orig_obj)) { - GC_ADDREF(obj); /* For $this pointer */ + GC_ADDREF_OBJ(obj); /* For $this pointer */ if (GC_DELREF(orig_obj) == 0) { zend_objects_store_del(orig_obj); } @@ -89221,7 +89235,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_M call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS; if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_STATIC) != 0)) { - if ((IS_UNUSED & (IS_VAR|IS_TMP_VAR)) && GC_DELREF(obj) == 0) { + if ((IS_UNUSED & (IS_VAR|IS_TMP_VAR)) && GC_DELREF_OBJ(obj) == 0) { zend_objects_store_del(obj); if (UNEXPECTED(EG(exception))) { HANDLE_EXCEPTION(); @@ -89232,7 +89246,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_M call_info = ZEND_CALL_NESTED_FUNCTION; } else if (IS_UNUSED & (IS_VAR|IS_TMP_VAR|IS_CV)) { if (IS_UNUSED == IS_CV) { - GC_ADDREF(obj); /* For $this pointer */ + GC_ADDREF_OBJ(obj); /* For $this pointer */ } /* CV may be changed indirectly (e.g. when it's a reference) */ call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS | ZEND_CALL_RELEASE_THIS; @@ -91389,7 +91403,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_METHOD_CALL_S CACHE_POLYMORPHIC_PTR(opline->result.num, called_scope, fbc); } if ((IS_UNUSED & (IS_VAR|IS_TMP_VAR)) && UNEXPECTED(obj != orig_obj)) { - GC_ADDREF(obj); /* For $this pointer */ + GC_ADDREF_OBJ(obj); /* For $this pointer */ if (GC_DELREF(orig_obj) == 0) { zend_objects_store_del(orig_obj); } @@ -91405,7 +91419,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_METHOD_CALL_S call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS; if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_STATIC) != 0)) { - if ((IS_UNUSED & (IS_VAR|IS_TMP_VAR)) && GC_DELREF(obj) == 0) { + if ((IS_UNUSED & (IS_VAR|IS_TMP_VAR)) && GC_DELREF_OBJ(obj) == 0) { zend_objects_store_del(obj); if (UNEXPECTED(EG(exception))) { HANDLE_EXCEPTION(); @@ -91416,7 +91430,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_METHOD_CALL_S call_info = ZEND_CALL_NESTED_FUNCTION; } else if (IS_UNUSED & (IS_VAR|IS_TMP_VAR|IS_CV)) { if (IS_UNUSED == IS_CV) { - GC_ADDREF(obj); /* For $this pointer */ + GC_ADDREF_OBJ(obj); /* For $this pointer */ } /* CV may be changed indirectly (e.g. when it's a reference) */ call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS | ZEND_CALL_RELEASE_THIS; @@ -92188,7 +92202,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_NEW_SPEC_UNUSED_UN constructor, opline->extended_value, Z_OBJ_P(result)); - Z_ADDREF_P(result); + GC_ADDREF_OBJ(Z_OBJ_P(result)); } call->prev_execute_data = EX(call); @@ -92345,7 +92359,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_ zval *result = EX_VAR(opline->result.var); ZVAL_OBJ(result, Z_OBJ(EX(This))); - Z_ADDREF_P(result); + GC_ADDREF_OBJ(Z_OBJ_P(result)); ZEND_VM_NEXT_OPCODE(); } else { ZEND_VM_TAIL_CALL(zend_this_not_in_object_context_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); @@ -94035,7 +94049,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_METHOD_CALL_S CACHE_POLYMORPHIC_PTR(opline->result.num, called_scope, fbc); } if ((IS_UNUSED & (IS_VAR|IS_TMP_VAR)) && UNEXPECTED(obj != orig_obj)) { - GC_ADDREF(obj); /* For $this pointer */ + GC_ADDREF_OBJ(obj); /* For $this pointer */ if (GC_DELREF(orig_obj) == 0) { zend_objects_store_del(orig_obj); } @@ -94051,7 +94065,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_METHOD_CALL_S call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS; if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_STATIC) != 0)) { - if ((IS_UNUSED & (IS_VAR|IS_TMP_VAR)) && GC_DELREF(obj) == 0) { + if ((IS_UNUSED & (IS_VAR|IS_TMP_VAR)) && GC_DELREF_OBJ(obj) == 0) { zend_objects_store_del(obj); if (UNEXPECTED(EG(exception))) { HANDLE_EXCEPTION(); @@ -94062,7 +94076,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_METHOD_CALL_S call_info = ZEND_CALL_NESTED_FUNCTION; } else if (IS_UNUSED & (IS_VAR|IS_TMP_VAR|IS_CV)) { if (IS_UNUSED == IS_CV) { - GC_ADDREF(obj); /* For $this pointer */ + GC_ADDREF_OBJ(obj); /* For $this pointer */ } /* CV may be changed indirectly (e.g. when it's a reference) */ call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS | ZEND_CALL_RELEASE_THIS; @@ -95700,7 +95714,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_YIELD_FROM_SPEC_CV if (ce == zend_ce_generator) { zend_generator *new_gen = (zend_generator *) Z_OBJ_P(val); - Z_ADDREF_P(val); + GC_ADDREF_OBJ(Z_OBJ_P(val)); if (UNEXPECTED(new_gen->execute_data == NULL)) { zend_throw_error(NULL, "Generator passed to yield from was aborted without proper return and is unable to continue"); @@ -98212,7 +98226,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_DIM_SPEC_CV if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { zend_object *obj = Z_OBJ_P(object_ptr); - GC_ADDREF(obj); + GC_ADDREF_OBJ(obj); dim = RT_CONSTANT(opline, opline->op2); if (IS_CONST == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { dim = ZVAL_UNDEFINED_OP2(); @@ -98229,7 +98243,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_DIM_SPEC_CV zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC); - if (UNEXPECTED(GC_DELREF(obj) == 0)) { + if (UNEXPECTED(GC_DELREF_OBJ(obj) == 0)) { zend_objects_store_del(obj); } } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { @@ -98364,7 +98378,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_DIM_SPEC_CV if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { zend_object *obj = Z_OBJ_P(object_ptr); - GC_ADDREF(obj); + GC_ADDREF_OBJ(obj); dim = RT_CONSTANT(opline, opline->op2); if (IS_CONST == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { dim = ZVAL_UNDEFINED_OP2(); @@ -98382,7 +98396,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_DIM_SPEC_CV zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC); zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); - if (UNEXPECTED(GC_DELREF(obj) == 0)) { + if (UNEXPECTED(GC_DELREF_OBJ(obj) == 0)) { zend_objects_store_del(obj); } } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { @@ -98517,7 +98531,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_DIM_SPEC_CV if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { zend_object *obj = Z_OBJ_P(object_ptr); - GC_ADDREF(obj); + GC_ADDREF_OBJ(obj); dim = RT_CONSTANT(opline, opline->op2); if (IS_CONST == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { dim = ZVAL_UNDEFINED_OP2(); @@ -98535,7 +98549,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_DIM_SPEC_CV zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC); zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); - if (UNEXPECTED(GC_DELREF(obj) == 0)) { + if (UNEXPECTED(GC_DELREF_OBJ(obj) == 0)) { zend_objects_store_del(obj); } } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { @@ -98670,7 +98684,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_DIM_SPEC_CV if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { zend_object *obj = Z_OBJ_P(object_ptr); - GC_ADDREF(obj); + GC_ADDREF_OBJ(obj); dim = RT_CONSTANT(opline, opline->op2); if (IS_CONST == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { dim = ZVAL_UNDEFINED_OP2(); @@ -98687,7 +98701,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_DIM_SPEC_CV zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC); - if (UNEXPECTED(GC_DELREF(obj) == 0)) { + if (UNEXPECTED(GC_DELREF_OBJ(obj) == 0)) { zend_objects_store_del(obj); } } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { @@ -99110,7 +99124,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_M CACHE_POLYMORPHIC_PTR(opline->result.num, called_scope, fbc); } if ((IS_CV & (IS_VAR|IS_TMP_VAR)) && UNEXPECTED(obj != orig_obj)) { - GC_ADDREF(obj); /* For $this pointer */ + GC_ADDREF_OBJ(obj); /* For $this pointer */ if (GC_DELREF(orig_obj) == 0) { zend_objects_store_del(orig_obj); } @@ -99126,7 +99140,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_M call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS; if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_STATIC) != 0)) { - if ((IS_CV & (IS_VAR|IS_TMP_VAR)) && GC_DELREF(obj) == 0) { + if ((IS_CV & (IS_VAR|IS_TMP_VAR)) && GC_DELREF_OBJ(obj) == 0) { zend_objects_store_del(obj); if (UNEXPECTED(EG(exception))) { HANDLE_EXCEPTION(); @@ -99137,7 +99151,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_M call_info = ZEND_CALL_NESTED_FUNCTION; } else if (IS_CV & (IS_VAR|IS_TMP_VAR|IS_CV)) { if (IS_CV == IS_CV) { - GC_ADDREF(obj); /* For $this pointer */ + GC_ADDREF_OBJ(obj); /* For $this pointer */ } /* CV may be changed indirectly (e.g. when it's a reference) */ call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS | ZEND_CALL_RELEASE_THIS; @@ -102165,7 +102179,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_DIM_SPEC_CV if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { zend_object *obj = Z_OBJ_P(object_ptr); - GC_ADDREF(obj); + GC_ADDREF_OBJ(obj); dim = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { dim = ZVAL_UNDEFINED_OP2(); @@ -102182,7 +102196,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_DIM_SPEC_CV zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC); - if (UNEXPECTED(GC_DELREF(obj) == 0)) { + if (UNEXPECTED(GC_DELREF_OBJ(obj) == 0)) { zend_objects_store_del(obj); } } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { @@ -102317,7 +102331,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_DIM_SPEC_CV if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { zend_object *obj = Z_OBJ_P(object_ptr); - GC_ADDREF(obj); + GC_ADDREF_OBJ(obj); dim = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { dim = ZVAL_UNDEFINED_OP2(); @@ -102335,7 +102349,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_DIM_SPEC_CV zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC); zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); - if (UNEXPECTED(GC_DELREF(obj) == 0)) { + if (UNEXPECTED(GC_DELREF_OBJ(obj) == 0)) { zend_objects_store_del(obj); } } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { @@ -102470,7 +102484,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_DIM_SPEC_CV if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { zend_object *obj = Z_OBJ_P(object_ptr); - GC_ADDREF(obj); + GC_ADDREF_OBJ(obj); dim = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { dim = ZVAL_UNDEFINED_OP2(); @@ -102488,7 +102502,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_DIM_SPEC_CV zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC); zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); - if (UNEXPECTED(GC_DELREF(obj) == 0)) { + if (UNEXPECTED(GC_DELREF_OBJ(obj) == 0)) { zend_objects_store_del(obj); } } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { @@ -102623,7 +102637,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_DIM_SPEC_CV if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { zend_object *obj = Z_OBJ_P(object_ptr); - GC_ADDREF(obj); + GC_ADDREF_OBJ(obj); dim = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { dim = ZVAL_UNDEFINED_OP2(); @@ -102640,7 +102654,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_DIM_SPEC_CV zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC); - if (UNEXPECTED(GC_DELREF(obj) == 0)) { + if (UNEXPECTED(GC_DELREF_OBJ(obj) == 0)) { zend_objects_store_del(obj); } } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { @@ -103005,7 +103019,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_METHOD_CALL_S CACHE_POLYMORPHIC_PTR(opline->result.num, called_scope, fbc); } if ((IS_CV & (IS_VAR|IS_TMP_VAR)) && UNEXPECTED(obj != orig_obj)) { - GC_ADDREF(obj); /* For $this pointer */ + GC_ADDREF_OBJ(obj); /* For $this pointer */ if (GC_DELREF(orig_obj) == 0) { zend_objects_store_del(orig_obj); } @@ -103021,7 +103035,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_METHOD_CALL_S call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS; if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_STATIC) != 0)) { - if ((IS_CV & (IS_VAR|IS_TMP_VAR)) && GC_DELREF(obj) == 0) { + if ((IS_CV & (IS_VAR|IS_TMP_VAR)) && GC_DELREF_OBJ(obj) == 0) { zend_objects_store_del(obj); if (UNEXPECTED(EG(exception))) { HANDLE_EXCEPTION(); @@ -103032,7 +103046,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_METHOD_CALL_S call_info = ZEND_CALL_NESTED_FUNCTION; } else if (IS_CV & (IS_VAR|IS_TMP_VAR|IS_CV)) { if (IS_CV == IS_CV) { - GC_ADDREF(obj); /* For $this pointer */ + GC_ADDREF_OBJ(obj); /* For $this pointer */ } /* CV may be changed indirectly (e.g. when it's a reference) */ call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS | ZEND_CALL_RELEASE_THIS; @@ -104108,7 +104122,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_DIM_SPEC_CV if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { zend_object *obj = Z_OBJ_P(object_ptr); - GC_ADDREF(obj); + GC_ADDREF_OBJ(obj); dim = NULL; if (IS_UNUSED == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { dim = ZVAL_UNDEFINED_OP2(); @@ -104125,7 +104139,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_DIM_SPEC_CV zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC); - if (UNEXPECTED(GC_DELREF(obj) == 0)) { + if (UNEXPECTED(GC_DELREF_OBJ(obj) == 0)) { zend_objects_store_del(obj); } } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { @@ -104260,7 +104274,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_DIM_SPEC_CV if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { zend_object *obj = Z_OBJ_P(object_ptr); - GC_ADDREF(obj); + GC_ADDREF_OBJ(obj); dim = NULL; if (IS_UNUSED == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { dim = ZVAL_UNDEFINED_OP2(); @@ -104278,7 +104292,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_DIM_SPEC_CV zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC); zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); - if (UNEXPECTED(GC_DELREF(obj) == 0)) { + if (UNEXPECTED(GC_DELREF_OBJ(obj) == 0)) { zend_objects_store_del(obj); } } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { @@ -104413,7 +104427,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_DIM_SPEC_CV if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { zend_object *obj = Z_OBJ_P(object_ptr); - GC_ADDREF(obj); + GC_ADDREF_OBJ(obj); dim = NULL; if (IS_UNUSED == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { dim = ZVAL_UNDEFINED_OP2(); @@ -104431,7 +104445,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_DIM_SPEC_CV zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC); zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); - if (UNEXPECTED(GC_DELREF(obj) == 0)) { + if (UNEXPECTED(GC_DELREF_OBJ(obj) == 0)) { zend_objects_store_del(obj); } } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { @@ -104566,7 +104580,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_DIM_SPEC_CV if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { zend_object *obj = Z_OBJ_P(object_ptr); - GC_ADDREF(obj); + GC_ADDREF_OBJ(obj); dim = NULL; if (IS_UNUSED == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { dim = ZVAL_UNDEFINED_OP2(); @@ -104583,7 +104597,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_DIM_SPEC_CV zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC); - if (UNEXPECTED(GC_DELREF(obj) == 0)) { + if (UNEXPECTED(GC_DELREF_OBJ(obj) == 0)) { zend_objects_store_del(obj); } } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { @@ -107565,7 +107579,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_DIM_SPEC_CV if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { zend_object *obj = Z_OBJ_P(object_ptr); - GC_ADDREF(obj); + GC_ADDREF_OBJ(obj); dim = EX_VAR(opline->op2.var); if (IS_CV == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { dim = ZVAL_UNDEFINED_OP2(); @@ -107582,7 +107596,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_DIM_SPEC_CV zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC); - if (UNEXPECTED(GC_DELREF(obj) == 0)) { + if (UNEXPECTED(GC_DELREF_OBJ(obj) == 0)) { zend_objects_store_del(obj); } } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { @@ -107717,7 +107731,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_DIM_SPEC_CV if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { zend_object *obj = Z_OBJ_P(object_ptr); - GC_ADDREF(obj); + GC_ADDREF_OBJ(obj); dim = EX_VAR(opline->op2.var); if (IS_CV == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { dim = ZVAL_UNDEFINED_OP2(); @@ -107735,7 +107749,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_DIM_SPEC_CV zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC); zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); - if (UNEXPECTED(GC_DELREF(obj) == 0)) { + if (UNEXPECTED(GC_DELREF_OBJ(obj) == 0)) { zend_objects_store_del(obj); } } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { @@ -107870,7 +107884,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_DIM_SPEC_CV if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { zend_object *obj = Z_OBJ_P(object_ptr); - GC_ADDREF(obj); + GC_ADDREF_OBJ(obj); dim = EX_VAR(opline->op2.var); if (IS_CV == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { dim = ZVAL_UNDEFINED_OP2(); @@ -107888,7 +107902,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_DIM_SPEC_CV zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC); zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); - if (UNEXPECTED(GC_DELREF(obj) == 0)) { + if (UNEXPECTED(GC_DELREF_OBJ(obj) == 0)) { zend_objects_store_del(obj); } } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { @@ -108023,7 +108037,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_DIM_SPEC_CV if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { zend_object *obj = Z_OBJ_P(object_ptr); - GC_ADDREF(obj); + GC_ADDREF_OBJ(obj); dim = EX_VAR(opline->op2.var); if (IS_CV == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { dim = ZVAL_UNDEFINED_OP2(); @@ -108040,7 +108054,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_DIM_SPEC_CV zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC); - if (UNEXPECTED(GC_DELREF(obj) == 0)) { + if (UNEXPECTED(GC_DELREF_OBJ(obj) == 0)) { zend_objects_store_del(obj); } } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { @@ -108501,7 +108515,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_METHOD_CALL_S CACHE_POLYMORPHIC_PTR(opline->result.num, called_scope, fbc); } if ((IS_CV & (IS_VAR|IS_TMP_VAR)) && UNEXPECTED(obj != orig_obj)) { - GC_ADDREF(obj); /* For $this pointer */ + GC_ADDREF_OBJ(obj); /* For $this pointer */ if (GC_DELREF(orig_obj) == 0) { zend_objects_store_del(orig_obj); } @@ -108517,7 +108531,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_METHOD_CALL_S call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS; if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_STATIC) != 0)) { - if ((IS_CV & (IS_VAR|IS_TMP_VAR)) && GC_DELREF(obj) == 0) { + if ((IS_CV & (IS_VAR|IS_TMP_VAR)) && GC_DELREF_OBJ(obj) == 0) { zend_objects_store_del(obj); if (UNEXPECTED(EG(exception))) { HANDLE_EXCEPTION(); @@ -108528,7 +108542,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_METHOD_CALL_S call_info = ZEND_CALL_NESTED_FUNCTION; } else if (IS_CV & (IS_VAR|IS_TMP_VAR|IS_CV)) { if (IS_CV == IS_CV) { - GC_ADDREF(obj); /* For $this pointer */ + GC_ADDREF_OBJ(obj); /* For $this pointer */ } /* CV may be changed indirectly (e.g. when it's a reference) */ call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS | ZEND_CALL_RELEASE_THIS; diff --git a/Zend/zend_weakrefs.c b/Zend/zend_weakrefs.c index 0c729755ff445..d6ea85468e112 100644 --- a/Zend/zend_weakrefs.c +++ b/Zend/zend_weakrefs.c @@ -99,6 +99,10 @@ static void zend_weakref_unref(zend_object *object, void *tagged_ptr) { static void zend_weakref_register(zend_object *object, void *payload) { GC_ADD_FLAGS(object, IS_OBJ_WEAKLY_REFERENCED); +#if USE_LIBGC + zend_objects_store_set_weakref_finalizer(object); +#endif + zend_ulong obj_key = zend_object_to_weakref_key(object); zval *zv = zend_hash_index_lookup(&EG(weakrefs), obj_key); if (Z_TYPE_P(zv) == IS_NULL) { @@ -483,7 +487,7 @@ static HashTable *zend_weakmap_get_properties_for(zend_object *object, zend_prop zval pair; array_init(&pair); - GC_ADDREF(obj); + GC_ADDREF_OBJ(obj); add_assoc_object(&pair, "key", obj); Z_TRY_ADDREF_P(val); add_assoc_zval(&pair, "value", val); diff --git a/Zend/zend_weakrefs.h b/Zend/zend_weakrefs.h index 00d4fbcc6bc4c..85f539ec9a651 100644 --- a/Zend/zend_weakrefs.h +++ b/Zend/zend_weakrefs.h @@ -60,12 +60,12 @@ static zend_always_inline void zend_weakrefs_hash_destroy(HashTable *ht) { static zend_always_inline zend_ulong zend_object_to_weakref_key(const zend_object *object) { ZEND_ASSERT(((uintptr_t)object) % ZEND_MM_ALIGNMENT == 0); - return ((uintptr_t) object) >> ZEND_MM_ALIGNMENT_LOG2; + return MASK_PTR(((uintptr_t) object) >> ZEND_MM_ALIGNMENT_LOG2); } static zend_always_inline zend_object *zend_weakref_key_to_object(zend_ulong key) { - return (zend_object *) (((uintptr_t) key) << ZEND_MM_ALIGNMENT_LOG2); + return (zend_object *) UNMASK_PTR(((uintptr_t) key) << ZEND_MM_ALIGNMENT_LOG2); } HashTable *zend_weakmap_get_gc(zend_object *object, zval **table, int *n); diff --git a/configure.ac b/configure.ac index 633244962d8d4..4c2cc2cd2177f 100644 --- a/configure.ac +++ b/configure.ac @@ -1733,7 +1733,7 @@ PHP_ADD_SOURCES([Zend], m4_normalize([ Optimizer/zend_inference.c Optimizer/zend_optimizer.c Optimizer/zend_ssa.c - zend_alloc.c + zend_alloc_libgc.c zend_API.c zend_ast.c zend_atomic.c diff --git a/ext/curl/interface.c b/ext/curl/interface.c index 53098c64eb03c..1dda6d2d35006 100644 --- a/ext/curl/interface.c +++ b/ext/curl/interface.c @@ -547,7 +547,7 @@ static size_t curl_write(char *data, size_t size, size_t nmemb, void *ctx) zval argv[2]; zval retval; - GC_ADDREF(&ch->std); + GC_ADDREF_OBJ(&ch->std); ZVAL_OBJ(&argv[0], &ch->std); ZVAL_STRINGL(&argv[1], data, length); @@ -578,7 +578,7 @@ static int curl_fnmatch(void *ctx, const char *pattern, const char *string) zval argv[3]; zval retval; - GC_ADDREF(&ch->std); + GC_ADDREF_OBJ(&ch->std); ZVAL_OBJ(&argv[0], &ch->std); ZVAL_STRING(&argv[1], pattern); ZVAL_STRING(&argv[2], string); @@ -613,7 +613,7 @@ static size_t curl_progress(void *clientp, double dltotal, double dlnow, double zval args[5]; zval retval; - GC_ADDREF(&ch->std); + GC_ADDREF_OBJ(&ch->std); ZVAL_OBJ(&args[0], &ch->std); ZVAL_LONG(&args[1], (zend_long)dltotal); ZVAL_LONG(&args[2], (zend_long)dlnow); @@ -651,7 +651,7 @@ static size_t curl_xferinfo(void *clientp, curl_off_t dltotal, curl_off_t dlnow, zval argv[5]; zval retval; - GC_ADDREF(&ch->std); + GC_ADDREF_OBJ(&ch->std); ZVAL_OBJ(&argv[0], &ch->std); ZVAL_LONG(&argv[1], dltotal); ZVAL_LONG(&argv[2], dlnow); @@ -696,7 +696,7 @@ static int curl_prereqfunction(void *clientp, char *conn_primary_ip, char *conn_ zval args[5]; zval retval; - GC_ADDREF(&ch->std); + GC_ADDREF_OBJ(&ch->std); ZVAL_OBJ(&args[0], &ch->std); ZVAL_STRING(&args[1], conn_primary_ip); ZVAL_STRING(&args[2], conn_local_ip); @@ -743,7 +743,7 @@ static int curl_ssh_hostkeyfunction(void *clientp, int keytype, const char *key, zval args[4]; zval retval; - GC_ADDREF(&ch->std); + GC_ADDREF_OBJ(&ch->std); ZVAL_OBJ(&args[0], &ch->std); ZVAL_LONG(&args[1], keytype); ZVAL_STRINGL(&args[2], key, keylen); @@ -791,7 +791,7 @@ static size_t curl_read(char *data, size_t size, size_t nmemb, void *ctx) zval argv[3]; zval retval; - GC_ADDREF(&ch->std); + GC_ADDREF_OBJ(&ch->std); ZVAL_OBJ(&argv[0], &ch->std); if (read_handler->res) { GC_ADDREF(read_handler->res); @@ -849,7 +849,7 @@ static size_t curl_write_header(char *data, size_t size, size_t nmemb, void *ctx zval argv[2]; zval retval; - GC_ADDREF(&ch->std); + GC_ADDREF_OBJ(&ch->std); ZVAL_OBJ(&argv[0], &ch->std); ZVAL_STRINGL(&argv[1], data, length); @@ -904,7 +904,7 @@ static int curl_debug(CURL *handle, curl_infotype type, char *data, size_t size, zval args[3]; - GC_ADDREF(&ch->std); + GC_ADDREF_OBJ(&ch->std); ZVAL_OBJ(&args[0], &ch->std); ZVAL_LONG(&args[1], type); ZVAL_STRINGL(&args[2], data, size); @@ -2269,7 +2269,7 @@ static zend_result _php_curl_setopt(php_curl *ch, zend_long option, zval *zvalue OBJ_RELEASE(&ch->share->std); } - GC_ADDREF(&sh->std); + GC_ADDREF_OBJ(&sh->std); ch->share = sh; } break; diff --git a/ext/dom/element.c b/ext/dom/element.c index dbab931301599..cfb3cd14b5b6d 100644 --- a/ext/dom/element.c +++ b/ext/dom/element.c @@ -671,7 +671,7 @@ PHP_METHOD(DOMElement, getAttributeNode) if (attrp->type == XML_NAMESPACE_DECL) { xmlNsPtr original = (xmlNsPtr) attrp; /* Keep parent alive, because we're a fake child. */ - GC_ADDREF(&intern->std); + GC_ADDREF_OBJ(&intern->std); (void) php_dom_create_fake_namespace_decl(nodep, original, return_value, intern); } else { DOM_RET_OBJ((xmlNodePtr) attrp, intern); @@ -1237,7 +1237,7 @@ PHP_METHOD(DOMElement, getAttributeNodeNS) nsptr = dom_get_nsdecl(elemp, BAD_CAST name); if (nsptr != NULL) { /* Keep parent alive, because we're a fake child. */ - GC_ADDREF(&intern->std); + GC_ADDREF_OBJ(&intern->std); (void) php_dom_create_fake_namespace_decl(elemp, nsptr, return_value, intern); } else { RETURN_NULL(); diff --git a/ext/dom/obj_map.c b/ext/dom/obj_map.c index 9c017c4d11a6b..8ad34e18df0b2 100644 --- a/ext/dom/obj_map.c +++ b/ext/dom/obj_map.c @@ -238,7 +238,7 @@ static void dom_map_cache_obj(dom_nnodemap_object *map, xmlNodePtr itemnode, zen * This also means we have to manually refcount the objects here, and remove the reference count * in reset_objmap_cache() and the destructor. */ dom_object *cached_obj = Z_DOMOBJ_P(return_value); - GC_ADDREF(&cached_obj->std); + GC_ADDREF_OBJ(&cached_obj->std); /* If the tag is stale, all cached data is useless. Otherwise only the cached object is useless. */ if (php_dom_is_cache_tag_stale_from_node(&map->cache_tag, itemnode)) { php_dom_mark_cache_tag_up_to_date_from_node(&map->cache_tag, itemnode); @@ -433,7 +433,7 @@ void php_dom_create_obj_map(dom_object *basenode, dom_object *intern, xmlHashTab ZEND_ASSERT(basenode != NULL); - GC_ADDREF(&basenode->std); + GC_ADDREF_OBJ(&basenode->std); xmlDocPtr doc = basenode->document ? basenode->document->ptr : NULL; diff --git a/ext/dom/php_dom.c b/ext/dom/php_dom.c index 32eaaf8c2b606..554bf5e6674a4 100644 --- a/ext/dom/php_dom.c +++ b/ext/dom/php_dom.c @@ -714,7 +714,7 @@ static zend_object *dom_object_namespace_node_clone_obj(zend_object *zobject) if (intern->parent_intern) { clone_intern->parent_intern = intern->parent_intern; - GC_ADDREF(&clone_intern->parent_intern->std); + GC_ADDREF_OBJ(&clone_intern->parent_intern->std); } dom_update_refcount_after_clone(&intern->dom, original_node, &clone_intern->dom, cloned_node); diff --git a/ext/ffi/ffi.c b/ext/ffi/ffi.c index 10fc11f52e70f..659a0c7ac52ef 100644 --- a/ext/ffi/ffi.c +++ b/ext/ffi/ffi.c @@ -605,7 +605,7 @@ static zend_always_inline void zend_ffi_cdata_to_zval(zend_ffi_cdata *cdata, voi cdata = zend_ffi_cdata_to_zval_slow_ptr(ptr, type, flags); } } else { - GC_ADDREF(&cdata->std); + GC_ADDREF_OBJ(&cdata->std); } ZVAL_OBJ(rv, &cdata->std); return; @@ -621,7 +621,7 @@ static zend_always_inline void zend_ffi_cdata_to_zval(zend_ffi_cdata *cdata, voi cdata = zend_ffi_cdata_to_zval_slow(ptr, type, flags); } } else { - GC_ADDREF(&cdata->std); + GC_ADDREF_OBJ(&cdata->std); } ZVAL_OBJ(rv, &cdata->std); } diff --git a/ext/intl/common/common_enum.cpp b/ext/intl/common/common_enum.cpp index 8cf9796717f4e..5160cdc275960 100644 --- a/ext/intl/common/common_enum.cpp +++ b/ext/intl/common/common_enum.cpp @@ -199,7 +199,7 @@ static zend_object_iterator *IntlIterator_get_iterator( return NULL; } - GC_ADDREF(&ii->iterator->std); + GC_ADDREF_OBJ(&ii->iterator->std); return ii->iterator; } diff --git a/ext/opcache/jit/zend_jit_helpers.c b/ext/opcache/jit/zend_jit_helpers.c index ce48d10223412..a51db1253904f 100644 --- a/ext/opcache/jit/zend_jit_helpers.c +++ b/ext/opcache/jit/zend_jit_helpers.c @@ -173,12 +173,12 @@ static zend_function* ZEND_FASTCALL zend_jit_find_method_tmp_helper(zend_object fbc = zend_jit_find_method_helper(obj, function_name, obj_ptr); if (!fbc) { - if (GC_DELREF(obj) == 0) { + if (GC_DELREF_OBJ(obj) == 0) { zend_objects_store_del(obj); } } else if (obj != *obj_ptr) { GC_ADDREF(*obj_ptr); - if (GC_DELREF(obj) == 0) { + if (GC_DELREF_OBJ(obj) == 0) { zend_objects_store_del(obj); } } @@ -282,7 +282,7 @@ static zend_execute_data* ZEND_FASTCALL zend_jit_push_static_method_call_frame_t { zend_class_entry *scope = obj->ce; - if (GC_DELREF(obj) == 0) { + if (GC_DELREF_OBJ(obj) == 0) { zend_objects_store_del(obj); if (UNEXPECTED(EG(exception))) { return NULL; @@ -1335,7 +1335,7 @@ static void ZEND_FASTCALL zend_jit_fetch_dim_obj_r_helper(zval *container, zval zval *retval; zend_object *obj = Z_OBJ_P(container); - GC_ADDREF(obj); + GC_ADDREF_OBJ(obj); if (UNEXPECTED(Z_TYPE_P(dim) == IS_UNDEF)) { zend_jit_undefined_op_helper(EG(current_execute_data)->opline->op2.var); dim = &EG(uninitialized_zval); @@ -1352,7 +1352,7 @@ static void ZEND_FASTCALL zend_jit_fetch_dim_obj_r_helper(zval *container, zval } else { ZVAL_NULL(result); } - if (UNEXPECTED(GC_DELREF(obj) == 0)) { + if (UNEXPECTED(GC_DELREF_OBJ(obj) == 0)) { zend_objects_store_del(obj); } } @@ -1362,7 +1362,7 @@ static void ZEND_FASTCALL zend_jit_fetch_dim_obj_is_helper(zval *container, zval zval *retval; zend_object *obj = Z_OBJ_P(container); - GC_ADDREF(obj); + GC_ADDREF_OBJ(obj); if (UNEXPECTED(Z_TYPE_P(dim) == IS_UNDEF)) { zend_jit_undefined_op_helper(EG(current_execute_data)->opline->op2.var); dim = &EG(uninitialized_zval); @@ -1379,7 +1379,7 @@ static void ZEND_FASTCALL zend_jit_fetch_dim_obj_is_helper(zval *container, zval } else { ZVAL_NULL(result); } - if (UNEXPECTED(GC_DELREF(obj) == 0)) { + if (UNEXPECTED(GC_DELREF_OBJ(obj) == 0)) { zend_objects_store_del(obj); } } @@ -1535,7 +1535,7 @@ static zend_always_inline void ZEND_FASTCALL zend_jit_fetch_dim_obj_helper(zval if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { zend_object *obj = Z_OBJ_P(object_ptr); - GC_ADDREF(obj); + GC_ADDREF_OBJ(obj); if (dim && UNEXPECTED(Z_ISUNDEF_P(dim))) { const zend_op *opline = EG(current_execute_data)->opline; zend_jit_undefined_op_helper(opline->op2.var); @@ -1568,7 +1568,7 @@ static zend_always_inline void ZEND_FASTCALL zend_jit_fetch_dim_obj_helper(zval ZEND_ASSERT(EG(exception) && "read_dimension() returned NULL without exception"); ZVAL_UNDEF(result); } - if (UNEXPECTED(GC_DELREF(obj) == 0)) { + if (UNEXPECTED(GC_DELREF_OBJ(obj) == 0)) { zend_objects_store_del(obj); } } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { @@ -1640,7 +1640,7 @@ static void ZEND_FASTCALL zend_jit_assign_dim_helper(zval *object_ptr, zval *dim if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { zend_object *obj = Z_OBJ_P(object_ptr); - GC_ADDREF(obj); + GC_ADDREF_OBJ(obj); if (dim && UNEXPECTED(Z_TYPE_P(dim) == IS_UNDEF)) { const zend_op *opline = EG(current_execute_data)->opline; zend_jit_undefined_op_helper(opline->op2.var); @@ -1664,7 +1664,7 @@ static void ZEND_FASTCALL zend_jit_assign_dim_helper(zval *object_ptr, zval *dim ZVAL_UNDEF(result); } } - if (UNEXPECTED(GC_DELREF(obj) == 0)) { + if (UNEXPECTED(GC_DELREF_OBJ(obj) == 0)) { zend_objects_store_del(obj); } return; @@ -1733,7 +1733,7 @@ static void ZEND_FASTCALL zend_jit_assign_dim_op_helper(zval *container, zval *d zval *z; zval rv, res; - GC_ADDREF(obj); + GC_ADDREF_OBJ(obj); if (dim && UNEXPECTED(Z_ISUNDEF_P(dim))) { const zend_op *opline = EG(current_execute_data)->opline; zend_jit_undefined_op_helper(opline->op2.var); @@ -1752,10 +1752,10 @@ static void ZEND_FASTCALL zend_jit_assign_dim_op_helper(zval *container, zval *d zval_ptr_dtor(&res); } else { /* Exception is thrown in this case */ - GC_DELREF(obj); + GC_DELREF_OBJ(obj); return; } - if (UNEXPECTED(GC_DELREF(obj) == 0)) { + if (UNEXPECTED(GC_DELREF_OBJ(obj) == 0)) { zend_objects_store_del(obj); //??? if (retval) { //??? ZVAL_NULL(retval); @@ -2863,7 +2863,7 @@ static zend_never_inline void _zend_jit_assign_op_overloaded_property(zend_objec zval *z; zval rv, res; - GC_ADDREF(object); + GC_ADDREF_OBJ(object); z = object->handlers->read_property(object, name, BP_VAR_R, cache_slot, &rv); if (UNEXPECTED(EG(exception))) { OBJ_RELEASE(object); diff --git a/ext/opcache/jit/zend_jit_ir.c b/ext/opcache/jit/zend_jit_ir.c index 57f7e189e6c41..aab05ae2a7cbe 100644 --- a/ext/opcache/jit/zend_jit_ir.c +++ b/ext/opcache/jit/zend_jit_ir.c @@ -1801,10 +1801,12 @@ static void jit_ZVAL_DTOR(zend_jit_ctx *jit, ir_ref ref, uint32_t op_info, const } return; } else if (type == IS_OBJECT) { - if (opline) { - jit_SET_EX_OPLINE(jit, opline); + if (IS_OBJECT_EX & (IS_TYPE_REFCOUNTED << Z_TYPE_FLAGS_SHIFT)) { + if (opline) { + jit_SET_EX_OPLINE(jit, opline); + } + ir_CALL_1(IR_VOID, ir_CONST_FC_FUNC(zend_objects_store_del), ref); } - ir_CALL_1(IR_VOID, ir_CONST_FC_FUNC(zend_objects_store_del), ref); return; } } @@ -1902,10 +1904,14 @@ static void jit_FREE_OP(zend_jit_ctx *jit, static void jit_OBJ_RELEASE(zend_jit_ctx *jit, ir_ref ref) { + if (!(IS_OBJECT_EX & (IS_TYPE_REFCOUNTED << Z_TYPE_FLAGS_SHIFT))) { + return; + } + ir_ref end_inputs = IR_UNUSED; ir_ref if_not_zero, if_may_not_leak; - // JIT: if (GC_DELREF(obj) == 0) { + // JIT: if (GC_DELREF_OBJ(obj) == 0) { if_not_zero = ir_IF(jit_GC_DELREF(jit, ref)); ir_IF_FALSE(if_not_zero); @@ -8620,7 +8626,7 @@ static int zend_jit_push_call_frame(zend_jit_ctx *jit, const zend_op *opline, co } } else { if (opline->op1_type == IS_CV) { - // JIT: GC_ADDREF(obj); + // JIT: GC_ADDREF_OBJ(obj); jit_GC_ADDREF(jit, this_ref); } diff --git a/ext/opcache/jit/zend_jit_trace.c b/ext/opcache/jit/zend_jit_trace.c index 66bb380c23d8d..3c272b428613d 100644 --- a/ext/opcache/jit/zend_jit_trace.c +++ b/ext/opcache/jit/zend_jit_trace.c @@ -8679,7 +8679,7 @@ int ZEND_FASTCALL zend_jit_trace_exit(uint32_t exit_num, zend_jit_registers_buf } else if (STACK_FLAGS(stack, i) == ZREG_THIS) { zend_object *obj = Z_OBJ(EX(This)); - GC_ADDREF(obj); + GC_ADDREF_OBJ(obj); ZVAL_OBJ(EX_VAR_NUM(i), obj); } else if (STACK_FLAGS(stack, i) == ZREG_ZVAL_ADDREF) { Z_TRY_ADDREF_P(EX_VAR_NUM(i)); diff --git a/ext/pdo/pdo_dbh.c b/ext/pdo/pdo_dbh.c index 1bdfcd935cfd1..2a487d7126a89 100644 --- a/ext/pdo/pdo_dbh.c +++ b/ext/pdo/pdo_dbh.c @@ -657,7 +657,7 @@ PHP_METHOD(PDO, prepare) stmt->default_fetch_type = dbh->default_fetch_type; stmt->dbh = dbh; /* give it a reference to me */ - GC_ADDREF(&dbh_obj->std); + GC_ADDREF_OBJ(&dbh_obj->std); stmt->database_object_handle = &dbh_obj->std; if (dbh->methods->preparer(dbh, statement, stmt, options)) { @@ -1221,7 +1221,7 @@ PHP_METHOD(PDO, query) stmt->default_fetch_type = dbh->default_fetch_type; stmt->dbh = dbh; /* give it a reference to me */ - GC_ADDREF(&dbh_obj->std); + GC_ADDREF_OBJ(&dbh_obj->std); stmt->database_object_handle = &dbh_obj->std; if (dbh->methods->preparer(dbh, statement, stmt, NULL)) { diff --git a/ext/pdo/pdo_stmt.c b/ext/pdo/pdo_stmt.c index 697940d94260d..d401317d25ab9 100644 --- a/ext/pdo/pdo_stmt.c +++ b/ext/pdo/pdo_stmt.c @@ -214,8 +214,8 @@ static void pdo_get_lazy_object(pdo_stmt_t *stmt, zval *return_value) /* {{{ */ zend_object_std_init(&row->std, pdo_row_ce); object_properties_init(&row->std, pdo_row_ce); stmt->lazy_object_ref = &row->std; - GC_ADDREF(&stmt->std); - GC_DELREF(&row->std); + GC_ADDREF_OBJ(&stmt->std); + GC_DELREF_OBJ(&row->std); } ZVAL_OBJ_COPY(return_value, stmt->lazy_object_ref); } diff --git a/ext/pgsql/pgsql.c b/ext/pgsql/pgsql.c index d97d0faa1a4b2..86ac60af0b10e 100644 --- a/ext/pgsql/pgsql.c +++ b/ext/pgsql/pgsql.c @@ -296,7 +296,7 @@ static zend_string *_php_pgsql_trim_message(const char *message) static void php_pgsql_set_default_link(zend_object *obj) { - GC_ADDREF(obj); + GC_ADDREF_OBJ(obj); if (PGG(default_link) != NULL) { zend_object_release(PGG(default_link)); diff --git a/ext/session/session.c b/ext/session/session.c index 66912fb1016c6..ab35b553e65f4 100644 --- a/ext/session/session.c +++ b/ext/session/session.c @@ -2025,7 +2025,7 @@ static inline void set_user_save_handler_ini(void) { #define SESSION_SET_USER_HANDLER_OO(struct_name, zstr_method_name) \ array_init_size(&PS(mod_user_names).struct_name, 2); \ - Z_ADDREF_P(obj); \ + GC_ADDREF_OBJ(Z_OBJ_P(obj)); \ add_next_index_zval(&PS(mod_user_names).struct_name, obj); \ add_next_index_str(&PS(mod_user_names).struct_name, zstr_method_name); @@ -2034,7 +2034,7 @@ static inline void set_user_save_handler_ini(void) { zval_ptr_dtor(&PS(mod_user_names).struct_name); \ } \ array_init_size(&PS(mod_user_names).struct_name, 2); \ - Z_ADDREF_P(obj); \ + GC_ADDREF_OBJ(Z_OBJ_P(obj)); \ add_next_index_zval(&PS(mod_user_names).struct_name, obj); \ add_next_index_str(&PS(mod_user_names).struct_name, zend_string_init(method_name, strlen(method_name), false)); diff --git a/ext/spl/spl_iterators.c b/ext/spl/spl_iterators.c index 1ae4dae1eaa35..1574b01aa6683 100644 --- a/ext/spl/spl_iterators.c +++ b/ext/spl/spl_iterators.c @@ -594,7 +594,7 @@ static void spl_recursive_it_it_construct(INTERNAL_FUNCTION_PARAMETERS, zend_cla } iterator = &aggregate_retval; } else { - Z_ADDREF_P(iterator); + GC_ADDREF_OBJ(Z_OBJ_P(iterator)); } break; } diff --git a/ext/spl/spl_observer.c b/ext/spl/spl_observer.c index 540e5c2c0ff94..3e000f0f56990 100644 --- a/ext/spl/spl_observer.c +++ b/ext/spl/spl_observer.c @@ -137,7 +137,7 @@ static spl_SplObjectStorageElement *spl_object_storage_create_element(zend_objec { spl_SplObjectStorageElement *pelement = emalloc(sizeof(spl_SplObjectStorageElement)); pelement->obj = obj; - GC_ADDREF(obj); + GC_ADDREF_OBJ(obj); if (inf) { ZVAL_COPY(&pelement->inf, inf); } else { @@ -206,7 +206,7 @@ static spl_SplObjectStorageElement *spl_object_storage_attach(spl_SplObjectStora } element.obj = obj; - GC_ADDREF(obj); + GC_ADDREF_OBJ(obj); if (inf) { ZVAL_COPY(&element.inf, inf); } else { diff --git a/ext/standard/var.c b/ext/standard/var.c index 1c2b0eb164a1c..fbb8d6ccc2373 100644 --- a/ext/standard/var.c +++ b/ext/standard/var.c @@ -735,10 +735,12 @@ static inline zend_long php_add_var_hash(php_serialize_data_t data, zval *var, b /* pass */ } else if (Z_TYPE_P(var) != IS_OBJECT) { return 0; +#ifndef USE_LIBGC } else if (!in_rcn_array && Z_REFCOUNT_P(var) == 1 && (Z_OBJ_P(var)->properties == NULL || GC_REFCOUNT(Z_OBJ_P(var)->properties) == 1)) { return 0; +#endif } /* References to objects are treated as if the reference didn't exist */ @@ -768,7 +770,7 @@ static inline zend_long php_add_var_hash(php_serialize_data_t data, zval *var, b * stored at the numeric value of the pointer + 1, which cannot be the location * of another zend_refcounted structure. */ zend_hash_index_add_new(&data->ht, key + 1, var); - Z_ADDREF_P(var); + Z_TRY_ADDREF_P(var); return 0; } diff --git a/main/main.c b/main/main.c index a48dd14b7f287..86759c082940e 100644 --- a/main/main.c +++ b/main/main.c @@ -418,7 +418,7 @@ static void php_binary_init(void) { char *binary_location = NULL; #ifdef PHP_WIN32 - binary_location = (char *)pemalloc(MAXPATHLEN, 1); + binary_location = (char *)pemalloc_atomic(MAXPATHLEN, 1); if (GetModuleFileName(0, binary_location, MAXPATHLEN) == 0) { pefree(binary_location, 1); binary_location = NULL; @@ -1915,6 +1915,8 @@ zend_result php_request_startup(void) SG(sapi_started) = 1; + prepare_memory_manager(); + return retval; } /* }}} */ diff --git a/sapi/cgi/cgi_main.c b/sapi/cgi/cgi_main.c index 6db96a43ac97b..2959e2a287407 100644 --- a/sapi/cgi/cgi_main.c +++ b/sapi/cgi/cgi_main.c @@ -1749,6 +1749,11 @@ int main(int argc, char *argv[]) char *query_string; int skip_getopt = 0; +#ifdef USE_LIBGC + /* Must be called before any GC_malloc() */ + init_memory_manager(); +#endif + #if defined(SIGPIPE) && defined(SIG_IGN) signal(SIGPIPE, SIG_IGN); /* ignore SIGPIPE in standalone mode so that sockets created via fsockopen() diff --git a/sapi/cli/php_cli.c b/sapi/cli/php_cli.c index e212a0f71a23d..56b9cbd665bb7 100644 --- a/sapi/cli/php_cli.c +++ b/sapi/cli/php_cli.c @@ -1200,6 +1200,11 @@ int main(int argc, char *argv[]) BOOL using_wide_argv = 0; #endif +#ifdef USE_LIBGC + /* Must be called before any GC_malloc() */ + init_memory_manager(); +#endif + int c; int exit_status = SUCCESS; int module_started = 0, sapi_started = 0;