diff --git a/Makefile b/Makefile index c7aaaf3930eeeb8e533d9467bfef1ab350c532c0..3e294fc24a7e0e175a866471069bb7ac4437fb1b 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,5 @@ # -# $Id: Makefile,v 1.167 2008/08/17 20:21:13 mast Exp $ +# $Id: Makefile,v 1.168 2009/11/28 13:36:19 mast Exp $ # # Meta Makefile # @@ -15,11 +15,11 @@ # Set to a flag for parallelizing make, e.g. -j2. It's given to make # at the level where it's most effective. -#MAKE_PARALLEL=-j`test -f /proc/cpuinfo && grep ^processor /proc/cpuinfo | wc -l || echo 1` +MAKE_PARALLEL=-j`test -f /proc/cpuinfo && grep ^processor /proc/cpuinfo | wc -l || echo 1` # Tip: Remove "-r" from the line below if you don't want to rebuild # from scratch every time you upgrade the kernel. -OS=`uname -s -r -m|sed \"s/ /-/g\"|tr \"[A-Z]\" \"[a-z]\"|tr \"/()\" \"___\"` +OS=`uname -s -m|sed \"s/ /-/g\"|tr \"[A-Z]\" \"[a-z]\"|tr \"/()\" \"___\"` VPATH=. BUILDDIR=build/$(OS) diff --git a/src/array.c b/src/array.c index c2442c2e2435922f5880c61536293b2a8e0369ab..8acb9a3e70fcf5effdbfcf7159fe843496b8b909 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.225 2009/11/28 13:14:00 mast Exp $ +|| $Id: array.c,v 1.226 2009/11/28 13:36:20 mast Exp $ */ #include "global.h" @@ -2689,7 +2689,7 @@ static void gc_check_array(struct array *a) void gc_mark_array_as_referenced(struct array *a) { - if(gc_mark(a)) + if(gc_mark(a, T_ARRAY)) GC_ENTER (a, T_ARRAY) { if (a == gc_mark_array_pos) gc_mark_array_pos = a->next; diff --git a/src/gc.c b/src/gc.c index 72068d5b0f5b57e35b1586e57f484a049686a1be..f8feb134ecc53cf14405efa8bedabc05274092bf 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.337 2009/11/28 11:49:47 mast Exp $ +|| $Id: gc.c,v 1.338 2009/11/28 13:36:20 mast Exp $ */ #include "global.h" @@ -993,7 +993,7 @@ static void describe_marker(struct marker *m) #endif /* PIKE_DEBUG */ -static void debug_gc_fatal_va (void *a, int flags, +static void debug_gc_fatal_va (void *a, int type, int flags, const char *fmt, va_list args) { #ifdef PIKE_DEBUG @@ -1005,10 +1005,13 @@ static void debug_gc_fatal_va (void *a, int flags, #ifdef PIKE_DEBUG if (a) { + void *inblock; /* Temporarily jumping out of gc to avoid being caught in debug * checks in describe(). */ Pike_in_gc = 0; - describe(a); + if (type == PIKE_T_UNKNOWN) + type = attempt_to_identify (a, &inblock); + describe_something (a, type, 0, 0, 0, inblock); if (flags & 1) locate_references(a); Pike_in_gc = orig_gc_pass; } @@ -1027,7 +1030,15 @@ void debug_gc_fatal (void *a, int flags, const char *fmt, ...) { va_list args; va_start (args, fmt); - debug_gc_fatal_va (a, flags, fmt, args); + debug_gc_fatal_va (a, PIKE_T_UNKNOWN, flags, fmt, args); + va_end (args); +} + +void debug_gc_fatal_2 (void *a, int type, int flags, const char *fmt, ...) +{ + va_list args; + va_start (args, fmt); + debug_gc_fatal_va (a, type, flags, fmt, args); va_end (args); } @@ -1037,7 +1048,7 @@ static void dloc_gc_fatal (const char *file, int line, va_list args; fprintf (stderr, "%s:%d: GC fatal:\n", file, line); va_start (args, fmt); - debug_gc_fatal_va (a, flags, fmt, args); + debug_gc_fatal_va (a, PIKE_T_UNKNOWN, flags, fmt, args); va_end (args); } @@ -2459,14 +2470,14 @@ void gc_delayed_free(void *a, int type) m->flags |= GC_GOT_DEAD_REF; } -int gc_mark(void *a) +int gc_mark_func(void *a DO_IF_DEBUG (COMMA int type)) { struct marker *m; #ifdef PIKE_DEBUG if (Pike_in_gc == GC_PASS_ZAP_WEAK && !find_marker (a)) - gc_fatal (a, 0, "gc_mark() called for for thing without marker " - "in zap weak pass.\n"); + gc_fatal_2 (a, type, 0, "gc_mark() called for for thing without marker " + "in zap weak pass.\n"); #endif m = get_marker (a); @@ -2483,9 +2494,9 @@ int gc_mark(void *a) if (Pike_in_gc != GC_PASS_MARK && Pike_in_gc != GC_PASS_ZAP_WEAK) Pike_fatal("GC mark attempted in invalid pass.\n"); if (!*(INT32 *) a) - gc_fatal(a, 0, "Marked a thing without refs.\n"); + gc_fatal_2 (a, type, 1, "Marked a thing without refs.\n"); if (m->weak_refs < 0) - gc_fatal(a, 0, "Marked a thing scheduled for weak free.\n"); + gc_fatal_2 (a, type, 1, "Marked a thing scheduled for weak free.\n"); #endif if (Pike_in_gc == GC_PASS_ZAP_WEAK) { @@ -2495,8 +2506,8 @@ int gc_mark(void *a) * internal cyclic nonweak refs. */ #ifdef PIKE_DEBUG if (!(m->flags & GC_MARKED)) - gc_fatal(a, 0, "gc_mark() called for thing in zap weak pass " - "that wasn't marked before.\n"); + gc_fatal_2 (a, type, 0, "gc_mark() called for thing in zap weak pass " + "that wasn't marked before.\n"); #endif if (m->flags & GC_FREE_VISITED) { debug_malloc_touch (a); @@ -2513,8 +2524,8 @@ int gc_mark(void *a) debug_malloc_touch (a); #ifdef PIKE_DEBUG if (m->weak_refs != 0) - gc_fatal (a, 0, "weak_refs changed in marker " - "already visited by gc_mark().\n"); + gc_fatal_2 (a, type, 0, "weak_refs changed in marker " + "already visited by gc_mark().\n"); #endif return 0; } diff --git a/src/gc.h b/src/gc.h index fcfd234743ef291867d99714720b2e2161b129a6..46d7e52a9d16f0ea8f125b896a6bfa2d8dd23395 100644 --- a/src/gc.h +++ b/src/gc.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: gc.h,v 1.137 2009/11/11 20:05:07 mast Exp $ +|| $Id: gc.h,v 1.138 2009/11/28 13:36:20 mast Exp $ */ #ifndef GC_H @@ -296,6 +296,7 @@ void describe_location(void *real_memblock, int depth, int flags); void debug_gc_fatal(void *a, int flags, const char *fmt, ...); +void debug_gc_fatal_2 (void *a, int type, int flags, const char *fmt, ...); void low_describe_something(void *a, int t, int indent, @@ -319,7 +320,7 @@ void debug_really_free_gc_frame(struct gc_frame *l); int gc_do_weak_free(void *a); void gc_delayed_free(void *a, int type); void debug_gc_mark_enqueue(queue_call call, void *data); -int gc_mark(void *a); +int gc_mark_func(void *a DO_IF_DEBUG (COMMA int type)); void gc_move_marker (void *old_thing, void *new_thing); PMOD_EXPORT void gc_cycle_enqueue(gc_cycle_check_cb *checkfn, void *data, int weak); void gc_cycle_run_queue(void); @@ -339,6 +340,12 @@ void cleanup_gc(void); #define DMALLOC_TOUCH_MARKER(X, EXPR) (EXPR) #endif +#ifdef PIKE_DEBUG +#define gc_mark(DATA, TYPE) gc_mark_func (DATA, TYPE) +#else +#define gc_mark(DATA, TYPE) gc_mark_func (DATA) +#endif + #define gc_check(VP) \ DMALLOC_TOUCH_MARKER(VP, real_gc_check(debug_malloc_pass(VP))) #define gc_check_weak(VP) \ @@ -438,6 +445,8 @@ static INLINE int debug_gc_check_weak (void *a, const char *place) #define gc_fatal \ fprintf(stderr, "%s:%d: GC fatal:\n", __FILE__, __LINE__), debug_gc_fatal +#define gc_fatal_2 \ + fprintf(stderr, "%s:%d: GC fatal:\n", __FILE__, __LINE__), debug_gc_fatal_2 #ifdef PIKE_DEBUG diff --git a/src/mapping.c b/src/mapping.c index 1fbee8a4d8095da2ad6dd96247a62bdeebfd4374..760e3d44ba3d826f45a71a0d31431f3079b8b520 100644 --- a/src/mapping.c +++ b/src/mapping.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: mapping.c,v 1.213 2009/09/22 15:45:09 grubba Exp $ +|| $Id: mapping.c,v 1.214 2009/11/28 13:36:20 mast Exp $ */ #include "global.h" @@ -2583,7 +2583,7 @@ void gc_mark_mapping_as_referenced(struct mapping *m) debug_malloc_touch(m); debug_malloc_touch(m->data); - if(gc_mark(m)) + if(gc_mark(m, T_MAPPING)) GC_ENTER (m, T_MAPPING) { struct mapping_data *md = m->data; @@ -2596,7 +2596,8 @@ void gc_mark_mapping_as_referenced(struct mapping *m) DOUBLELINK(first_mapping, m); /* Linked in first. */ } - if(gc_mark(md) && ((md->ind_types | md->val_types) & BIT_COMPLEX)) { + if(gc_mark(md, T_MAPPING_DATA) && + ((md->ind_types | md->val_types) & BIT_COMPLEX)) { TYPE_FIELD ind_types = 0, val_types = 0; if (MAPPING_DATA_IN_USE(md)) { /* Must leave the mapping data untouched if it's busy. */ diff --git a/src/multiset.c b/src/multiset.c index 46f27763bc4c60098b266eed6b560da97e506094..d1153d5a2035a60105ddd2433b3de525a87abb7d 100644 --- a/src/multiset.c +++ b/src/multiset.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: multiset.c,v 1.118 2009/08/10 14:27:47 grubba Exp $ +|| $Id: multiset.c,v 1.119 2009/11/28 13:36:20 mast Exp $ */ #include "global.h" @@ -4163,7 +4163,7 @@ static void gc_unlink_msnode_shared (struct multiset_data *msd, void gc_mark_multiset_as_referenced (struct multiset *l) { - if (gc_mark (l)) + if (gc_mark (l, T_MULTISET)) GC_ENTER (l, T_MULTISET) { struct multiset_data *msd = l->msd; @@ -4176,7 +4176,7 @@ void gc_mark_multiset_as_referenced (struct multiset *l) DOUBLELINK (first_multiset, l); /* Linked in first. */ } - if (gc_mark (msd) && msd->root && + if (gc_mark (msd, T_MULTISET_DATA) && msd->root && ((msd->ind_types | msd->val_types) & BIT_COMPLEX)) { struct marker *m = get_marker (msd); TYPE_FIELD ind_types = 0, val_types = 0; diff --git a/src/object.c b/src/object.c index efa0edb52e295069e6474bde7c164dc41f150db3..891175b45fa164b70f5c8f3caa96aaf5266902c4 100644 --- a/src/object.c +++ b/src/object.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: object.c,v 1.303 2009/08/25 16:59:22 grubba Exp $ +|| $Id: object.c,v 1.304 2009/11/28 13:36:20 mast Exp $ */ #include "global.h" @@ -2027,7 +2027,7 @@ PMOD_EXPORT void gc_mark_object_as_referenced(struct object *o) debug_malloc_touch(o); debug_malloc_touch(o->storage); - if(gc_mark(o)) { + if(gc_mark(o, T_OBJECT)) { if(o->next == o) return; /* Fake object used by compiler */ GC_ENTER (o, T_OBJECT) { diff --git a/src/pike_types.c b/src/pike_types.c index 86ab672880f193894552ed09a2fb0890a53b950b..5ed3931df638de190834694935eecea1afd4b8a5 100644 --- a/src/pike_types.c +++ b/src/pike_types.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: pike_types.c,v 1.360 2009/04/11 12:42:22 grubba Exp $ +|| $Id: pike_types.c,v 1.361 2009/11/28 13:36:21 mast Exp $ */ #include "global.h" @@ -8022,7 +8022,7 @@ PMOD_EXPORT void visit_type (struct pike_type *t, int action) void gc_mark_type_as_referenced(struct pike_type *t) { - if (gc_mark(t)) { + if (gc_mark(t, PIKE_T_TYPE)) { GC_ENTER(t, PIKE_T_TYPE) { switch(t->type) { case PIKE_T_SCOPE: diff --git a/src/program.c b/src/program.c index 1e15cab9c1ed42ae1ac6ca22a5dbdb75a7cd55fa..ca66019f91a707b604a60206a3d70c666cfa00a6 100644 --- a/src/program.c +++ b/src/program.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: program.c,v 1.772 2009/11/20 10:58:09 grubba Exp $ +|| $Id: program.c,v 1.773 2009/11/28 13:36:21 mast Exp $ */ #include "global.h" @@ -10185,7 +10185,7 @@ void gc_mark_program_as_referenced(struct program *p) */ debug_malloc_touch(p); - if (gc_mark(p)) { + if (gc_mark(p, T_PROGRAM)) { if (p == gc_mark_program_pos) gc_mark_program_pos = p->next; if (p == gc_internal_program) @@ -10199,7 +10199,7 @@ void gc_mark_program_as_referenced(struct program *p) return; } - if(gc_mark(p)) + if(gc_mark(p, T_PROGRAM)) GC_ENTER (p, T_PROGRAM) { int e; diff --git a/src/svalue.c b/src/svalue.c index f925962028d03338d3ae5a69f3a116901b6d7119..2bd0114c73e74500c1573e7ccf4414995d55880e 100644 --- a/src/svalue.c +++ b/src/svalue.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: svalue.c,v 1.254 2009/08/20 16:24:36 mast Exp $ +|| $Id: svalue.c,v 1.255 2009/11/28 13:36:21 mast Exp $ */ #include "global.h" @@ -2291,9 +2291,16 @@ void gc_check_weak_short_svalue(const union anything *u, TYPE_T type) #define GC_DONT_MARK(U, TN) do {} while (0) +#define MARK_PRE { \ + DO_IF_DEBUG ( \ + if (!s->u.refs) \ + (gc_fatal_2 (s->u.ptr, s->type, 0, "Marking thing without refs.\n")); \ + ); \ + } + #define DO_MARK_FUNC_SVALUE(U, T, ZAP, GC_DO) \ if (s->subtype == FUNCTION_BUILTIN) { \ - DO_IF_DEBUG (if (d_flag) gc_mark (s->u.efun->name)); \ + DO_IF_DEBUG (if (d_flag) gc_mark (s->u.efun->name, T_STRING)); \ DO_IF_DEBUG_OR_CLEANUP (GC_DO_MARK ((*s->u.efun), type)); \ break; \ } \ @@ -2310,7 +2317,7 @@ void gc_check_weak_short_svalue(const union anything *u, TYPE_T type) GC_DO_MARK(U, TN) #define DO_MARK_STRING(U) \ - DO_IF_DEBUG(if (U.refs && d_flag) gc_mark(U.string)) + DO_IF_DEBUG(if (U.refs && d_flag) gc_mark(U.string, T_STRING)) #define DONT_MARK_STRING(U) @@ -2323,7 +2330,7 @@ PMOD_EXPORT TYPE_FIELD real_gc_mark_svalues(struct svalue *s, size_t num) { dmalloc_touch_svalue(s); GC_RECURSE_SWITCH((s->u), (s->type), ZAP_SVALUE, DONT_FREE_WEAK, - GC_DO_MARK, {}, + GC_DO_MARK, MARK_PRE, DO_MARK_FUNC_SVALUE, GC_DO_MARK, DO_MARK_STRING, GC_DO_MARK); t |= 1 << s->type; @@ -2340,7 +2347,7 @@ TYPE_FIELD gc_mark_weak_svalues(struct svalue *s, size_t num) { dmalloc_touch_svalue(s); GC_RECURSE_SWITCH((s->u), (s->type), ZAP_SVALUE, FREE_WEAK, - GC_DONT_MARK, {}, + GC_DONT_MARK, MARK_PRE, DO_MARK_FUNC_SVALUE, DO_MARK_OBJ_WEAK, DO_MARK_STRING, GC_DO_MARK); t |= 1 << s->type; @@ -2375,7 +2382,7 @@ int gc_mark_without_recurse(struct svalue *s) int freed = 0; dmalloc_touch_svalue(s); GC_RECURSE_SWITCH((s->u), (s->type), ZAP_SVALUE, DONT_FREE_WEAK, - GC_DONT_MARK, {}, + GC_DONT_MARK, MARK_PRE, DONT_MARK_FUNC_SVALUE, GC_DONT_MARK, DONT_MARK_STRING, GC_DONT_MARK); return freed; @@ -2386,7 +2393,7 @@ int gc_mark_weak_without_recurse(struct svalue *s) int freed = 0; dmalloc_touch_svalue(s); GC_RECURSE_SWITCH((s->u), (s->type), ZAP_SVALUE, FREE_WEAK, - GC_DONT_MARK, {}, + GC_DONT_MARK, MARK_PRE, DONT_MARK_FUNC_SVALUE, GC_DONT_MARK, DONT_MARK_STRING, GC_DONT_MARK); return freed;