diff --git a/src/array.c b/src/array.c index fb4ef40079a2f38cfae742e85de97cb24d006ac6..ccfbf4c355eede6ee2445103dc8e4e8c2746fd6a 100644 --- a/src/array.c +++ b/src/array.c @@ -23,7 +23,7 @@ #include "stuff.h" #include "bignum.h" -RCSID("$Id: array.c,v 1.73 2000/06/09 22:43:04 mast Exp $"); +RCSID("$Id: array.c,v 1.74 2000/07/04 00:43:56 mast Exp $"); struct array empty_array= { @@ -1784,25 +1784,15 @@ static void gc_check_array(struct array *a) { if(a->type_field & BIT_COMPLEX) { - TYPE_FIELD t; if (a->flags & ARRAY_WEAK_FLAG) - t=debug_gc_check_weak_svalues(ITEM(a), a->size, T_ARRAY, a); + debug_gc_check_weak_svalues(ITEM(a), a->size, T_ARRAY, a); else - t=debug_gc_check_svalues(ITEM(a), a->size, T_ARRAY, a); - - /* Ugly, but we are not allowed to change type_field - * at the same time as the array is being built... - * Actually we just need better primitives for building arrays. - */ - if(!(a->type_field & BIT_UNFINISHED) || a->refs!=1) - a->type_field = t; - else - a->type_field |= t; + debug_gc_check_svalues(ITEM(a), a->size, T_ARRAY, a); } } static void gc_recurse_weak_array(struct array *a, - TYPE_FIELD (*recurse_fn)(struct svalue *, int)) + TYPE_FIELD (*recurse_fn)(struct svalue *, size_t)) { int e; TYPE_FIELD t; @@ -1857,8 +1847,15 @@ void gc_mark_array_as_referenced(struct array *a) { if (a->flags & ARRAY_WEAK_FLAG) gc_recurse_weak_array(a, gc_mark_weak_svalues); - else - gc_mark_svalues(ITEM(a), a->size); + else { + TYPE_FIELD t; + if ((t = gc_mark_svalues(ITEM(a), a->size))) { + if(!(a->type_field & BIT_UNFINISHED) || a->refs!=1) + a->type_field = t; + else + a->type_field |= t; + } + } } } } @@ -1874,8 +1871,15 @@ static void low_gc_cycle_check_array(struct array *a) { if (a->flags & ARRAY_WEAK_FLAG) gc_recurse_weak_array(a, gc_cycle_check_weak_svalues); - else - gc_cycle_check_svalues(ITEM(a), a->size); + else { + TYPE_FIELD t; + if ((t = gc_cycle_check_svalues(ITEM(a), a->size))) { + if(!(a->type_field & BIT_UNFINISHED) || a->refs!=1) + a->type_field = t; + else + a->type_field |= t; + } + } } } diff --git a/src/gc.c b/src/gc.c index 96ff37c2fcad12019a29d1348da57ce25789394c..18ad5dcb8618aa283c5881030828268a0619a795 100644 --- a/src/gc.c +++ b/src/gc.c @@ -29,7 +29,7 @@ struct callback *gc_evaluator_callback=0; #include "block_alloc.h" -RCSID("$Id: gc.c,v 1.100 2000/07/03 18:38:26 mast Exp $"); +RCSID("$Id: gc.c,v 1.101 2000/07/04 00:43:57 mast Exp $"); /* Run garbage collect approximately every time * 20 percent of all arrays, objects and programs is @@ -453,26 +453,22 @@ void debug_gc_xmark_svalues(struct svalue *s, int num, char *fromwhere) found_in=0; } -TYPE_FIELD debug_gc_check_svalues(struct svalue *s, int num, TYPE_T t, void *data) +void debug_gc_check_svalues(struct svalue *s, int num, TYPE_T t, void *data) { - TYPE_FIELD ret; found_in=data; found_in_type=t; - ret=gc_check_svalues(s,num); + gc_check_svalues(s,num); found_in_type=T_UNKNOWN; found_in=0; - return ret; } -TYPE_FIELD debug_gc_check_weak_svalues(struct svalue *s, int num, TYPE_T t, void *data) +void debug_gc_check_weak_svalues(struct svalue *s, int num, TYPE_T t, void *data) { - TYPE_FIELD ret; found_in=data; found_in_type=t; - ret=gc_check_weak_svalues(s,num); + gc_check_weak_svalues(s,num); found_in_type=T_UNKNOWN; found_in=0; - return ret; } void debug_gc_check_short_svalue(union anything *u, TYPE_T type, TYPE_T t, void *data) diff --git a/src/gc.h b/src/gc.h index 2ab06c39585510afb44f402aa8ad046055f19643..2cf31512f88a69c5ea932af03d33ccc3396e346f 100644 --- a/src/gc.h +++ b/src/gc.h @@ -1,5 +1,5 @@ /* - * $Id: gc.h,v 1.52 2000/07/03 16:50:09 mast Exp $ + * $Id: gc.h,v 1.53 2000/07/04 00:43:57 mast Exp $ */ #ifndef GC_H #define GC_H @@ -49,24 +49,18 @@ extern void *gc_svalue_location; } while(0) #endif -#define LOW_GC_FREE() do { \ +#define GC_FREE() do { \ DO_IF_DEBUG( \ extern int d_flag; \ if(d_flag) CHECK_INTERPRETER_LOCK(); \ + if(Pike_in_gc == GC_PASS_CHECK) \ + fatal("Freeing objects in this gc pass is not allowed.\n"); \ if(num_objects < 1) \ fatal("Panic!! less than zero objects!\n"); \ ) \ num_objects-- ; \ }while(0) -#define GC_FREE() do { \ - DO_IF_DEBUG( \ - if(Pike_in_gc == GC_PASS_CHECK) \ - fatal("Freeing objects in this gc pass is not allowed.\n"); \ - ); \ - LOW_GC_FREE(); \ -} while (0) - struct marker { struct marker *next; @@ -123,8 +117,8 @@ void describe_location(void *memblock, int type, void *location,int indent, int void debug_gc_fatal(void *a, int flags, const char *fmt, ...) ATTRIBUTE((format(printf, 3, 4))); void debug_gc_xmark_svalues(struct svalue *s, int num, char *fromwhere); -TYPE_FIELD debug_gc_check_svalues(struct svalue *s, int num, TYPE_T t, void *data); -TYPE_FIELD debug_gc_check_weak_svalues(struct svalue *s, int num, TYPE_T t, void *data); +void debug_gc_check_svalues(struct svalue *s, int num, TYPE_T t, void *data); +void debug_gc_check_weak_svalues(struct svalue *s, int num, TYPE_T t, void *data); void debug_gc_check_short_svalue(union anything *u, TYPE_T type, TYPE_T t, void *data); void debug_gc_check_weak_short_svalue(union anything *u, TYPE_T type, TYPE_T t, void *data); int debug_gc_check(void *x, TYPE_T t, void *data); diff --git a/src/mapping.c b/src/mapping.c index 8e020ae11e25d86388ed05165e13ce39f9e70b04..ce79e7a21352cba54b656a7b7bed2e64156c6c69 100644 --- a/src/mapping.c +++ b/src/mapping.c @@ -5,7 +5,7 @@ \*/ /**/ #include "global.h" -RCSID("$Id: mapping.c,v 1.89 2000/07/03 20:14:07 mast Exp $"); +RCSID("$Id: mapping.c,v 1.90 2000/07/04 00:43:57 mast Exp $"); #include "main.h" #include "object.h" #include "mapping.h" @@ -1891,8 +1891,13 @@ void gc_mark_mapping_as_referenced(struct mapping *m) else NEW_MAPPING_LOOP(m->data) { - gc_mark_svalues(&k->ind, 1); - gc_mark_svalues(&k->val, 1); + if (gc_mark_svalues(&k->ind, 1) || + gc_mark_svalues(&k->val, 1)) { +#ifdef PIKE_DEBUG + fatal("Looks like check_mapping_for_destruct " + "didn't do its job properly.\n"); +#endif + } } } } @@ -1915,8 +1920,13 @@ void low_gc_cycle_check_mapping(struct mapping *m) else NEW_MAPPING_LOOP(m->data) { - gc_cycle_check_svalues(&k->ind, 1); - gc_cycle_check_svalues(&k->val, 1); + if (gc_cycle_check_svalues(&k->ind, 1) || + gc_cycle_check_svalues(&k->val, 1)) { +#ifdef PIKE_DEBUG + fatal("Looks like check_mapping_for_destruct " + "didn't do its job properly.\n"); +#endif + } } } } @@ -1955,8 +1965,7 @@ static void gc_check_mapping(struct mapping *m) continue; debug_gc_check_weak_svalues(&k->ind, 1, T_MAPPING, m); - m->data->val_types |= - debug_gc_check_weak_svalues(&k->val, 1, T_MAPPING, m); + debug_gc_check_weak_svalues(&k->val, 1, T_MAPPING, m); } } else { @@ -1970,8 +1979,7 @@ static void gc_check_mapping(struct mapping *m) continue; debug_gc_check_svalues(&k->ind, 1, T_MAPPING, m); - m->data->val_types |= - debug_gc_check_svalues(&k->val, 1, T_MAPPING, m); + debug_gc_check_svalues(&k->val, 1, T_MAPPING, m); } } } diff --git a/src/object.c b/src/object.c index 64425d970bfa9ce9488f1e927fcebcdacf22eb29..1a80fa5e4685aa06bf4eb248815ac85e2258574a 100644 --- a/src/object.c +++ b/src/object.c @@ -5,7 +5,7 @@ \*/ /**/ #include "global.h" -RCSID("$Id: object.c,v 1.130 2000/07/03 18:38:55 mast Exp $"); +RCSID("$Id: object.c,v 1.131 2000/07/04 00:43:57 mast Exp $"); #include "object.h" #include "dynamic_buffer.h" #include "interpret.h" @@ -734,8 +734,7 @@ void schedule_really_free_object(struct object *o) /* It's a fake object which isn't counted by the gc, so * counteract the num_objects-- done by GC_FREE. */ num_objects++; - /* This is the only free allowed in the gc check pass. */ - LOW_GC_FREE(); + GC_FREE(); FREE_PROT(o); diff --git a/src/svalue.c b/src/svalue.c index 28ad48b240df07de5eac8ba3431d8ea2657d6652..d2032aba1fa60f10c1ea1ea6710430ac238f2cc6 100644 --- a/src/svalue.c +++ b/src/svalue.c @@ -23,7 +23,7 @@ #include "queue.h" #include "bignum.h" -RCSID("$Id: svalue.c,v 1.80 2000/07/03 20:14:07 mast Exp $"); +RCSID("$Id: svalue.c,v 1.81 2000/07/04 00:43:57 mast Exp $"); struct svalue dest_ob_zero = { T_INT, 0 }; @@ -1283,86 +1283,63 @@ void real_gc_xmark_svalues(struct svalue *s, ptrdiff_t num) fatal("Cannot have a function in a short svalue.\n"); #define DO_CHECK_OBJ(U, T, ZAP, GC_DO) \ - if (U.object->prog) \ - GC_DO(U.object); \ - else ZAP(); \ + GC_DO(U.object); \ break; #define DO_CHECK_OBJ_WEAK(U, T, ZAP, GC_DO) \ - if(U.object->prog) \ - if (U.object->prog->flags & PROGRAM_NO_WEAK_FREE) \ - gc_check(U.object); \ - else \ - gc_check_weak(U.object); \ - else ZAP(); \ + if (U.object->prog && \ + !(U.object->prog->flags & PROGRAM_NO_WEAK_FREE)) \ + gc_check_weak(U.object); \ + else \ + gc_check(U.object); \ break; -#define ZAP_SVALUE() \ - do { \ - free_svalue(s); \ - s->type = T_INT; \ - s->u.integer = 0; \ - s->subtype = NUMBER_DESTRUCTED; \ - } while (0) - -#define ZAP_SHORT_SVALUE() \ - do { \ - free_short_svalue(u, type); \ - u->refs = 0; \ - } while (0) +#define NEVER_ZAP() #define SET_SUB_SVALUE(V) s->subtype = (V) #define SET_SUB_SHORT_SVALUE(V) -TYPE_FIELD real_gc_check_svalues(struct svalue *s, size_t num) +void real_gc_check_svalues(struct svalue *s, size_t num) { #ifdef PIKE_DEBUG extern void * check_for; #endif size_t e; - TYPE_FIELD f; - f=0; for(e=0;e<num;e++,s++) { check_svalue(s); #ifdef PIKE_DEBUG gc_svalue_location=(void *)s; #endif - GC_CHECK_SWITCH((s->u), (s->type), ZAP_SVALUE, gc_check, + GC_CHECK_SWITCH((s->u), (s->type), NEVER_ZAP, gc_check, {}, DO_CHECK_FUNC_SVALUE, DO_CHECK_OBJ); - f|= 1 << s->type; } #ifdef PIKE_DEBUG gc_svalue_location=0; #endif - return f; } -TYPE_FIELD gc_check_weak_svalues(struct svalue *s, size_t num) +void gc_check_weak_svalues(struct svalue *s, size_t num) { #ifdef PIKE_DEBUG extern void * check_for; #endif size_t e; - TYPE_FIELD f; - f=0; for(e=0;e<num;e++,s++) { check_svalue(s); #ifdef PIKE_DEBUG gc_svalue_location=(void *)s; #endif - GC_CHECK_SWITCH((s->u), (s->type), ZAP_SVALUE, gc_check_weak, + GC_CHECK_SWITCH((s->u), (s->type), NEVER_ZAP, gc_check_weak, {}, DO_CHECK_FUNC_SVALUE, DO_CHECK_OBJ_WEAK); - f|= 1 << s->type; } #ifdef PIKE_DEBUG gc_svalue_location=0; #endif - return f; } void real_gc_check_short_svalue(union anything *u, TYPE_T type) @@ -1372,7 +1349,7 @@ void real_gc_check_short_svalue(union anything *u, TYPE_T type) gc_svalue_location=(void *)u; #endif debug_malloc_touch(u); - GC_CHECK_SWITCH((*u), type, ZAP_SHORT_SVALUE, gc_check, + GC_CHECK_SWITCH((*u), type, NEVER_ZAP, gc_check, {if (!u->refs) return;}, DO_FUNC_SHORT_SVALUE, DO_CHECK_OBJ); #ifdef PIKE_DEBUG @@ -1387,7 +1364,7 @@ void gc_check_weak_short_svalue(union anything *u, TYPE_T type) gc_svalue_location=(void *)u; #endif debug_malloc_touch(u); - GC_CHECK_SWITCH((*u), type, ZAP_SHORT_SVALUE, gc_check_weak, + GC_CHECK_SWITCH((*u), type, NEVER_ZAP, gc_check_weak, {if (!u->refs) return;}, DO_FUNC_SHORT_SVALUE, DO_CHECK_OBJ_WEAK); #ifdef PIKE_DEBUG @@ -1395,17 +1372,31 @@ void gc_check_weak_short_svalue(union anything *u, TYPE_T type) #endif } +#define ZAP_SVALUE() \ + do { \ + free_svalue(s); \ + s->type = T_INT; \ + s->u.integer = 0; \ + s->subtype = NUMBER_DESTRUCTED; \ + } while (0) + +#define ZAP_SHORT_SVALUE() \ + do { \ + free_short_svalue(u, type); \ + u->refs = 0; \ + } while (0) + #define GC_RECURSE_SWITCH(U,T,ZAP,FREE_WEAK,GC_DO,PRE,DO_FUNC,DO_STR) \ switch (T) { \ case T_FUNCTION: \ PRE DO_FUNC(U, T, ZAP, GC_DO) \ case T_OBJECT: \ PRE \ - DO_IF_DEBUG( \ - if (!U.object->prog) \ - gc_fatal(U.object, 0, \ - "Unfreed destructed object in mark pass.\n"); \ - ) \ + if (!U.object->prog) { \ + ZAP(); \ + freed = 1; \ + break; \ + } \ FREE_WEAK(U, T, ZAP) GC_DO(U, object); \ break; \ case T_STRING: \ @@ -1449,8 +1440,10 @@ void gc_check_weak_short_svalue(union anything *u, TYPE_T type) break; \ } -void real_gc_mark_svalues(struct svalue *s, size_t num) +TYPE_FIELD real_gc_mark_svalues(struct svalue *s, size_t num) { + TYPE_FIELD t = 0; + int freed = 0; size_t e; for(e=0;e<num;e++,s++) { @@ -1458,7 +1451,9 @@ void real_gc_mark_svalues(struct svalue *s, size_t num) GC_RECURSE_SWITCH((s->u), (s->type), ZAP_SVALUE, DONT_FREE_WEAK, GC_DO_MARK, {}, DO_MARK_FUNC_SVALUE, DO_MARK_STRING); + t |= 1 << s->type; } + return freed ? t : 0; } TYPE_FIELD gc_mark_weak_svalues(struct svalue *s, size_t num) @@ -1477,12 +1472,14 @@ TYPE_FIELD gc_mark_weak_svalues(struct svalue *s, size_t num) return freed ? t : 0; } -void real_gc_mark_short_svalue(union anything *u, TYPE_T type) +int real_gc_mark_short_svalue(union anything *u, TYPE_T type) { + int freed = 0; debug_malloc_touch(u); GC_RECURSE_SWITCH((*u), type, ZAP_SHORT_SVALUE, DONT_FREE_WEAK, - GC_DO_MARK, {if (!u->refs) return;}, + GC_DO_MARK, {if (!u->refs) return 0;}, DO_FUNC_SHORT_SVALUE, DO_MARK_STRING); + return freed; } int gc_mark_weak_short_svalue(union anything *u, TYPE_T type) @@ -1504,8 +1501,10 @@ int gc_mark_weak_short_svalue(union anything *u, TYPE_T type) #define GC_DO_CYCLE_CHECK(U, TN) PIKE_CONCAT(gc_cycle_check_, TN)(U.TN) #define GC_DO_CYCLE_CHECK_WEAK(U, TN) PIKE_CONCAT3(gc_cycle_check_, TN, _weak)(U.TN) -void real_gc_cycle_check_svalues(struct svalue *s, size_t num) +TYPE_FIELD real_gc_cycle_check_svalues(struct svalue *s, size_t num) { + TYPE_FIELD t = 0; + int freed = 0; size_t e; for(e=0;e<num;e++,s++) { @@ -1513,7 +1512,9 @@ void real_gc_cycle_check_svalues(struct svalue *s, size_t num) GC_RECURSE_SWITCH((s->u), (s->type), ZAP_SVALUE, DONT_FREE_WEAK, GC_DO_CYCLE_CHECK, {}, DO_CYCLE_CHECK_FUNC_SVALUE, DO_CYCLE_CHECK_STRING); + t |= 1 << s->type; } + return freed ? t : 0; } TYPE_FIELD gc_cycle_check_weak_svalues(struct svalue *s, size_t num) @@ -1532,12 +1533,14 @@ TYPE_FIELD gc_cycle_check_weak_svalues(struct svalue *s, size_t num) return freed ? t : 0; } -void real_gc_cycle_check_short_svalue(union anything *u, TYPE_T type) +int real_gc_cycle_check_short_svalue(union anything *u, TYPE_T type) { + int freed = 0; debug_malloc_touch(u); GC_RECURSE_SWITCH((*u), type, ZAP_SHORT_SVALUE, DONT_FREE_WEAK, - GC_DO_CYCLE_CHECK, {if (!u->refs) return;}, + GC_DO_CYCLE_CHECK, {if (!u->refs) return 0;}, DO_FUNC_SHORT_SVALUE, DO_CYCLE_CHECK_STRING); + return freed; } int gc_cycle_check_weak_short_svalue(union anything *u, TYPE_T type) diff --git a/src/svalue.h b/src/svalue.h index 293dc1e338816b90d1141483323bcfaf33ae5bfb..8951eeb5d6db1c8448ff732357bb4339e1fb8528 100644 --- a/src/svalue.h +++ b/src/svalue.h @@ -5,7 +5,7 @@ \*/ /* - * $Id: svalue.h,v 1.59 2000/07/03 20:14:08 mast Exp $ + * $Id: svalue.h,v 1.60 2000/07/04 00:43:58 mast Exp $ */ #ifndef SVALUE_H #define SVALUE_H @@ -375,16 +375,16 @@ void copy_svalues_recursively_no_free(struct svalue *to, void check_short_svalue(union anything *u, TYPE_T type); void debug_check_svalue(struct svalue *s); void real_gc_xmark_svalues(struct svalue *s, ptrdiff_t num); -TYPE_FIELD real_gc_check_svalues(struct svalue *s, size_t num); +void real_gc_check_svalues(struct svalue *s, size_t num); void real_gc_check_short_svalue(union anything *u, TYPE_T type); -TYPE_FIELD gc_check_weak_svalues(struct svalue *s, size_t num); +void gc_check_weak_svalues(struct svalue *s, size_t num); void gc_check_weak_short_svalue(union anything *u, TYPE_T type); -void real_gc_mark_svalues(struct svalue *s, size_t num); -void real_gc_mark_short_svalue(union anything *u, TYPE_T type); +TYPE_FIELD real_gc_mark_svalues(struct svalue *s, size_t num); +int real_gc_mark_short_svalue(union anything *u, TYPE_T type); TYPE_FIELD gc_mark_weak_svalues(struct svalue *s, size_t num); int gc_mark_weak_short_svalue(union anything *u, TYPE_T type); -void real_gc_cycle_check_svalues(struct svalue *s, size_t num); -void real_gc_cycle_check_short_svalue(union anything *u, TYPE_T type); +TYPE_FIELD real_gc_cycle_check_svalues(struct svalue *s, size_t num); +int real_gc_cycle_check_short_svalue(union anything *u, TYPE_T type); TYPE_FIELD gc_cycle_check_weak_svalues(struct svalue *s, size_t num); int gc_cycle_check_weak_short_svalue(union anything *u, TYPE_T type); INT32 pike_sizeof(struct svalue *s);