summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Zend/zend_compile.h16
-rw-r--r--Zend/zend_execute.c2
-rw-r--r--Zend/zend_execute_API.c6
-rw-r--r--Zend/zend_globals.h4
4 files changed, 23 insertions, 5 deletions
diff --git a/Zend/zend_compile.h b/Zend/zend_compile.h
index 1e17e34d30..95ad06e4a3 100644
--- a/Zend/zend_compile.h
+++ b/Zend/zend_compile.h
@@ -568,7 +568,21 @@ int zendlex(znode *zendlval CLS_DC);
#define PZVAL_IS_REF(z) ((z)->is_ref)
#define PZVAL_LOCK(z) ((z)->refcount++)
-#define PZVAL_UNLOCK(z) ((z)->refcount--)
+#define PZVAL_UNLOCK(z) { ((z)->refcount--); \
+ if (!(z)->refcount) { \
+ EG(garbage)[EG(garbage_ptr)++] = (z); \
+ if (EG(garbage_ptr) == 4) { \
+ zval_dtor(EG(garbage)[0]); \
+ efree(EG(garbage)[0]); \
+ zval_dtor(EG(garbage)[1]); \
+ efree(EG(garbage)[1]); \
+ EG(garbage)[0] = EG(garbage)[2]; \
+ EG(garbage)[1] = EG(garbage)[3]; \
+ EG(garbage_ptr) -= 2; \
+ } \
+ } \
+ }
+
#define SELECTIVE_PZVAL_LOCK(pzv, pzn) if (!((pzn)->u.EA.type & EXT_TYPE_UNUSED)) { PZVAL_LOCK(pzv); }
#endif /* _COMPILE_H */
diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c
index c93f8e056a..9fda4a6485 100644
--- a/Zend/zend_execute.c
+++ b/Zend/zend_execute.c
@@ -1508,7 +1508,6 @@ do_fcall_common:
EG(opline_ptr) = &opline;
EG(active_op_array) = op_array;
EG(return_value)=original_return_value;
- EG(destroying_function_symbol_table) = 1;
if (EG(symtable_cache_ptr)>=EG(symtable_cache_limit)) {
zend_hash_destroy(function_state.function_symbol_table);
efree(function_state.function_symbol_table);
@@ -1516,7 +1515,6 @@ do_fcall_common:
*(++EG(symtable_cache_ptr)) = function_state.function_symbol_table;
zend_hash_clean(*EG(symtable_cache_ptr));
}
- EG(destroying_function_symbol_table) = 0;
EG(active_symbol_table) = calling_symbol_table;
} else { /* ZEND_OVERLOADED_FUNCTION */
call_overloaded_function(opline->extended_value, &Ts[opline->result.u.var].tmp_var, &EG(regular_list), &EG(persistent_list) ELS_CC);
diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c
index c9f0abebee..4be3f58808 100644
--- a/Zend/zend_execute_API.c
+++ b/Zend/zend_execute_API.c
@@ -89,7 +89,6 @@ void init_executor(CLS_D ELS_DC)
EG(error_zval).refcount = 1;
EG(error_zval).is_ref=0;
EG(error_zval_ptr)=&EG(error_zval);
- EG(destroying_function_symbol_table) = 0;
zend_ptr_stack_init(&EG(arg_types_stack));
zend_stack_init(&EG(overloaded_objects_stack));
/* destroys stack frame, therefore makes core dumps worthless */
@@ -115,6 +114,7 @@ void init_executor(CLS_D ELS_DC)
zend_llist_apply(&zend_extensions, (void (*)(void *)) zend_extension_activator);
EG(opline_ptr) = NULL;
+ EG(garbage_ptr) = 0;
}
@@ -144,6 +144,10 @@ void shutdown_executor(ELS_D)
#if ZEND_DEBUG
signal(SIGSEGV, original_sigsegv_handler);
#endif
+ while (EG(garbage_ptr)--) {
+ zval_dtor(EG(garbage)[EG(garbage_ptr)]);
+ efree(EG(garbage)[EG(garbage_ptr)]);
+ }
}
diff --git a/Zend/zend_globals.h b/Zend/zend_globals.h
index 5e9d1f4d81..ea740e107d 100644
--- a/Zend/zend_globals.h
+++ b/Zend/zend_globals.h
@@ -138,7 +138,6 @@ struct _zend_executor_globals {
HashTable *zend_constants; /* constants table */
long precision;
- zend_bool destroying_function_symbol_table;
/* for extended information support */
zend_bool no_extensions;
@@ -151,6 +150,9 @@ struct _zend_executor_globals {
int (*unary_op)(zval *result, zval *op1);
int (*binary_op)(zval *result, zval *op1, zval *op2);
+ zval *garbage[4];
+ int garbage_ptr;
+
void *reserved[ZEND_MAX_RESERVED_RESOURCES];
#if SUPPORT_INTERACTIVE
int interactive;