diff --git a/src/array.c b/src/array.c index 0af45d6b64c55c82b839742219fd4de5ccda6cf8..4e6d8ffbc9c90375076d629bc9c633ba41b40793 100644 --- a/src/array.c +++ b/src/array.c @@ -23,18 +23,28 @@ #include "stuff.h" #include "bignum.h" -RCSID("$Id: array.c,v 1.105 2001/04/30 17:31:28 mast Exp $"); +RCSID("$Id: array.c,v 1.106 2001/06/06 02:22:38 mast Exp $"); PMOD_EXPORT struct array empty_array= { PIKE_CONSTANT_MEMOBJ_INIT(1), /* Never free */ - &empty_array, /* Next */ - &empty_array, /* previous (circular) */ + &weak_empty_array, /* Next */ + &weak_shrink_empty_array, /* previous (circular) */ 0, /* Size = 0 */ 0, /* malloced Size = 0 */ 0, /* no types */ 0, /* no flags */ }; +PMOD_EXPORT struct array weak_empty_array= +{ + PIKE_CONSTANT_MEMOBJ_INIT(1), + &weak_shrink_empty_array, &empty_array, 0, 0, 0, ARRAY_WEAK_FLAG +}; +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 +}; struct array *gc_internal_array = &empty_array; static struct array *gc_mark_array_pos = 0; @@ -101,8 +111,8 @@ static void array_free_no_free(struct array *v) PMOD_EXPORT void really_free_array(struct array *v) { #ifdef PIKE_DEBUG - if(v == & empty_array) - fatal("Tried to free the empty_array.\n"); + if(v == & empty_array || v == &weak_empty_array || v == &weak_shrink_empty_array) + fatal("Tried to free some *_empty_array.\n"); #endif #ifdef PIKE_DEBUG @@ -122,6 +132,26 @@ PMOD_EXPORT void do_free_array(struct array *a) free_array(a); } +PMOD_EXPORT struct array *array_set_flags(struct array *a, int flags) +{ + if (a->size) + a->flags = flags; + else { + free_array(a); + switch (flags) { + case 0: + add_ref(a = &empty_array); break; + case ARRAY_WEAK_FLAG: + add_ref(a = &weak_empty_array); break; + case ARRAY_WEAK_FLAG|ARRAY_WEAK_SHRINK: + add_ref(a = &weak_shrink_empty_array); break; + default: + fatal("Invalid flags %x\n", flags); + } + } + return a; +} + /* * Extract an svalue from an array */ @@ -1981,7 +2011,8 @@ void gc_mark_array_as_referenced(struct array *a) int e; if(gc_mark(a)) { #ifdef PIKE_DEBUG - if (a == &empty_array) fatal("Trying to gc mark empty_array.\n"); + if (a == &empty_array || a == &weak_empty_array || a == &weak_shrink_empty_array) + fatal("Trying to gc mark some *_empty_array.\n"); #endif if (a == gc_mark_array_pos) @@ -2048,7 +2079,8 @@ void real_gc_cycle_check_array(struct array *a, int weak) GC_CYCLE_ENTER(a, weak) { int e; #ifdef PIKE_DEBUG - if (a == &empty_array) fatal("Trying to gc cycle check empty_array.\n"); + if (a == &empty_array || a == &weak_empty_array || a == &weak_shrink_empty_array) + fatal("Trying to gc cycle check some *_empty_array.\n"); #endif if (a->type_field & BIT_COMPLEX) @@ -2110,6 +2142,8 @@ 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) { struct array *a = gc_mark_array_pos; #ifdef PIKE_DEBUG @@ -2145,7 +2179,7 @@ void gc_free_all_unreferenced_arrays(void) { struct array *a,*next; - for (a = gc_internal_array; a != &empty_array; a = next) + for (a = gc_internal_array; a != &weak_empty_array; a = next) { #ifdef PIKE_DEBUG if (!a) @@ -2193,7 +2227,10 @@ void debug_dump_array(struct array *a) a->flags, a->size, a->malloced_size, - a == &empty_array ? " (the empty_array)" : ""); + a == &empty_array ? " (the empty_array)" : + a == &weak_empty_array ? " (the weak_empty_array)" : + a == &weak_shrink_empty_array ? " (the weak_shrink_empty_array)" : + ""); fprintf(stderr,"Type field = "); debug_dump_type_field(a->type_field); fprintf(stderr,"\n"); @@ -2211,7 +2248,8 @@ void zap_all_arrays(void) { #if defined(PIKE_DEBUG) && defined(DEBUG_MALLOC) - if(verbose_debug_exit && a!=&empty_array) + if(verbose_debug_exit && a!=&empty_array && + a!=&weak_empty_array && a!=&weak_shrink_empty_array) describe(a); #endif @@ -2231,7 +2269,7 @@ void count_memory_in_arrays(INT32 *num_, INT32 *size_) { INT32 num=0, size=0; struct array *m; - for(m=empty_array.next;m!=&empty_array;m=m->next) + for(m=empty_array.next;m!=&weak_empty_array;m=m->next) { num++; size+=sizeof(struct array)+ diff --git a/src/array.h b/src/array.h index 54ad7cfc0d810aa939d302be3ba516e235348e50..aa8f74e5c20b8e0555d04f2db05a40451ab7e33b 100644 --- a/src/array.h +++ b/src/array.h @@ -5,7 +5,7 @@ \*/ /* - * $Id: array.h,v 1.34 2001/04/30 17:31:29 mast Exp $ + * $Id: array.h,v 1.35 2001/06/06 02:22:39 mast Exp $ */ #ifndef ARRAY_H #define ARRAY_H @@ -34,7 +34,7 @@ struct array #define ARRAY_LVALUE 4 #define ARRAY_WEAK_SHRINK 8 -PMOD_EXPORT extern struct array empty_array; +PMOD_EXPORT extern struct array empty_array, weak_empty_array, weak_shrink_empty_array; extern struct array *gc_internal_array; #if defined(DEBUG_MALLOC) && defined(PIKE_DEBUG) @@ -90,6 +90,7 @@ typedef short_cmpfun (*cmpfun_getter)(TYPE_T); PMOD_EXPORT struct array *low_allocate_array(ptrdiff_t size, ptrdiff_t extra_space); PMOD_EXPORT void really_free_array(struct array *v); PMOD_EXPORT void do_free_array(struct array *a); +PMOD_EXPORT struct array *array_set_flags(struct array *a, int flags); PMOD_EXPORT void array_index_no_free(struct svalue *s,struct array *v,INT32 index); PMOD_EXPORT void array_index(struct svalue *s,struct array *v,INT32 index); PMOD_EXPORT void simple_array_index_no_free(struct svalue *s, @@ -180,6 +181,8 @@ PMOD_EXPORT struct array *explode_array(struct array *a, struct array *b); PMOD_EXPORT struct array *implode_array(struct array *a, struct array *b); /* Prototypes end here */ +#define array_get_flags(a) ((a)->flags) + #define gc_cycle_check_array(X, WEAK) \ gc_cycle_enqueue((gc_cycle_check_cb *) real_gc_cycle_check_array, (X), (WEAK)) diff --git a/src/builtin_functions.c b/src/builtin_functions.c index 50172187dee3201a9d87a16185f53bbbe68cbf85..7b9db9a6d163a4a2b5a82562c3cd35e1705b9d31 100644 --- a/src/builtin_functions.c +++ b/src/builtin_functions.c @@ -5,7 +5,7 @@ \*/ /**/ #include "global.h" -RCSID("$Id: builtin_functions.c,v 1.372 2001/06/05 10:11:52 hubbe Exp $"); +RCSID("$Id: builtin_functions.c,v 1.373 2001/06/06 02:22:39 mast Exp $"); #include "interpret.h" #include "svalue.h" #include "pike_macros.h" @@ -3370,6 +3370,7 @@ void f_set_weak_flag(INT32 args) { struct svalue *s; INT_TYPE ret; + int flags; get_all_args("set_weak_flag",args,"%*%i",&s,&ret); @@ -3378,17 +3379,19 @@ void f_set_weak_flag(INT32 args) switch(s->type) { case T_ARRAY: - SETFLAG(s->u.array->flags,ARRAY_WEAK_FLAG,ret & PIKE_WEAK_VALUES); + flags = array_get_flags(s->u.array); + SETFLAG(flags,ARRAY_WEAK_FLAG,ret & PIKE_WEAK_VALUES); + s->u.array = array_set_flags(s->u.array, flags); break; - case T_MAPPING: { - int flags = mapping_get_flags(s->u.mapping); + case T_MAPPING: + flags = mapping_get_flags(s->u.mapping); flags = (flags & ~PIKE_WEAK_BOTH) | (ret & PIKE_WEAK_BOTH); mapping_set_flags(s->u.mapping, flags); break; - } case T_MULTISET: - SETFLAG(s->u.multiset->ind->flags,(ARRAY_WEAK_FLAG|ARRAY_WEAK_SHRINK), - ret & PIKE_WEAK_INDICES); + flags = array_get_flags(s->u.multiset->ind); + SETFLAG(flags,(ARRAY_WEAK_FLAG|ARRAY_WEAK_SHRINK), ret & PIKE_WEAK_INDICES); + s->u.multiset->ind = array_set_flags(s->u.multiset->ind, flags); break; default: SIMPLE_BAD_ARG_ERROR("set_weak_flag",1,"array|mapping|multiset"); diff --git a/src/gc.c b/src/gc.c index bce638854090358abcfb303447c8d6b7873265b2..35b1753a3100fcc9d9358816ae7bffc1169dbec9 100644 --- a/src/gc.c +++ b/src/gc.c @@ -30,7 +30,7 @@ struct callback *gc_evaluator_callback=0; #include "block_alloc.h" -RCSID("$Id: gc.c,v 1.151 2001/05/19 05:30:18 mast Exp $"); +RCSID("$Id: gc.c,v 1.152 2001/06/06 02:22:39 mast Exp $"); /* Run garbage collect approximately every time * 20 percent of all arrays, objects and programs is @@ -95,7 +95,7 @@ RCSID("$Id: gc.c,v 1.151 2001/05/19 05:30:18 mast Exp $"); #define GC_VERBOSE_DO(X) #endif -INT32 num_objects = 1; /* Account for empty_array. */ +INT32 num_objects = 3; /* Account for *_empty_array. */ INT32 num_allocs =0; ptrdiff_t alloc_threshold = MIN_ALLOC_THRESHOLD; PMOD_EXPORT int Pike_in_gc = 0;