com php-src: Use object apply count in var_dump / print _r: Zend/zend.c ext/spl/spl_array.c ext/spl/spl _dllist.c ext/spl/spl_heap.c
ext/spl/spl_observer .c ext/standard/var.c

From: Date: Wed, 15 Apr 2015 20:00:12 +0000
Subject: com php-src: Use object apply count in var_dump / print _r: Zend/zend.c ext/spl/spl_array.c ext/spl/spl _dllist.c ext/spl/spl_heap.c
ext/spl/spl_observer .c ext/standard/var.c
Groups: php.cvs 
Request: Send a blank email to php-cvs+get-86317@lists.php.net to get a copy of this message
Commit: dc764bf644bba1b574c0970df4386d3fcc243914 Author: Nikita Popov <nikic@php.net> Wed, 15 Apr 2015 21:07:34 +0200 Parents: 3dcad2eea2f24164f2a313792bbfda5e093b4807 Branches: master Link: http://git.php.net/?p=php-src.git;a=commitdiff;h=dc764bf644bba1b574c0970df4386d3fcc243914 Log: Use object apply count in var_dump / print_r Instead of using the array apply count on the debug_info array, use the object apply count for recursion detection when dumping. This handles recursion in a more generic way and does not require each debug_info handler to deal with this. This allows returning a temporary debug_info array, instead of having to store it in the object (thus delaying destruction of the values). Switch SPL debug_info handlers to use a temporary array. Changed paths: M Zend/zend.c M ext/spl/spl_array..c M ext/spl/spl_dllist.c M ext/spl/spl_heap.c M ext/spl/spl_observer.c M ext/standard/var.c

