2008-03-29
2008-03-29 16:20:19 by Martin Stjernholm <mast@lysator.liu.se>
-
cd9dfaa849e295043b69177982698f2d242a844e
(159 lines)
(+36/-123)
[
Show
| Annotate
]
Branch: 7.9
Fixed proper use of the gc to detect pike type leaks. Some other minor
fiddling with the leak reports.
Rev: src/gc.c:1.302
Rev: src/global.h:1.111
Rev: src/module.c:1.50
Rev: src/pike_types.c:1.318
Rev: src/pike_types.h:1.111
Rev: src/program.c:1.656
Rev: src/svalue.c:1.238
2:
|| 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.317 2008/03/27 12:31:11 grubba Exp $
+ || $Id: pike_types.c,v 1.318 2008/03/29 16:20:16 mast Exp $
*/
#include "global.h"
2417: Inside #if defined (PIKE_DEBUG) || defined (DO_PIKE_CLEANUP)
}
}
- /* Leak reporting similar to the exit_with_cleanup code in
- * exit_builtin_modules. */
-
- void report_all_type_leaks (void)
- {
- unsigned INT32 index;
- if (!gc_keep_markers)
- Pike_fatal ("Should only be called in final cleanup.\n");
- for (index = 0; index < pike_type_hash_size; index++) {
- struct pike_type *t;
- for (t = pike_type_hash[index]; t; t = t->next) {
- struct marker *m = find_marker (t);
- /* We aren't hooked in to the gc mark pass so we don't have
- * markers for types with only external references. */
- INT32 m_refs = m ? m->refs : 0;
- if (t->refs != m_refs) {
- fprintf (stderr, "Type at %p got %d unaccounted refs: ",
- t, t->refs - m_refs);
- simple_describe_type (t);
- fputc ('\n', stderr);
- #ifdef DEBUG_MALLOC
- debug_malloc_dump_references (t, 2, 1, 0);
- #endif
- }
- }
- }
- }
-
+
void free_all_leaked_types (void)
{
unsigned INT32 index;
2454: Inside #if defined (PIKE_DEBUG) || defined (DO_PIKE_CLEANUP)
struct pike_type *t;
for (t = pike_type_hash[index]; t; t = t->next) {
struct marker *m = find_marker (t);
- INT32 m_refs = m ? m->refs : 0;
+ if (m) {
INT32 refs = t->refs;
- if (refs > m_refs) {
+ if (refs > m->refs) {
#ifdef PIKE_DEBUG
- if (m) m->flags |= GC_CLEANUP_FREED;
+ m->flags |= GC_CLEANUP_FREED;
#endif /* PIKE_DEBUG */
do {
free_type (t);
refs--;
- } while (refs > m_refs);
+ } while (refs > m->refs);
+ if (!refs) {
/* t is invalid here, as is its next pointer.
* Start over from the top of this hash entry.
*/
2473: Inside #if defined (PIKE_DEBUG) || defined (DO_PIKE_CLEANUP)
}
}
}
+ }
+ }
#endif /* PIKE_DEBUG || DO_PIKE_CLEANUP */
7713:
#endif /* DO_PIKE_CLEANUP */
}
- #if 0
- #ifdef PIKE_DEBUG
+ #if defined (PIKE_DEBUG) || defined (DO_PIKE_CLEANUP)
-
+ /* This is only enough gc stuff to detect leaking pike_type structs
+ * and to locate references to them. More is needed if types are
+ * extended to contain pointers to other memory objects or if they
+ * might contain cycles. */
+
void gc_mark_type_as_referenced(struct pike_type *t)
{
if (gc_mark(t)) {
7748: Inside #if 0 and #if defined(PIKE_DEBUG)
}
}
- unsigned gc_touch_all_types(void)
+ static void gc_check_type (struct pike_type *t)
{
- size_t e;
- unsigned n = 0;
- if (!pike_type_hash) return 0;
- for(e=0;e<pike_type_hash_size;e++)
- {
- struct pike_type *t;
- for(t = pike_type_hash[e]; t; t=t->next) debug_gc_touch(t), n++;
- }
- return n;
- }
+ debug_malloc_touch (t);
- void gc_mark_all_types(void)
- {
- size_t e;
- if(!pike_type_hash) return;
- for(e=0;e<pike_type_hash_size;e++)
- {
- struct pike_type *t;
- for(t=pike_type_hash[e]; t; t=t->next) {
- if (gc_is_referenced(t)) {
- gc_mark_type_as_referenced(t);
- }
- }
- }
- }
-
- size_t gc_free_all_unreferenced_types(void)
- {
- size_t unreferenced = 0;
- size_t e;
- for (e = 0; e < pike_type_hash_size; e++) {
- struct pike_type *t;
- loop:
- for (t = pike_type_hash[e]; t; t = t->next) {
- struct marker *m = find_marker(t);
- if (!m) continue;
- if ((m->flags & GC_GOT_EXTRA_REF) == GC_GOT_EXTRA_REF) {
- if (gc_do_free(t)) {
- free_type(t);
- unreferenced++;
- /* The hash table may have been modified! */
- goto loop;
- }
- }
- }
- }
- for (e = 0; e < pike_type_hash_size; e++) {
- struct pike_type *t;
- for (t = pike_type_hash[e]; t; t = t->next) {
- struct marker *m = find_marker(t);
- if (!m) continue;
- if ((m->flags & GC_GOT_EXTRA_REF) == GC_GOT_EXTRA_REF) {
- fprintf(stderr, "There's still an extra ref to ");
- simple_describe_type(t);
- fprintf(stderr, "\n");
- }
- }
- }
- return unreferenced;
- }
-
- void real_gc_cycle_check_type(struct pike_type *t, int weak)
- {
- GC_CYCLE_ENTER(t, PIKE_T_TYPE, weak) {
+ GC_ENTER (t, PIKE_T_TYPE) {
switch(t->type) {
case PIKE_T_SCOPE:
case T_ASSIGN:
case PIKE_T_NAME:
case PIKE_T_ATTRIBUTE:
- if (t->cdr) gc_cycle_check_type(t->cdr, 0);
+ if (t->cdr) debug_gc_check (t->cdr, " as cdr in a type");
break;
case PIKE_T_FUNCTION:
case T_MANY:
7828: Inside #if 0 and #if defined(PIKE_DEBUG)
case PIKE_T_MAPPING:
case T_OR:
case T_AND:
- if (t->cdr) gc_cycle_check_type(t->cdr, 0);
+ if (t->cdr) debug_gc_check (t->cdr, " as cdr in a type");
/* FALL_THOUGH */
case PIKE_T_ARRAY:
case PIKE_T_MULTISET:
case T_NOT:
case PIKE_T_TYPE:
case PIKE_T_PROGRAM:
- if (t->car) gc_cycle_check_type(t->car, 0);
+ if (t->car) debug_gc_check (t->car, " as car in a type");
break;
}
- } GC_CYCLE_LEAVE;
+ } GC_LEAVE;
}
- void gc_cycle_check_all_types(void)
+ void gc_check_all_types (void)
{
- #if 0
+
size_t e;
- if(!pike_type_hash) return;
+ if (!pike_type_hash) return;
for(e=0;e<pike_type_hash_size;e++)
{
struct pike_type *t;
- for(t=pike_type_hash[e]; t; t=t->next) {
- real_gc_cycle_check_type(t, 0);
- gc_cycle_run_queue();
+ for(t = pike_type_hash[e]; t; t=t->next) gc_check_type (t);
}
}
- #endif
- }
+
- #endif /* PIKE_DEBUG */
- #endif /* 0 */
+ #endif /* PIKE_DEBUG || DO_PIKE_CLEANUP */