diff --git a/src/array.c b/src/array.c index cdcf6481e340f1f8492b78b1ad923ff5cdeb9c37..88bf09f4b28c9b358918ba0e894c6f3cd269c387 100644 --- a/src/array.c +++ b/src/array.c @@ -2,7 +2,7 @@ || This file is part of Pike. For copyright information see COPYRIGHT. || Pike is distributed under GPL, LGPL and MPL. See the file COPYING || for more information. -|| $Id: array.c,v 1.153 2004/03/09 15:48:51 nilsson Exp $ +|| $Id: array.c,v 1.154 2004/03/15 22:23:14 mast Exp $ */ #include "global.h" @@ -26,13 +26,13 @@ #include "cyclic.h" #include "multiset.h" -RCSID("$Id: array.c,v 1.153 2004/03/09 15:48:51 nilsson Exp $"); +RCSID("$Id: array.c,v 1.154 2004/03/15 22:23:14 mast Exp $"); PMOD_EXPORT struct array empty_array= { PIKE_CONSTANT_MEMOBJ_INIT(1), /* Never free */ &weak_empty_array, /* Next */ - &weak_shrink_empty_array, /* previous (circular) */ + 0, /* previous */ 0, /* Size = 0 */ 0, /* malloced Size = 0 */ 0, /* no types */ @@ -54,14 +54,15 @@ PMOD_EXPORT struct array weak_empty_array= PMOD_EXPORT struct array weak_shrink_empty_array= { PIKE_CONSTANT_MEMOBJ_INIT(1), - &empty_array, &weak_empty_array, 0, 0, 0, ARRAY_WEAK_FLAG|ARRAY_WEAK_SHRINK, + 0, &weak_empty_array, 0, 0, 0, ARRAY_WEAK_FLAG|ARRAY_WEAK_SHRINK, weak_shrink_empty_array.real_item, #ifdef HAVE_UNION_INIT {{0, 0, {0}}}, /* Only to avoid warnings. */ #endif }; -struct array *gc_internal_array = &empty_array; +struct array *first_array = &empty_array; +struct array *gc_internal_array = 0; static struct array *gc_mark_array_pos = 0; #ifdef TRACE_UNFINISHED_TYPE_FIELDS @@ -108,7 +109,7 @@ PMOD_EXPORT struct array *low_allocate_array(ptrdiff_t size, ptrdiff_t extra_spa v->item=v->real_item; v->size = DO_NOT_WARN((INT32)size); INIT_PIKE_MEMOBJ(v); - LINK_ARRAY(v); + DOUBLELINK (first_array, v); for(e=0;e<v->size;e++) { @@ -125,7 +126,7 @@ PMOD_EXPORT struct array *low_allocate_array(ptrdiff_t size, ptrdiff_t extra_spa */ static void array_free_no_free(struct array *v) { - UNLINK_ARRAY(v); + DOUBLEUNLINK (first_array, v); free((char *)v); @@ -2216,8 +2217,17 @@ PMOD_EXPORT void check_array(struct array *a) { INT32 e; - if(a->next->prev != a) - Pike_fatal("Array check: a->next->prev != a\n"); + if(a->next && a->next->prev != a) + Pike_fatal("array->next->prev != array.\n"); + + if(a->prev) + { + if(a->prev->next != a) + Pike_fatal("array->prev->next != array.\n"); + }else{ + if(first_array != a) + Pike_fatal("array->prev == 0 but first_array != array.\n"); + } if(a->size > a->malloced_size) Pike_fatal("Array is larger than malloced block!\n"); @@ -2252,16 +2262,8 @@ PMOD_EXPORT void check_array(struct array *a) void check_all_arrays(void) { struct array *a; - - a=&empty_array; - do - { + for (a = first_array; a; a = a->next) check_array(a); - - a=a->next; - if(!a) - Pike_fatal("Null pointer in array list.\n"); - } while (a != & empty_array); } #endif /* PIKE_DEBUG */ @@ -2285,18 +2287,13 @@ void gc_mark_array_as_referenced(struct array *a) { if(gc_mark(a)) GC_ENTER (a, T_ARRAY) { -#ifdef PIKE_DEBUG - if (a == &empty_array || a == &weak_empty_array || a == &weak_shrink_empty_array) - Pike_fatal("Trying to gc mark some *_empty_array.\n"); -#endif - if (a == gc_mark_array_pos) gc_mark_array_pos = a->next; if (a == gc_internal_array) gc_internal_array = a->next; else { - UNLINK_ARRAY(a); - LINK_ARRAY(a); /* Linked in first. */ + DOUBLEUNLINK (first_array, a); + DOUBLELINK (first_array, a); /* Linked in first. */ } if (a->type_field & BIT_COMPLEX) @@ -2383,43 +2380,35 @@ void real_gc_cycle_check_array(struct array *a, int weak) unsigned gc_touch_all_arrays(void) { unsigned n = 0; - struct array *a = &empty_array; - do { + struct array *a; + if (!first_array || first_array->prev) + Pike_fatal ("error in array link list.\n"); + for (a = first_array; a; a = a->next) { debug_gc_touch(a); n++; - if (!a->next || a->next->prev != a) + if (a->next && a->next->prev != a) Pike_fatal("Error in array link list.\n"); - a=a->next; - } while (a != &empty_array); + } return n; } void gc_check_all_arrays(void) { struct array *a; - a=&empty_array; - do - { + for (a = first_array; a; a = a->next) { #ifdef PIKE_DEBUG if(d_flag > 1) array_check_type_field(a); #endif gc_check_array(a); - a=a->next; - } while (a != & empty_array); + } } void gc_mark_all_arrays(void) { gc_mark_array_pos = gc_internal_array; - gc_mark(&empty_array); - gc_mark(&weak_empty_array); - gc_mark(&weak_shrink_empty_array); - while (gc_mark_array_pos != &empty_array) { + while (gc_mark_array_pos) { struct array *a = gc_mark_array_pos; -#ifdef PIKE_DEBUG - if (!a) Pike_fatal("Null pointer in array list.\n"); -#endif gc_mark_array_pos = a->next; if(gc_is_referenced(a)) gc_mark_array_as_referenced(a); @@ -2429,7 +2418,7 @@ void gc_mark_all_arrays(void) void gc_cycle_check_all_arrays(void) { struct array *a; - for (a = gc_internal_array; a != &empty_array; a = a->next) { + for (a = gc_internal_array; a; a = a->next) { real_gc_cycle_check_array(a, 0); gc_cycle_run_queue(); } @@ -2437,7 +2426,7 @@ void gc_cycle_check_all_arrays(void) void gc_zap_ext_weak_refs_in_arrays(void) { - gc_mark_array_pos = empty_array.next; + gc_mark_array_pos = first_array; while (gc_mark_array_pos != gc_internal_array && gc_ext_weak_refs) { struct array *a = gc_mark_array_pos; gc_mark_array_pos = a->next; @@ -2451,7 +2440,7 @@ size_t gc_free_all_unreferenced_arrays(void) struct array *a,*next; size_t unreferenced = 0; - for (a = gc_internal_array; a != &weak_empty_array; a = next) + for (a = gc_internal_array; a; a = next) { #ifdef PIKE_DEBUG if (!a) @@ -2518,7 +2507,7 @@ void count_memory_in_arrays(INT32 *num_, INT32 *size_) { INT32 num=0, size=0; struct array *m; - for(m=empty_array.next;m!=&weak_empty_array;m=m->next) + for(m=first_array;m;m=m->next) { num++; size+=sizeof(struct array)+ diff --git a/src/array.h b/src/array.h index 51e059e2ce1fbcaab6376ffc3451db8483cda76f..84d6fe8c5ddd76e129cce1b4528b8b27e12167ec 100644 --- a/src/array.h +++ b/src/array.h @@ -2,7 +2,7 @@ || This file is part of Pike. For copyright information see COPYRIGHT. || Pike is distributed under GPL, LGPL and MPL. See the file COPYING || for more information. -|| $Id: array.h,v 1.54 2004/03/09 15:49:04 nilsson Exp $ +|| $Id: array.h,v 1.55 2004/03/15 22:23:14 mast Exp $ */ #ifndef ARRAY_H @@ -39,6 +39,7 @@ struct array #define ARRAY_WEAK_SHRINK 8 PMOD_EXPORT extern struct array empty_array, weak_empty_array, weak_shrink_empty_array; +extern struct array *first_array; extern struct array *gc_internal_array; #if defined(DEBUG_MALLOC) && defined(PIKE_DEBUG) @@ -47,19 +48,6 @@ extern struct array *gc_internal_array; #define ITEM(X) ((X)->item) #endif -#define LINK_ARRAY(a) do { \ - (a)->prev = &empty_array; \ - (a)->next = empty_array.next; \ - empty_array.next = (a); \ - (a)->next->prev = (a); \ -} while (0) - -#define UNLINK_ARRAY(a) do { \ - struct array *next = (a)->next, *prev = (a)->prev; \ - prev->next = next; \ - next->prev = prev; \ -} while (0) - /* These are arguments for the function 'merge' which merges two sorted * set stored in arrays in the way you specify */ diff --git a/src/gc.c b/src/gc.c index 4461bae5d03b16c91eccede818f84e6fea750a55..b0d9aaaf8ae296a606dec1737d9eb9ca1cd95495 100644 --- a/src/gc.c +++ b/src/gc.c @@ -2,7 +2,7 @@ || This file is part of Pike. For copyright information see COPYRIGHT. || Pike is distributed under GPL, LGPL and MPL. See the file COPYING || for more information. -|| $Id: gc.c,v 1.240 2004/03/15 19:03:48 mast Exp $ +|| $Id: gc.c,v 1.241 2004/03/15 22:23:14 mast Exp $ */ #include "global.h" @@ -33,7 +33,7 @@ struct callback *gc_evaluator_callback=0; #include "block_alloc.h" -RCSID("$Id: gc.c,v 1.240 2004/03/15 19:03:48 mast Exp $"); +RCSID("$Id: gc.c,v 1.241 2004/03/15 22:23:14 mast Exp $"); int gc_enabled = 1; @@ -284,12 +284,9 @@ int attempt_to_identify(void *something, void **inblock) if (inblock) *inblock = 0; - a=&empty_array; - do - { + for (a = first_array; a; a = a->next) { if(a==(struct array *)something) return T_ARRAY; - a=a->next; - }while(a!=&empty_array); + } for(o=first_object;o;o=o->next) { if(o==(struct object *)something) @@ -2196,7 +2193,7 @@ int gc_cycle_push(void *x, struct marker *m, int weak) struct program *p; struct mapping *m; struct multiset *l; - for(a = gc_internal_array; a != &empty_array; a = a->next) + for(a = gc_internal_array; a; a = a->next) if(a == (struct array *) x) goto on_gc_internal_lists; for(o = gc_internal_object; o; o = o->next) if(o == (struct object *) x) goto on_gc_internal_lists; @@ -2794,7 +2791,7 @@ size_t do_gc(void *ignored, int explicit_call) /* Anything after and including gc_internal_* in the linked lists * are considered to lack external references. The mark pass move * externally referenced things in front of these pointers. */ - gc_internal_array = empty_array.next; + gc_internal_array = first_array; gc_internal_multiset = first_multiset; gc_internal_mapping = first_mapping; gc_internal_program = first_program; @@ -2946,7 +2943,7 @@ size_t do_gc(void *ignored, int explicit_call) * added above are removed just before the calls so we'll get the * correct relative positions in them. */ unreferenced = 0; - if (gc_internal_array != &weak_empty_array) + if (gc_internal_array) unreferenced += gc_free_all_unreferenced_arrays(); if (gc_internal_multiset) unreferenced += gc_free_all_unreferenced_multisets(); diff --git a/src/main.c b/src/main.c index 4b4c470f85f35a3b2bfac20a617b892a20725744..23375d98d9440d5bbff778b9a3cd28c5ec49f33b 100644 --- a/src/main.c +++ b/src/main.c @@ -2,11 +2,11 @@ || This file is part of Pike. For copyright information see COPYRIGHT. || Pike is distributed under GPL, LGPL and MPL. See the file COPYING || for more information. -|| $Id: main.c,v 1.190 2004/03/10 09:40:00 grubba Exp $ +|| $Id: main.c,v 1.191 2004/03/15 22:23:14 mast Exp $ */ #include "global.h" -RCSID("$Id: main.c,v 1.190 2004/03/10 09:40:00 grubba Exp $"); +RCSID("$Id: main.c,v 1.191 2004/03/15 22:23:14 mast Exp $"); #include "fdlib.h" #include "backend.h" #include "module.h" @@ -984,10 +984,10 @@ void low_exit_main(void) search_all_memheaders_for_references(); -#define REPORT_LINKED_LIST_LEAKS(TYPE, START, END, T_TYPE, NAME) do { \ +#define REPORT_LINKED_LIST_LEAKS(TYPE, START, T_TYPE, NAME) do { \ size_t num = 0; \ struct TYPE *x; \ - for (x = START; x != END; x = x->next) { \ + for (x = START; x; x = x->next) { \ struct marker *m = find_marker (x); \ num++; \ if (!m) { \ @@ -1004,11 +1004,11 @@ void low_exit_main(void) fprintf (stderr, NAME "s left: %"PRINTSIZET"d\n", num); \ } while (0) - REPORT_LINKED_LIST_LEAKS (array, empty_array.next, &weak_empty_array, T_ARRAY, "Array"); - REPORT_LINKED_LIST_LEAKS (multiset, first_multiset, NULL, T_MULTISET, "Multiset"); - REPORT_LINKED_LIST_LEAKS (mapping, first_mapping, NULL, T_MAPPING, "Mapping"); - REPORT_LINKED_LIST_LEAKS (program, first_program, NULL, T_PROGRAM, "Program"); - REPORT_LINKED_LIST_LEAKS (object, first_object, NULL, T_OBJECT, "Object"); + REPORT_LINKED_LIST_LEAKS (array, first_array, T_ARRAY, "Array"); + REPORT_LINKED_LIST_LEAKS (multiset, first_multiset, T_MULTISET, "Multiset"); + REPORT_LINKED_LIST_LEAKS (mapping, first_mapping, T_MAPPING, "Mapping"); + REPORT_LINKED_LIST_LEAKS (program, first_program, T_PROGRAM, "Program"); + REPORT_LINKED_LIST_LEAKS (object, first_object, T_OBJECT, "Object"); #undef REPORT_LINKED_LIST_LEAKS @@ -1016,9 +1016,9 @@ void low_exit_main(void) * another gc so that we don't report the blocks again in the low * level dmalloc reports. */ -#define ZAP_LINKED_LIST_LEAKS(TYPE, START, END) do { \ +#define ZAP_LINKED_LIST_LEAKS(TYPE, START) do { \ struct TYPE *x; \ - for (x = START; x != END; x = x->next) { \ + for (x = START; x; x = x->next) { \ struct marker *m = find_marker (x); \ if (m) \ while (x->refs > m->refs) \ @@ -1026,11 +1026,11 @@ void low_exit_main(void) } \ } while (0) - ZAP_LINKED_LIST_LEAKS (array, empty_array.next, &weak_empty_array); - ZAP_LINKED_LIST_LEAKS (multiset, first_multiset, NULL); - ZAP_LINKED_LIST_LEAKS (mapping, first_mapping, NULL); - ZAP_LINKED_LIST_LEAKS (program, first_program, NULL); - ZAP_LINKED_LIST_LEAKS (object, first_object, NULL); + ZAP_LINKED_LIST_LEAKS (array, first_array); + ZAP_LINKED_LIST_LEAKS (multiset, first_multiset); + ZAP_LINKED_LIST_LEAKS (mapping, first_mapping); + ZAP_LINKED_LIST_LEAKS (program, first_program); + ZAP_LINKED_LIST_LEAKS (object, first_object); #undef ZAP_LINKED_LIST_LEAKS