mirror of
https://github.com/php/php-src.git
synced 2024-09-21 18:07:23 +00:00
Step 1 in nuking the garbage collector:
- Change the hash destructor to return int - Don't kill the bucket on hash_destroy if the destructor returns 0
This commit is contained in:
parent
db1e0bc820
commit
81d901b14d
12
Zend/zend.c
12
Zend/zend.c
@ -203,7 +203,7 @@ static void register_standard_class()
|
|||||||
zend_standard_class_def.name = zend_strndup("stdClass", zend_standard_class_def.name_length);
|
zend_standard_class_def.name = zend_strndup("stdClass", zend_standard_class_def.name_length);
|
||||||
zend_standard_class_def.parent = NULL;
|
zend_standard_class_def.parent = NULL;
|
||||||
zend_hash_init(&zend_standard_class_def.default_properties, 0, NULL, PVAL_PTR_DTOR, 1);
|
zend_hash_init(&zend_standard_class_def.default_properties, 0, NULL, PVAL_PTR_DTOR, 1);
|
||||||
zend_hash_init(&zend_standard_class_def.function_table, 0, NULL, (void (*)(void *)) destroy_zend_function, 1);
|
zend_hash_init(&zend_standard_class_def.function_table, 0, NULL, ZEND_FUNCTION_DTOR, 1);
|
||||||
zend_standard_class_def.handle_function_call = NULL;
|
zend_standard_class_def.handle_function_call = NULL;
|
||||||
zend_standard_class_def.handle_property_get = NULL;
|
zend_standard_class_def.handle_property_get = NULL;
|
||||||
zend_standard_class_def.handle_property_set = NULL;
|
zend_standard_class_def.handle_property_set = NULL;
|
||||||
@ -220,11 +220,11 @@ static void compiler_globals_ctor(zend_compiler_globals *compiler_globals)
|
|||||||
zend_class_entry tmp_class;
|
zend_class_entry tmp_class;
|
||||||
|
|
||||||
compiler_globals->function_table = (HashTable *) malloc(sizeof(HashTable));
|
compiler_globals->function_table = (HashTable *) malloc(sizeof(HashTable));
|
||||||
zend_hash_init(compiler_globals->function_table, 100, NULL, (void (*)(void *)) destroy_zend_function, 1);
|
zend_hash_init(compiler_globals->function_table, 100, NULL, ZEND_FUNCTION_DTOR, 1);
|
||||||
zend_hash_copy(compiler_globals->function_table, global_function_table, NULL, &tmp_func, sizeof(zend_function));
|
zend_hash_copy(compiler_globals->function_table, global_function_table, NULL, &tmp_func, sizeof(zend_function));
|
||||||
|
|
||||||
compiler_globals->class_table = (HashTable *) malloc(sizeof(HashTable));
|
compiler_globals->class_table = (HashTable *) malloc(sizeof(HashTable));
|
||||||
zend_hash_init(compiler_globals->class_table, 10, NULL, (void (*)(void *)) destroy_zend_class, 1);
|
zend_hash_init(compiler_globals->class_table, 10, NULL, ZEND_CLASS_DTOR, 1);
|
||||||
zend_hash_copy(compiler_globals->class_table, global_class_table, zend_class_add_ref, &tmp_class, sizeof(zend_class_entry));
|
zend_hash_copy(compiler_globals->class_table, global_class_table, zend_class_add_ref, &tmp_class, sizeof(zend_class_entry));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -303,10 +303,10 @@ int zend_startup(zend_utility_functions *utility_functions, char **extensions)
|
|||||||
#endif
|
#endif
|
||||||
GLOBAL_FUNCTION_TABLE = (HashTable *) malloc(sizeof(HashTable));
|
GLOBAL_FUNCTION_TABLE = (HashTable *) malloc(sizeof(HashTable));
|
||||||
GLOBAL_CLASS_TABLE = (HashTable *) malloc(sizeof(HashTable));
|
GLOBAL_CLASS_TABLE = (HashTable *) malloc(sizeof(HashTable));
|
||||||
zend_hash_init(GLOBAL_FUNCTION_TABLE, 100, NULL, (void (*)(void *)) destroy_zend_function, 1);
|
zend_hash_init(GLOBAL_FUNCTION_TABLE, 100, NULL, ZEND_FUNCTION_DTOR, 1);
|
||||||
zend_hash_init(GLOBAL_CLASS_TABLE, 10, NULL, (void (*)(void *)) destroy_zend_class, 1);
|
zend_hash_init(GLOBAL_CLASS_TABLE, 10, NULL, ZEND_CLASS_DTOR, 1);
|
||||||
register_standard_class();
|
register_standard_class();
|
||||||
zend_hash_init(&module_registry, 50, NULL, (void (*)(void *)) module_destructor, 1);
|
zend_hash_init(&module_registry, 50, NULL, ZEND_MODULE_DTOR, 1);
|
||||||
zend_hash_init(&list_destructors, 50, NULL, NULL, 1);
|
zend_hash_init(&list_destructors, 50, NULL, NULL, 1);
|
||||||
|
|
||||||
#ifdef ZTS
|
#ifdef ZTS
|
||||||
|
@ -767,7 +767,7 @@ ZEND_API zend_class_entry *register_internal_class(zend_class_entry *class_entry
|
|||||||
class_entry->refcount = (int *) malloc(sizeof(int));
|
class_entry->refcount = (int *) malloc(sizeof(int));
|
||||||
*class_entry->refcount = 1;
|
*class_entry->refcount = 1;
|
||||||
zend_hash_init(&class_entry->default_properties, 0, NULL, PVAL_PTR_DTOR, 1);
|
zend_hash_init(&class_entry->default_properties, 0, NULL, PVAL_PTR_DTOR, 1);
|
||||||
zend_hash_init(&class_entry->function_table, 0, NULL, (void (*)(void *)) destroy_zend_function, 1);
|
zend_hash_init(&class_entry->function_table, 0, NULL, ZEND_FUNCTION_DTOR, 1);
|
||||||
|
|
||||||
zend_hash_update(CG(class_table), lowercase_name, class_entry->name_length+1, class_entry, sizeof(zend_class_entry), (void **) ®ister_class);
|
zend_hash_update(CG(class_table), lowercase_name, class_entry->name_length+1, class_entry, sizeof(zend_class_entry), (void **) ®ister_class);
|
||||||
free(lowercase_name);
|
free(lowercase_name);
|
||||||
|
@ -1219,7 +1219,7 @@ void do_begin_class_declaration(znode *class_name, znode *parent_class_name CLS_
|
|||||||
|
|
||||||
zend_str_tolower(CG(class_entry).name, CG(class_entry).name_length);
|
zend_str_tolower(CG(class_entry).name, CG(class_entry).name_length);
|
||||||
|
|
||||||
zend_hash_init(&CG(class_entry).function_table, 10, NULL, (void (*)(void *)) destroy_zend_function, 0);
|
zend_hash_init(&CG(class_entry).function_table, 10, NULL, ZEND_FUNCTION_DTOR, 0);
|
||||||
zend_hash_init(&CG(class_entry).default_properties, 10, NULL, PVAL_PTR_DTOR, 0);
|
zend_hash_init(&CG(class_entry).default_properties, 10, NULL, PVAL_PTR_DTOR, 0);
|
||||||
|
|
||||||
/* code for inheritance from parent class */
|
/* code for inheritance from parent class */
|
||||||
|
@ -350,10 +350,13 @@ ZEND_API void zend_close_file_handle(zend_file_handle *file_handle CLS_DC);
|
|||||||
ZEND_API void zend_open_file_dtor(void *f);
|
ZEND_API void zend_open_file_dtor(void *f);
|
||||||
END_EXTERN_C()
|
END_EXTERN_C()
|
||||||
|
|
||||||
ZEND_API void destroy_zend_function(zend_function *function);
|
ZEND_API int destroy_zend_function(zend_function *function);
|
||||||
ZEND_API void destroy_zend_class(zend_class_entry *ce);
|
ZEND_API int destroy_zend_class(zend_class_entry *ce);
|
||||||
void zend_class_add_ref(zend_class_entry *ce);
|
void zend_class_add_ref(zend_class_entry *ce);
|
||||||
|
|
||||||
|
#define ZEND_FUNCTION_DTOR (int (*)(void *)) destroy_zend_function
|
||||||
|
#define ZEND_CLASS_DTOR (int (*)(void *)) destroy_zend_class
|
||||||
|
|
||||||
zend_op *get_next_op(zend_op_array *op_array CLS_DC);
|
zend_op *get_next_op(zend_op_array *op_array CLS_DC);
|
||||||
int get_next_op_number(zend_op_array *op_array);
|
int get_next_op_number(zend_op_array *op_array);
|
||||||
int print_class(zend_class_entry *class_entry);
|
int print_class(zend_class_entry *class_entry);
|
||||||
|
@ -22,12 +22,13 @@
|
|||||||
#include "zend_globals.h"
|
#include "zend_globals.h"
|
||||||
|
|
||||||
|
|
||||||
void free_zend_constant(zend_constant *c)
|
int free_zend_constant(zend_constant *c)
|
||||||
{
|
{
|
||||||
if (!(c->flags & CONST_PERSISTENT)) {
|
if (!(c->flags & CONST_PERSISTENT)) {
|
||||||
zval_dtor(&c->value);
|
zval_dtor(&c->value);
|
||||||
}
|
}
|
||||||
free(c->name);
|
free(c->name);
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -86,7 +87,7 @@ int zend_startup_constants(ELS_D)
|
|||||||
|
|
||||||
EG(zend_constants) = (HashTable *) malloc(sizeof(HashTable));
|
EG(zend_constants) = (HashTable *) malloc(sizeof(HashTable));
|
||||||
|
|
||||||
if (zend_hash_init(EG(zend_constants), 20, NULL, (void(*)(void *)) free_zend_constant, 1)==FAILURE) {
|
if (zend_hash_init(EG(zend_constants), 20, NULL, ZEND_CONSTANT_DTOR, 1)==FAILURE) {
|
||||||
return FAILURE;
|
return FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -41,7 +41,7 @@ typedef struct _zend_constant {
|
|||||||
#define REGISTER_MAIN_STRINGL_CONSTANT(name,str,len,flags) zend_register_stringl_constant((name),sizeof(name),(str),(len),(flags),0 ELS_CC)
|
#define REGISTER_MAIN_STRINGL_CONSTANT(name,str,len,flags) zend_register_stringl_constant((name),sizeof(name),(str),(len),(flags),0 ELS_CC)
|
||||||
|
|
||||||
void clean_module_constants(int module_number);
|
void clean_module_constants(int module_number);
|
||||||
void free_zend_constant(zend_constant *c);
|
int free_zend_constant(zend_constant *c);
|
||||||
int zend_startup_constants(ELS_D);
|
int zend_startup_constants(ELS_D);
|
||||||
int zend_shutdown_constants(ELS_D);
|
int zend_shutdown_constants(ELS_D);
|
||||||
void clean_non_persistent_constants(void);
|
void clean_non_persistent_constants(void);
|
||||||
@ -52,4 +52,6 @@ ZEND_API void zend_register_string_constant(char *name, uint name_len, char *str
|
|||||||
ZEND_API void zend_register_stringl_constant(char *name, uint name_len, char *strval, uint strlen, int flags, int module_number ELS_DC);
|
ZEND_API void zend_register_stringl_constant(char *name, uint name_len, char *strval, uint strlen, int flags, int module_number ELS_DC);
|
||||||
ZEND_API void zend_register_constant(zend_constant *c ELS_DC);
|
ZEND_API void zend_register_constant(zend_constant *c ELS_DC);
|
||||||
|
|
||||||
|
#define ZEND_CONSTANT_DTOR (int (*)(void *)) free_zend_constant
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -195,7 +195,7 @@ ZEND_API inline void safe_free_zval_ptr(zval *p)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
ZEND_API void zval_ptr_dtor(zval **zval_ptr)
|
ZEND_API int zval_ptr_dtor(zval **zval_ptr)
|
||||||
{
|
{
|
||||||
#if DEBUG_ZEND>=2
|
#if DEBUG_ZEND>=2
|
||||||
printf("Reducing refcount for %x (%x): %d->%d\n", *zval_ptr, zval_ptr, (*zval_ptr)->refcount, (*zval_ptr)->refcount-1);
|
printf("Reducing refcount for %x (%x): %d->%d\n", *zval_ptr, zval_ptr, (*zval_ptr)->refcount, (*zval_ptr)->refcount-1);
|
||||||
@ -205,6 +205,7 @@ ZEND_API void zval_ptr_dtor(zval **zval_ptr)
|
|||||||
zval_dtor(*zval_ptr);
|
zval_dtor(*zval_ptr);
|
||||||
safe_free_zval_ptr(*zval_ptr);
|
safe_free_zval_ptr(*zval_ptr);
|
||||||
}
|
}
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -71,7 +71,7 @@ ZEND_API ulong hashpjw(char *arKey, uint nKeyLength)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
ZEND_API int zend_hash_init(HashTable *ht, uint nSize, ulong(*pHashFunction) (char *arKey, uint nKeyLength), void (*pDestructor) (void *pData),int persistent)
|
ZEND_API int zend_hash_init(HashTable *ht, uint nSize, ulong(*pHashFunction) (char *arKey, uint nKeyLength), int (*pDestructor) (void *pData),int persistent)
|
||||||
{
|
{
|
||||||
uint i;
|
uint i;
|
||||||
|
|
||||||
@ -720,6 +720,7 @@ ZEND_API int zend_hash_del_key_or_index(HashTable *ht, char *arKey, uint nKeyLen
|
|||||||
ZEND_API void zend_hash_destroy(HashTable *ht)
|
ZEND_API void zend_hash_destroy(HashTable *ht)
|
||||||
{
|
{
|
||||||
Bucket *p, *q;
|
Bucket *p, *q;
|
||||||
|
int delete_bucket;
|
||||||
|
|
||||||
p = ht->pListHead;
|
p = ht->pListHead;
|
||||||
while (p != NULL) {
|
while (p != NULL) {
|
||||||
@ -727,13 +728,19 @@ ZEND_API void zend_hash_destroy(HashTable *ht)
|
|||||||
p = p->pListNext;
|
p = p->pListNext;
|
||||||
if (!q->bIsPointer) {
|
if (!q->bIsPointer) {
|
||||||
if (ht->pDestructor) {
|
if (ht->pDestructor) {
|
||||||
ht->pDestructor(q->pData);
|
delete_bucket = ht->pDestructor(q->pData);
|
||||||
|
} else {
|
||||||
|
delete_bucket = 1;
|
||||||
}
|
}
|
||||||
if (!q->pDataPtr && q->pData) {
|
if (!q->pDataPtr && q->pData) {
|
||||||
pefree(q->pData,ht->persistent);
|
pefree(q->pData,ht->persistent);
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
delete_bucket = 1;
|
||||||
|
}
|
||||||
|
if (delete_bucket) {
|
||||||
|
pefree(q,ht->persistent);
|
||||||
}
|
}
|
||||||
pefree(q,ht->persistent);
|
|
||||||
}
|
}
|
||||||
pefree(ht->arBuckets,ht->persistent);
|
pefree(ht->arBuckets,ht->persistent);
|
||||||
}
|
}
|
||||||
|
@ -56,7 +56,7 @@ typedef struct hashtable {
|
|||||||
Bucket *pListHead;
|
Bucket *pListHead;
|
||||||
Bucket *pListTail;
|
Bucket *pListTail;
|
||||||
Bucket **arBuckets;
|
Bucket **arBuckets;
|
||||||
void (*pDestructor) (void *pData);
|
int (*pDestructor) (void *pData);
|
||||||
unsigned char persistent;
|
unsigned char persistent;
|
||||||
} HashTable;
|
} HashTable;
|
||||||
|
|
||||||
@ -64,7 +64,7 @@ typedef struct hashtable {
|
|||||||
BEGIN_EXTERN_C()
|
BEGIN_EXTERN_C()
|
||||||
|
|
||||||
/* startup/shutdown */
|
/* startup/shutdown */
|
||||||
ZEND_API int zend_hash_init(HashTable *ht, uint nSize, ulong(*pHashFunction) (char *arKey, uint nKeyLength), void (*pDestructor) (void *pData), int persistent);
|
ZEND_API int zend_hash_init(HashTable *ht, uint nSize, ulong(*pHashFunction) (char *arKey, uint nKeyLength), int (*pDestructor) (void *pData), int persistent);
|
||||||
ZEND_API void zend_hash_destroy(HashTable *ht);
|
ZEND_API void zend_hash_destroy(HashTable *ht);
|
||||||
|
|
||||||
ZEND_API void zend_hash_clean(HashTable *ht);
|
ZEND_API void zend_hash_clean(HashTable *ht);
|
||||||
|
@ -133,7 +133,7 @@ ZEND_API void *zend_plist_find(int id, int *type)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void list_entry_destructor(void *ptr)
|
int list_entry_destructor(void *ptr)
|
||||||
{
|
{
|
||||||
list_entry *le = (list_entry *) ptr;
|
list_entry *le = (list_entry *) ptr;
|
||||||
list_destructors_entry *ld;
|
list_destructors_entry *ld;
|
||||||
@ -145,10 +145,11 @@ void list_entry_destructor(void *ptr)
|
|||||||
} else {
|
} else {
|
||||||
zend_error(E_WARNING,"Unknown list entry type in request shutdown (%d)",le->type);
|
zend_error(E_WARNING,"Unknown list entry type in request shutdown (%d)",le->type);
|
||||||
}
|
}
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void plist_entry_destructor(void *ptr)
|
int plist_entry_destructor(void *ptr)
|
||||||
{
|
{
|
||||||
list_entry *le = (list_entry *) ptr;
|
list_entry *le = (list_entry *) ptr;
|
||||||
list_destructors_entry *ld;
|
list_destructors_entry *ld;
|
||||||
@ -160,6 +161,7 @@ void plist_entry_destructor(void *ptr)
|
|||||||
} else {
|
} else {
|
||||||
zend_error(E_WARNING,"Unknown persistent list entry type in module shutdown (%d)",le->type);
|
zend_error(E_WARNING,"Unknown persistent list entry type in module shutdown (%d)",le->type);
|
||||||
}
|
}
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -42,8 +42,8 @@ enum list_entry_type {
|
|||||||
LE_DB=1000
|
LE_DB=1000
|
||||||
};
|
};
|
||||||
|
|
||||||
void list_entry_destructor(void *ptr);
|
int list_entry_destructor(void *ptr);
|
||||||
void plist_entry_destructor(void *ptr);
|
int plist_entry_destructor(void *ptr);
|
||||||
|
|
||||||
int clean_module_resource_destructors(list_destructors_entry *ld, int *module_number);
|
int clean_module_resource_destructors(list_destructors_entry *ld, int *module_number);
|
||||||
int init_resource_list(ELS_D);
|
int init_resource_list(ELS_D);
|
||||||
|
@ -52,4 +52,5 @@ extern void module_destructor(zend_module_entry *module);
|
|||||||
extern int module_registry_cleanup(zend_module_entry *module);
|
extern int module_registry_cleanup(zend_module_entry *module);
|
||||||
extern int module_registry_request_startup(zend_module_entry *module);
|
extern int module_registry_request_startup(zend_module_entry *module);
|
||||||
|
|
||||||
|
#define ZEND_MODULE_DTOR (int (*)(void *)) module_destructor
|
||||||
#endif
|
#endif
|
||||||
|
@ -99,7 +99,7 @@ void init_op_array(zend_op_array *op_array, int initial_ops_size)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
ZEND_API void destroy_zend_function(zend_function *function)
|
ZEND_API int destroy_zend_function(zend_function *function)
|
||||||
{
|
{
|
||||||
switch (function->type) {
|
switch (function->type) {
|
||||||
case ZEND_USER_FUNCTION:
|
case ZEND_USER_FUNCTION:
|
||||||
@ -109,13 +109,14 @@ ZEND_API void destroy_zend_function(zend_function *function)
|
|||||||
/* do nothing */
|
/* do nothing */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
ZEND_API void destroy_zend_class(zend_class_entry *ce)
|
ZEND_API int destroy_zend_class(zend_class_entry *ce)
|
||||||
{
|
{
|
||||||
if (--(*ce->refcount)>0) {
|
if (--(*ce->refcount)>0) {
|
||||||
return;
|
return 1;
|
||||||
}
|
}
|
||||||
switch (ce->type) {
|
switch (ce->type) {
|
||||||
case ZEND_USER_CLASS:
|
case ZEND_USER_CLASS:
|
||||||
@ -131,6 +132,7 @@ ZEND_API void destroy_zend_class(zend_class_entry *ce)
|
|||||||
zend_hash_destroy(&ce->default_properties);
|
zend_hash_destroy(&ce->default_properties);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -47,7 +47,7 @@ ZEND_API inline void var_uninit(zval *var)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
ZEND_API void zval_dtor(zval *zvalue)
|
ZEND_API int zval_dtor(zval *zvalue)
|
||||||
{
|
{
|
||||||
if (zvalue->type==IS_LONG) {
|
if (zvalue->type==IS_LONG) {
|
||||||
return;
|
return;
|
||||||
|
@ -22,14 +22,14 @@ ZEND_API int zend_print_variable(zval *var);
|
|||||||
|
|
||||||
BEGIN_EXTERN_C()
|
BEGIN_EXTERN_C()
|
||||||
ZEND_API int zval_copy_ctor(zval *zvalue);
|
ZEND_API int zval_copy_ctor(zval *zvalue);
|
||||||
ZEND_API void zval_dtor(zval *zvalue);
|
ZEND_API int zval_dtor(zval *zvalue);
|
||||||
END_EXTERN_C()
|
END_EXTERN_C()
|
||||||
|
|
||||||
ZEND_API void zval_ptr_dtor(zval **zval_ptr);
|
ZEND_API int zval_ptr_dtor(zval **zval_ptr);
|
||||||
void zval_add_ref(zval **p);
|
void zval_add_ref(zval **p);
|
||||||
|
|
||||||
#define PVAL_DESTRUCTOR (void (*)(void *)) zval_dtor
|
#define PVAL_DESTRUCTOR (int (*)(void *)) zval_dtor
|
||||||
#define PVAL_PTR_DTOR (void (*)(void *)) zval_ptr_dtor
|
#define PVAL_PTR_DTOR (int (*)(void *)) zval_ptr_dtor
|
||||||
#define PVAL_COPY_CTOR (void (*)(void *)) zval_copy_ctor
|
#define PVAL_COPY_CTOR (void (*)(void *)) zval_copy_ctor
|
||||||
|
|
||||||
ZEND_API void var_reset(zval *var);
|
ZEND_API void var_reset(zval *var);
|
||||||
|
Loading…
Reference in New Issue
Block a user