diff --git a/Zend/zend.c b/Zend/zend.c index 77e0b62..03082de 100644 --- a/Zend/zend.c +++ b/Zend/zend.c @@ -296,17 +296,18 @@ ZEND_API void zend_print_flat_zval_r(zval *expr) /* {{{ */ zend_printf("%s Object (", class_name->val); zend_string_release(class_name); + if (Z_OBJ_APPLY_COUNT_P(expr) > 0) { + ZEND_PUTS(" *RECURSION*"); + return; + } + if (Z_OBJ_HANDLER_P(expr, get_properties)) { properties = Z_OBJPROP_P(expr); } if (properties) { - if (++properties->u.v.nApplyCount>1) { - ZEND_PUTS(" *RECURSION*"); - properties->u.v.nApplyCount--; - return; - } + Z_OBJ_INC_APPLY_COUNT_P(expr); print_flat_hash(properties); - properties->u.v.nApplyCount--; + Z_OBJ_DEC_APPLY_COUNT_P(expr); } ZEND_PUTS(")"); break; @@ -351,16 +352,18 @@ ZEND_API void zend_print_zval_r_ex(zend_write_func_t write_func, zval *expr, int zend_string_release(class_name); ZEND_PUTS_EX(" Object\n"); - if ((properties = Z_OBJDEBUG_P(expr, is_temp)) == NULL) { - break; - } - if (++properties->u.v.nApplyCount>1) { + if (Z_OBJ_APPLY_COUNT_P(expr) > 0) { ZEND_PUTS_EX(" *RECURSION*"); - properties->u.v.nApplyCount--; return; } + if ((properties = Z_OBJDEBUG_P(expr, is_temp)) == NULL) { + break; + } + + Z_OBJ_INC_APPLY_COUNT_P(expr); print_hash(write_func, properties, indent, 1); - properties->u.v.nApplyCount--; + Z_OBJ_DEC_APPLY_COUNT_P(expr); + if (is_temp) { zend_hash_destroy(properties); FREE_HASHTABLE(properties); diff --git a/ext/spl/spl_array.c b/ext/spl/spl_array.c index 7639238..78fe94c 100644 --- a/ext/spl/spl_array.c +++ b/ext/spl/spl_array.c @@ -73,7 +73,6 @@ typedef struct _spl_array_object { zend_function *fptr_offset_del; zend_function *fptr_count; zend_class_entry* ce_get_iterator; - HashTable *debug_info; unsigned char nApplyCount; zend_object std; } spl_array_object; @@ -131,11 +130,6 @@ static void spl_array_object_free_storage(zend_object *object) zend_object_std_dtor(&intern->std); zval_ptr_dtor(&intern->array); - - if (intern->debug_info != NULL) { - zend_hash_destroy(intern->debug_info); - efree(intern->debug_info); - } } /* }}} */ @@ -154,7 +148,6 @@ static zend_object *spl_array_object_new_ex(zend_class_entry *class_type, zval * object_properties_init(&intern->std, class_type); intern->ar_flags = 0; - intern->debug_info = NULL; intern->ce_get_iterator = spl_ce_ArrayIterator; if (orig) { spl_array_object *other = Z_SPLARRAY_P(orig); @@ -806,34 +799,31 @@ static HashTable* spl_array_get_debug_info(zval *obj, int *is_temp) /* {{{ */ zend_class_entry *base; spl_array_object *intern = Z_SPLARRAY_P(obj); - *is_temp = 0; - if (!intern->std.properties) { rebuild_object_properties(&intern->std); } if (HASH_OF(&intern->array) == intern->std.properties) { + *is_temp = 0; return intern->std.properties; } else { - if (intern->debug_info == NULL) { - ALLOC_HASHTABLE(intern->debug_info); - ZEND_INIT_SYMTABLE_EX(intern->debug_info, zend_hash_num_elements(intern->std.properties) + 1, 0); - } + HashTable *debug_info; + *is_temp = 1; - if (intern->debug_info->u.v.nApplyCount == 0) { - zend_hash_clean(intern->debug_info); - zend_hash_copy(intern->debug_info, intern->std.properties, (copy_ctor_func_t) zval_add_ref); + ALLOC_HASHTABLE(debug_info); + ZEND_INIT_SYMTABLE_EX(debug_info, zend_hash_num_elements(intern->std.properties) + 1, 0); + zend_hash_copy(debug_info, intern->std.properties, (copy_ctor_func_t) zval_add_ref); - storage = &intern->array; - Z_TRY_ADDREF_P(storage); + storage = &intern->array; + Z_TRY_ADDREF_P(storage); - base = (Z_OBJ_HT_P(obj) == &spl_handler_ArrayIterator) ? spl_ce_ArrayIterator : spl_ce_ArrayObject; - zname = spl_gen_private_prop_name(base, "storage", sizeof("storage")-1); - zend_symtable_update(intern->debug_info, zname, storage); - zend_string_release(zname); - } + base = Z_OBJ_HT_P(obj) == &spl_handler_ArrayIterator + ? spl_ce_ArrayIterator : spl_ce_ArrayObject; + zname = spl_gen_private_prop_name(base, "storage", sizeof("storage")-1); + zend_symtable_update(debug_info, zname, storage); + zend_string_release(zname); - return intern->debug_info; + return debug_info; } } /* }}} */ diff --git a/ext/spl/spl_dllist.c b/ext/spl/spl_dllist.c index 68c4648..6406670 100644 --- a/ext/spl/spl_dllist.c +++ b/ext/spl/spl_dllist.c @@ -93,7 +93,6 @@ struct _spl_dllist_object { zend_function *fptr_offset_del; zend_function *fptr_count; zend_class_entry *ce_get_iterator; - HashTable *debug_info; zend_object std; }; @@ -357,11 +356,6 @@ static void spl_dllist_object_free_storage(zend_object *object) /* {{{ */ spl_ptr_llist_destroy(intern->llist); SPL_LLIST_CHECK_DELREF(intern->traverse_pointer); - - if (intern->debug_info != NULL) { - zend_hash_destroy(intern->debug_info); - efree(intern->debug_info); - } } /* }}} */ @@ -380,7 +374,6 @@ static zend_object *spl_dllist_object_new_ex(zend_class_entry *class_type, zval intern->flags = 0; intern->traverse_position = 0; - intern->debug_info = NULL; if (orig) { spl_dllist_object *other = Z_SPLDLLIST_P(orig); @@ -500,46 +493,41 @@ static HashTable* spl_dllist_object_get_debug_info(zval *obj, int *is_temp) /* { zval tmp, dllist_array; zend_string *pnstr; int i = 0; + HashTable *debug_info; + *is_temp = 1; - *is_temp = 0; - - if (intern->debug_info == NULL) { - ALLOC_HASHTABLE(intern->debug_info); - zend_hash_init(intern->debug_info, 1, NULL, ZVAL_PTR_DTOR, 0); + if (!intern->std.properties) { + rebuild_object_properties(&intern->std); } - if (intern->debug_info->u.v.nApplyCount == 0) { - - if (!intern->std.properties) { - rebuild_object_properties(&intern->std); - } - zend_hash_copy(intern->debug_info, intern->std.properties, (copy_ctor_func_t) zval_add_ref); - - pnstr = spl_gen_private_prop_name(spl_ce_SplDoublyLinkedList, "flags", sizeof("flags")-1); - ZVAL_LONG(&tmp, intern->flags); - zend_hash_add(intern->debug_info, pnstr, &tmp); - zend_string_release(pnstr); + ALLOC_HASHTABLE(debug_info); + zend_hash_init(debug_info, 1, NULL, ZVAL_PTR_DTOR, 0); + zend_hash_copy(debug_info, intern->std.properties, (copy_ctor_func_t) zval_add_ref); - array_init(&dllist_array); + pnstr = spl_gen_private_prop_name(spl_ce_SplDoublyLinkedList, "flags", sizeof("flags")-1); + ZVAL_LONG(&tmp, intern->flags); + zend_hash_add(debug_info, pnstr, &tmp); + zend_string_release(pnstr); - while (current) { - next = current->next; + array_init(&dllist_array); - add_index_zval(&dllist_array, i, &current->data); - if (Z_REFCOUNTED(current->data)) { - Z_ADDREF(current->data); - } - i++; + while (current) { + next = current->next; - current = next; + add_index_zval(&dllist_array, i, &current->data); + if (Z_REFCOUNTED(current->data)) { + Z_ADDREF(current->data); } + i++; - pnstr = spl_gen_private_prop_name(spl_ce_SplDoublyLinkedList, "dllist", sizeof("dllist")-1); - zend_hash_add(intern->debug_info, pnstr, &dllist_array); - zend_string_release(pnstr); + current = next; } - return intern->debug_info; + pnstr = spl_gen_private_prop_name(spl_ce_SplDoublyLinkedList, "dllist", sizeof("dllist")-1); + zend_hash_add(debug_info, pnstr, &dllist_array); + zend_string_release(pnstr); + + return debug_info; } /* }}}} */ diff --git a/ext/spl/spl_heap.c b/ext/spl/spl_heap.c index 98f4217..825344f 100644 --- a/ext/spl/spl_heap.c +++ b/ext/spl/spl_heap.c @@ -73,7 +73,6 @@ struct _spl_heap_object { zend_class_entry *ce_get_iterator; zend_function *fptr_cmp; zend_function *fptr_count; - HashTable *debug_info; zend_object std; }; @@ -369,11 +368,6 @@ static void spl_heap_object_free_storage(zend_object *object) /* {{{ */ } spl_ptr_heap_destroy(intern->heap); - - if (intern->debug_info != NULL) { - zend_hash_destroy(intern->debug_info); - efree(intern->debug_info); - } } /* }}} */ @@ -390,7 +384,6 @@ static zend_object *spl_heap_object_new_ex(zend_class_entry *class_type, zval *o intern->flags = 0; intern->fptr_cmp = NULL; - intern->debug_info = NULL; if (orig) { spl_heap_object *other = Z_SPLHEAP_P(orig); @@ -506,48 +499,43 @@ static HashTable* spl_heap_object_get_debug_info_helper(zend_class_entry *ce, zv spl_heap_object *intern = Z_SPLHEAP_P(obj); zval tmp, heap_array; zend_string *pnstr; + HashTable *debug_info; int i; - *is_temp = 0; + *is_temp = 1; if (!intern->std.properties) { rebuild_object_properties(&intern->std); } - if (intern->debug_info == NULL) { - ALLOC_HASHTABLE(intern->debug_info); - ZEND_INIT_SYMTABLE_EX(intern->debug_info, zend_hash_num_elements(intern->std.properties) + 1, 0); - } - - if (intern->debug_info->u.v.nApplyCount == 0) { - - zend_hash_copy(intern->debug_info, intern->std.properties, (copy_ctor_func_t) zval_add_ref); + ALLOC_HASHTABLE(debug_info); + ZEND_INIT_SYMTABLE_EX(debug_info, zend_hash_num_elements(intern->std.properties) + 1, 0); + zend_hash_copy(debug_info, intern->std.properties, (copy_ctor_func_t) zval_add_ref); - pnstr = spl_gen_private_prop_name(ce, "flags", sizeof("flags")-1); - ZVAL_LONG(&tmp, intern->flags); - zend_hash_update(intern->debug_info, pnstr, &tmp); - zend_string_release(pnstr); + pnstr = spl_gen_private_prop_name(ce, "flags", sizeof("flags")-1); + ZVAL_LONG(&tmp, intern->flags); + zend_hash_update(debug_info, pnstr, &tmp); + zend_string_release(pnstr); - pnstr = spl_gen_private_prop_name(ce, "isCorrupted", sizeof("isCorrupted")-1); - ZVAL_BOOL(&tmp, intern->heap->flags&SPL_HEAP_CORRUPTED); - zend_hash_update(intern->debug_info, pnstr, &tmp); - zend_string_release(pnstr); + pnstr = spl_gen_private_prop_name(ce, "isCorrupted", sizeof("isCorrupted")-1); + ZVAL_BOOL(&tmp, intern->heap->flags&SPL_HEAP_CORRUPTED); + zend_hash_update(debug_info, pnstr, &tmp); + zend_string_release(pnstr); - array_init(&heap_array); + array_init(&heap_array); - for (i = 0; i < intern->heap->count; ++i) { - add_index_zval(&heap_array, i, &intern->heap->elements[i]); - if (Z_REFCOUNTED(intern->heap->elements[i])) { - Z_ADDREF(intern->heap->elements[i]); - } + for (i = 0; i < intern->heap->count; ++i) { + add_index_zval(&heap_array, i, &intern->heap->elements[i]); + if (Z_REFCOUNTED(intern->heap->elements[i])) { + Z_ADDREF(intern->heap->elements[i]); } - - pnstr = spl_gen_private_prop_name(ce, "heap", sizeof("heap")-1); - zend_hash_update(intern->debug_info, pnstr, &heap_array); - zend_string_release(pnstr); } - return intern->debug_info; + pnstr = spl_gen_private_prop_name(ce, "heap", sizeof("heap")-1); + zend_hash_update(debug_info, pnstr, &heap_array); + zend_string_release(pnstr); + + return debug_info; } /* }}} */ diff --git a/ext/spl/spl_observer.c b/ext/spl/spl_observer.c index 76933a8..b508565 100644 --- a/ext/spl/spl_observer.c +++ b/ext/spl/spl_observer.c @@ -85,7 +85,6 @@ typedef struct _spl_SplObjectStorage { /* {{{ */ HashPosition pos; zend_long flags; zend_function *fptr_get_hash; - HashTable *debug_info; zval *gcdata; size_t gcdata_num; zend_object std; @@ -112,11 +111,6 @@ void spl_SplObjectStorage_free_storage(zend_object *object) /* {{{ */ zend_hash_destroy(&intern->storage); - if (intern->debug_info != NULL) { - zend_hash_destroy(intern->debug_info); - efree(intern->debug_info); - } - if (intern->gcdata != NULL) { efree(intern->gcdata); } @@ -320,39 +314,35 @@ static HashTable* spl_object_storage_debug_info(zval *obj, int *is_temp) /* {{{ zval tmp, storage; zend_string *md5str; zend_string *zname; + HashTable *debug_info; - *is_temp = 0; + *is_temp = 1; props = Z_OBJPROP_P(obj); - if (intern->debug_info == NULL) { - ALLOC_HASHTABLE(intern->debug_info); - ZEND_INIT_SYMTABLE_EX(intern->debug_info, zend_hash_num_elements(props) + 1, 0); - } - - if (intern->debug_info->u.v.nApplyCount == 0) { - zend_hash_copy(intern->debug_info, props, (copy_ctor_func_t)zval_add_ref); + ALLOC_HASHTABLE(debug_info); + ZEND_INIT_SYMTABLE_EX(debug_info, zend_hash_num_elements(props) + 1, 0); + zend_hash_copy(debug_info, props, (copy_ctor_func_t)zval_add_ref); - array_init(&storage); + array_init(&storage); - ZEND_HASH_FOREACH_PTR(&intern->storage, element) { - md5str = php_spl_object_hash(&element->obj); - array_init(&tmp); - /* Incrementing the refcount of obj and inf would confuse the garbage collector. - * Prefer to null the destructor */ - Z_ARRVAL_P(&tmp)->pDestructor = NULL; - add_assoc_zval_ex(&tmp, "obj", sizeof("obj") - 1, &element->obj); - add_assoc_zval_ex(&tmp, "inf", sizeof("inf") - 1, &element->inf); - zend_hash_update(Z_ARRVAL(storage), md5str, &tmp); - zend_string_release(md5str); - } ZEND_HASH_FOREACH_END(); + ZEND_HASH_FOREACH_PTR(&intern->storage, element) { + md5str = php_spl_object_hash(&element->obj); + array_init(&tmp); + /* Incrementing the refcount of obj and inf would confuse the garbage collector. + * Prefer to null the destructor */ + Z_ARRVAL_P(&tmp)->pDestructor = NULL; + add_assoc_zval_ex(&tmp, "obj", sizeof("obj") - 1, &element->obj); + add_assoc_zval_ex(&tmp, "inf", sizeof("inf") - 1, &element->inf); + zend_hash_update(Z_ARRVAL(storage), md5str, &tmp); + zend_string_release(md5str); + } ZEND_HASH_FOREACH_END(); - zname = spl_gen_private_prop_name(spl_ce_SplObjectStorage, "storage", sizeof("storage")-1); - zend_symtable_update(intern->debug_info, zname, &storage); - zend_string_release(zname); - } + zname = spl_gen_private_prop_name(spl_ce_SplObjectStorage, "storage", sizeof("storage")-1); + zend_symtable_update(debug_info, zname, &storage); + zend_string_release(zname); - return intern->debug_info; + return debug_info; } /* }}} */ diff --git a/ext/standard/var.c b/ext/standard/var.c index 64926d1..fc6be92 100644 --- a/ext/standard/var.c +++ b/ext/standard/var.c @@ -62,7 +62,7 @@ static void php_array_element_dump(zval *zv, zend_ulong index, zend_string *key, php_printf("%*c[\"", level + 1, ' '); PHPWRITE(key->val, key->len); php_printf("\"]=>\n"); - } + } php_var_dump(zv, level + 2); } /* }}} */ @@ -156,13 +156,13 @@ again: PUTS("}\n"); break; case IS_OBJECT: - myht = Z_OBJDEBUG_P(struc, is_temp); - if (myht && ++myht->u.v.nApplyCount > 1) { + if (Z_OBJ_APPLY_COUNT_P(struc) > 0) { PUTS("*RECURSION*\n"); - --myht->u.v.nApplyCount; return; } + Z_OBJ_INC_APPLY_COUNT_P(struc); + myht = Z_OBJDEBUG_P(struc, is_temp); class_name = Z_OBJ_HANDLER_P(struc, get_class_name)(Z_OBJ_P(struc)); php_printf("%sobject(%s)#%d (%d) {\n", COMMON, class_name->val, Z_OBJ_HANDLE_P(struc), myht ? zend_obj_num_elements(myht) : 0); zend_string_release(class_name); @@ -175,7 +175,6 @@ again: ZEND_HASH_FOREACH_KEY_VAL_IND(myht, num, key, val) { php_object_property_dump(val, num, key, level); } ZEND_HASH_FOREACH_END(); - --myht->u.v.nApplyCount; if (is_temp) { zend_hash_destroy(myht); efree(myht); @@ -185,6 +184,7 @@ again: php_printf("%*c", level-1, ' '); } PUTS("}\n"); + Z_OBJ_DEC_APPLY_COUNT_P(struc); break; case IS_RESOURCE: { const char *type_name = zend_rsrc_list_get_rsrc_type(Z_RES_P(struc));
« previous php.cvs (#86317) next »