diff --git a/src/gc.c b/src/gc.c index 468212808f2139ca9409e8c7ddc8b050c6a511ba..8c944de87285e44c374ecccdc6b240cc6232d1a5 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.71 2000/04/19 18:06:45 mast Exp $"); +RCSID("$Id: gc.c,v 1.72 2000/04/19 21:25:33 mast Exp $"); /* Run garbage collect approximate every time we have * 20 percent of all arrays, objects and programs is @@ -151,7 +151,7 @@ void describe_location(void *real_memblock, if(!location) return; /* fprintf(stderr,"**Location of (short) svalue: %p\n",location); */ - if(real_type!=-1) real_memblock=memblock; + if(real_type!=-1) memblock=real_memblock; #ifdef DEBUG_MALLOC if(memblock == 0 || type == -1) @@ -506,7 +506,7 @@ void describe_something(void *a, int t, int indent, int depth, int flags) } else #endif /* DEBUG_MALLOC */ if (((int)a) & 3) { - fprintf(stderr,"%*s**Location: %p Type: %s Missaligned address\n",indent,"",a, + fprintf(stderr,"%*s**Location: %p Type: %s Misaligned address\n",indent,"",a, get_name_of_type(t)); } else { fprintf(stderr,"%*s**Location: %p Type: %s Refs: %d\n",indent,"",a, @@ -514,13 +514,13 @@ void describe_something(void *a, int t, int indent, int depth, int flags) *(INT32 *)a); } - low_describe_something(a,t,indent,depth,flags); - #ifdef DEBUG_MALLOC if(!(flags & DESCRIBE_NO_DMALLOC)) debug_malloc_dump_references(a,indent+2,depth-1,flags); #endif + low_describe_something(a,t,indent,depth,flags); + fprintf(stderr,"%*s*******************\n",indent,""); d_flag=tmp; @@ -571,7 +571,7 @@ void debug_describe_svalue(struct svalue *s) INT32 real_gc_check(void *a) { struct marker *m=get_marker(a); - + #ifdef PIKE_DEBUG if(check_for) { @@ -597,6 +597,9 @@ INT32 real_gc_check(void *a) return 0; } + if (Pike_in_gc != 1) + fatal("gc check attempted in pass %d.\n", Pike_in_gc); + if(m->saved_refs != -1) if(m->saved_refs != *(INT32 *)a) { fprintf(stderr,"**Refs changed in gc() pass %d. Expected %ld, got %ld.\n", @@ -807,6 +810,11 @@ int gc_mark(void *a) struct marker *m; m=get_marker(debug_malloc_pass(a)); +#ifdef PIKE_DEBUG + if (Pike_in_gc != 2) + fatal("gc mark attempted in pass %d.\n", Pike_in_gc); +#endif + if(m->flags & GC_REFERENCED) { return 0; @@ -870,6 +878,8 @@ void do_gc(void) gc_evaluator_callback=0; } + remove_objects_to_destruct_callback(); + tmp2=num_objects; #ifdef PIKE_DEBUG diff --git a/src/gc.h b/src/gc.h index b1857a516ed91d52088f7be41a357ee207547af6..b539f0ffa816c0a3339c4ed4c346f4b7d8fa1273 100644 --- a/src/gc.h +++ b/src/gc.h @@ -1,5 +1,5 @@ /* - * $Id: gc.h,v 1.35 2000/04/19 16:05:19 mast Exp $ + * $Id: gc.h,v 1.36 2000/04/19 21:25:33 mast Exp $ */ #ifndef GC_H #define GC_H @@ -125,7 +125,10 @@ void f__gc_status(INT32 args); #define GC_REFERENCED 1 #define GC_XREFERENCED 2 #define GC_CHECKED 4 - +#ifdef PIKE_DEBUG +#define GC_DO_FREE_OBJ 8 +#define GC_OBJ_PASS_4 16 +#endif #ifdef PIKE_DEBUG #define gc_is_referenced(X) debug_gc_is_referenced(debug_malloc_pass(X)) diff --git a/src/object.c b/src/object.c index 27e93791d15804df12b49accb47b46f26ddc5cb6..30398435c1a88ab93d1c8908751326a2041c7fdf 100644 --- a/src/object.c +++ b/src/object.c @@ -5,7 +5,7 @@ \*/ /**/ #include "global.h" -RCSID("$Id: object.c,v 1.113 2000/04/19 14:00:43 mast Exp $"); +RCSID("$Id: object.c,v 1.114 2000/04/19 21:25:33 mast Exp $"); #include "object.h" #include "dynamic_buffer.h" #include "interpret.h" @@ -551,6 +551,15 @@ void destruct(struct object *o) static struct object *objects_to_destruct = 0; static struct callback *destruct_object_evaluator_callback =0; +void remove_objects_to_destruct_callback(void) +{ + if(destruct_object_evaluator_callback) + { + remove_callback(destruct_object_evaluator_callback); + destruct_object_evaluator_callback=0; + } +} + /* This function destructs the objects that are scheduled to be * destructed by really_free_object. It links the object back into the * list of objects first. Adds a reference, destructs it and then frees it. @@ -560,6 +569,11 @@ void destruct_objects_to_destruct(void) struct object *my_list=0; struct object *o, *next; +#ifdef PIKE_DEBUG + if (Pike_in_gc >= 3 && Pike_in_gc <= 4) + fatal("Can't meddle with the object link list in gc pass %d.\n", Pike_in_gc); +#endif + while((o=objects_to_destruct)) { /* Link object back to list of objects */ @@ -576,11 +590,7 @@ void destruct_objects_to_destruct(void) free_object(o); } - if(destruct_object_evaluator_callback) - { - remove_callback(destruct_object_evaluator_callback); - destruct_object_evaluator_callback=0; - } + remove_objects_to_destruct_callback(); } @@ -606,6 +616,8 @@ void really_free_object(struct object *o) if(o->prog) { + DOUBLELINK(objects_to_destruct,o); + if (Pike_in_gc) return; /* Done last in gc(). */ if(!destruct_object_evaluator_callback) { destruct_object_evaluator_callback= @@ -613,8 +625,6 @@ void really_free_object(struct object *o) (callback_func)destruct_objects_to_destruct, 0,0); } - - DOUBLELINK(objects_to_destruct,o); } else { if(o->parent) { @@ -1244,9 +1254,15 @@ void gc_free_all_unreferenced_objects(void) for(o=first_object;o;o=o->next) { +#ifdef PIKE_DEBUG + get_marker(o)->flags |= GC_OBJ_PASS_4; +#endif if(gc_do_free(o)) { add_ref(o); +#ifdef PIKE_DEBUG + get_marker(o)->flags |= GC_DO_FREE_OBJ; +#endif call_destroy(o,0); } } @@ -1255,6 +1271,18 @@ void gc_free_all_unreferenced_objects(void) { if(gc_do_free(o)) { +#ifdef PIKE_DEBUG + if (!(get_marker(o)->flags & GC_DO_FREE_OBJ) || + !(get_marker(o)->flags & GC_OBJ_PASS_4)) { + extern char *fatal_after_gc; + fprintf(stderr,"**Object unexpectedly marked for gc. flags: %d\n", + get_marker(o)->flags); + describe(o); + locate_references(o); + fprintf(stderr,"##### Continuing search for more bugs....\n"); + fatal_after_gc="Object unexpectedly marked for gc.\n"; + } +#endif low_destruct(o,1); SET_NEXT_AND_FREE(o,free_object); }else{ diff --git a/src/object.h b/src/object.h index ffe23ee9597d19e6b9345424e8b5b5264c409436..ab20a180aa894876d7dbc690f9b26fd844cc66bd 100644 --- a/src/object.h +++ b/src/object.h @@ -5,7 +5,7 @@ \*/ /* - * $Id: object.h,v 1.41 2000/04/13 20:14:35 hubbe Exp $ + * $Id: object.h,v 1.42 2000/04/19 21:25:33 mast Exp $ */ #ifndef OBJECT_H #define OBJECT_H @@ -66,6 +66,7 @@ struct destroy_called_mark; PTR_HASH_ALLOC(destroy_called_mark,128) void low_destruct(struct object *o,int do_free); void destruct(struct object *o); +void remove_objects_to_destruct_callback(void); void destruct_objects_to_destruct(void); void really_free_object(struct object *o); void low_object_index_no_free(struct svalue *to,