diff src/alloc.c @ 2645:e6854ec89f8e

[xemacs-hg @ 2005-03-10 09:12:36 by crestani] KKCC backtrace. 2005-03-01 Marcus Crestani <crestani@informatik.uni-tuebingen.de> * alloc.c: Add functionality for backtracing the KKCC mark algorithm. * alloc.c (kkcc_backtrace): New. * alloc.c (kkcc_bt_push): New. * alloc.c (kkcc_gc_stack_push): * alloc.c (kkcc_gc_stack_push_lisp_object): * alloc.c (mark_object_maybe_checking_free): * alloc.c (mark_struct_contents): * alloc.c (kkcc_marking): * alloc.c (mark_object): * data.c (finish_marking_weak_lists): * data.c (continue_marking_ephemerons): * data.c (finish_marking_ephemerons): * elhash.c (MARK_OBJ): * lisp.h: * profile.c (mark_profiling_info_maphash): Add level (current depth of mark tree) and pos (position within description) as additional arguments to KKCC mark functions.
author crestani
date Thu, 10 Mar 2005 09:12:38 +0000
parents 9f70af3ac939
children fc554bcc59e7
line wrap: on
line diff
--- a/src/alloc.c	Thu Mar 10 09:05:52 2005 +0000
+++ b/src/alloc.c	Thu Mar 10 09:12:38 2005 +0000
@@ -3091,6 +3091,10 @@
     default:
       stderr_out ("Unsupported count type : %d (line = %d, code = %ld)\n",
 		  idesc[line].type, line, (long) code);
+#ifdef USE_KKCC
+      if (gc_in_progress)
+	kkcc_backtrace ();
+#endif
 #ifdef PDUMP
       if (in_pdump)
 	pdump_backtrace ();
@@ -3307,6 +3311,10 @@
 {
   void *data;
   const struct memory_description *desc;
+#ifdef DEBUG_XEMACS
+  int level;
+  int pos;
+#endif
 } kkcc_gc_stack_entry;
 
 static kkcc_gc_stack_entry *kkcc_gc_stack_ptr;
@@ -3314,6 +3322,72 @@
 static kkcc_gc_stack_entry *kkcc_gc_stack_last_entry;
 static int kkcc_gc_stack_size;
 
+#ifdef DEBUG_XEMACS
+#define KKCC_BT_STACK_SIZE 4096
+
+static struct
+{
+  void *obj;
+  const struct memory_description *desc;
+  int pos;
+} kkcc_bt[KKCC_BT_STACK_SIZE];
+
+static int kkcc_bt_depth = 0;
+
+#define KKCC_BT_INIT() kkcc_bt_depth = 0;
+
+void
+kkcc_backtrace (void)
+{
+  int i;
+  stderr_out ("KKCC mark stack backtrace :\n");
+  for (i = kkcc_bt_depth - 1; i >= 0; i--)
+    {
+      stderr_out (" [%d]", i);
+      if ((((struct lrecord_header *) kkcc_bt[i].obj)->type
+	   >= lrecord_type_free)
+	  || (!LRECORDP (kkcc_bt[i].obj))
+	  || (!XRECORD_LHEADER_IMPLEMENTATION (kkcc_bt[i].obj)))
+	{
+	  stderr_out (" non Lisp Object");
+	}
+      else
+	{
+	  stderr_out (" %s",
+		      XRECORD_LHEADER_IMPLEMENTATION (kkcc_bt[i].obj)->name);
+	}
+      stderr_out (" (addr: 0x%x, desc: 0x%x, ",
+		  (int) kkcc_bt[i].obj,
+		  (int) kkcc_bt[i].desc);
+      if (kkcc_bt[i].pos >= 0)
+	stderr_out ("pos: %d)\n", kkcc_bt[i].pos);
+      else
+	stderr_out ("root set)\n");
+    }
+}
+
+static void
+kkcc_bt_push (void *obj, const struct memory_description *desc, 
+	      int level, int pos)
+{
+  kkcc_bt_depth = level;
+  kkcc_bt[kkcc_bt_depth].obj = obj;
+  kkcc_bt[kkcc_bt_depth].desc = desc;
+  kkcc_bt[kkcc_bt_depth].pos = pos;
+  kkcc_bt_depth++;
+  if (kkcc_bt_depth > KKCC_BT_STACK_SIZE)
+    {
+      stderr_out ("KKCC backtrace overflow, adjust KKCC_BT_STACK_SIZE.\n");
+      stderr_out ("Maybe it is a loop?\n");
+      ABORT ();
+    }
+}
+
+#else /* not DEBUG_XEMACS */
+#define KKCC_BT_INIT()
+#define kkcc_bt_push(obj, desc, level, pos)
+#endif /* not DEBUG_XEMACS */
+
 static void
 kkcc_gc_stack_init (void)
 {
@@ -3359,14 +3433,31 @@
 #define KKCC_GC_STACK_EMPTY (kkcc_gc_stack_top < kkcc_gc_stack_ptr)
 
 static void
-kkcc_gc_stack_push (void *data, const struct memory_description *desc)
+#ifdef DEBUG_XEMACS
+kkcc_gc_stack_push_1 (void *data, const struct memory_description *desc,
+		    int level, int pos)
+#else
+kkcc_gc_stack_push_1 (void *data, const struct memory_description *desc)
+#endif
 {
   if (KKCC_GC_STACK_FULL)
       kkcc_gc_stack_realloc();
   kkcc_gc_stack_top++;
   kkcc_gc_stack_top->data = data;
   kkcc_gc_stack_top->desc = desc;
-}
+#ifdef DEBUG_XEMACS
+  kkcc_gc_stack_top->level = level;
+  kkcc_gc_stack_top->pos = pos;
+#endif
+}
+
+#ifdef DEBUG_XEMACS
+#define kkcc_gc_stack_push(data, desc, level, pos)	\
+  kkcc_gc_stack_push_1 (data, desc, level, pos)
+#else
+#define kkcc_gc_stack_push(data, desc, level, pos)	\
+  kkcc_gc_stack_push_1 (data, desc)
+#endif
 
 static kkcc_gc_stack_entry *
 kkcc_gc_stack_pop (void)
@@ -3378,7 +3469,11 @@
 }
 
 void
-kkcc_gc_stack_push_lisp_object (Lisp_Object obj)
+#ifdef DEBUG_XEMACS
+kkcc_gc_stack_push_lisp_object_1 (Lisp_Object obj, int level, int pos)
+#else
+kkcc_gc_stack_push_lisp_object_1 (Lisp_Object obj)
+#endif
 {
   if (XTYPE (obj) == Lisp_Type_Record)
     {
@@ -3389,11 +3484,19 @@
       if (! MARKED_RECORD_HEADER_P (lheader)) 
 	{
 	  MARK_RECORD_HEADER (lheader);
-	  kkcc_gc_stack_push((void*) lheader, desc);
+	  kkcc_gc_stack_push((void*) lheader, desc, level, pos);
 	}
     }
 }
 
+#ifdef DEBUG_XEMACS
+#define kkcc_gc_stack_push_lisp_object(obj, level, pos) \
+  kkcc_gc_stack_push_lisp_object_1 (obj, level, pos)
+#else
+#define kkcc_gc_stack_push_lisp_object(obj, level, pos) \
+  kkcc_gc_stack_push_lisp_object_1 (obj)
+#endif
+
 #ifdef ERROR_CHECK_GC
 #define KKCC_DO_CHECK_FREE(obj, allow_free)			\
 do								\
@@ -3409,24 +3512,44 @@
 #endif
 
 #ifdef ERROR_CHECK_GC
+#ifdef DEBUG_XEMACS
 static void
-mark_object_maybe_checking_free (Lisp_Object obj, int allow_free)
+mark_object_maybe_checking_free_1 (Lisp_Object obj, int allow_free,
+				 int level, int pos)
+#else
+static void
+mark_object_maybe_checking_free_1 (Lisp_Object obj, int allow_free)
+#endif
 {
   KKCC_DO_CHECK_FREE (obj, allow_free);
-  kkcc_gc_stack_push_lisp_object (obj);
-}
+  kkcc_gc_stack_push_lisp_object (obj, level, pos);
+}
+
+#ifdef DEBUG_XEMACS
+#define mark_object_maybe_checking_free(obj, allow_free, level, pos) \
+  mark_object_maybe_checking_free_1 (obj, allow_free, level, pos)
 #else
-#define mark_object_maybe_checking_free(obj, allow_free) 	\
-      kkcc_gc_stack_push_lisp_object (obj)
-#endif /* ERROR_CHECK_GC */
+#define mark_object_maybe_checking_free(obj, allow_free, level, pos) \
+  mark_object_maybe_checking_free_1 (obj, allow_free)
+#endif
+#else /* not ERROR_CHECK_GC */
+#define mark_object_maybe_checking_free(obj, allow_free, level, pos) 	\
+  kkcc_gc_stack_push_lisp_object (obj, level, pos)
+#endif /* not ERROR_CHECK_GC */
 
 
 /* This function loops all elements of a struct pointer and calls 
    mark_with_description with each element. */
 static void
-mark_struct_contents (const void *data,
+#ifdef DEBUG_XEMACS
+mark_struct_contents_1 (const void *data,
+		      const struct sized_memory_description *sdesc,
+		      int count, int level, int pos)
+#else
+mark_struct_contents_1 (const void *data,
 		      const struct sized_memory_description *sdesc,
 		      int count)
+#endif
 {
   int i;
   Bytecount elsize;
@@ -3434,10 +3557,18 @@
 
   for (i = 0; i < count; i++)
     {
-      kkcc_gc_stack_push (((char *) data) + elsize * i, sdesc->description);
+      kkcc_gc_stack_push (((char *) data) + elsize * i, sdesc->description,
+			  level, pos);
     }
 }
 
+#ifdef DEBUG_XEMACS
+#define mark_struct_contents(data, sdesc, count, level, pos) \
+  mark_struct_contents_1 (data, sdesc, count, level, pos)
+#else
+#define mark_struct_contents(data, sdesc, count, level, pos) \
+  mark_struct_contents_1 (data, sdesc, count)
+#endif
 
 /* This function implements the KKCC mark algorithm.
    Instead of calling mark_object, all the alive Lisp_Objects are pushed
@@ -3450,11 +3581,20 @@
   void *data = 0;
   const struct memory_description *desc = 0;
   int pos;
+#ifdef DEBUG_XEMACS
+  int level = 0;
+  KKCC_BT_INIT ();
+#endif
   
   while ((stack_entry = kkcc_gc_stack_pop ()) != 0)
     {
       data = stack_entry->data;
       desc = stack_entry->desc;
+#ifdef DEBUG_XEMACS
+      level = stack_entry->level + 1;
+#endif
+
+      kkcc_bt_push (data, desc, stack_entry->level, stack_entry->pos);
 
       for (pos = 0; desc[pos].type != XD_END; pos++)
 	{
@@ -3493,8 +3633,8 @@
 		if (EQ (*stored_obj, Qnull_pointer))
 		  break;
 		mark_object_maybe_checking_free
-		  (*stored_obj, (desc1->flags) & XD_FLAG_FREE_LISP_OBJECT);
-	    
+		  (*stored_obj, (desc1->flags) & XD_FLAG_FREE_LISP_OBJECT,
+		   level, pos);
 		break;
 	      }
 	    case XD_LISP_OBJECT_ARRAY:
@@ -3510,9 +3650,9 @@
 
 		    if (EQ (*stored_obj, Qnull_pointer))
 		      break;
-
 		    mark_object_maybe_checking_free
-		      (*stored_obj, (desc1->flags) & XD_FLAG_FREE_LISP_OBJECT);
+		      (*stored_obj, (desc1->flags) & XD_FLAG_FREE_LISP_OBJECT,
+		       level, pos);
 		  }
 		break;
 	      }
@@ -3524,7 +3664,7 @@
 		  lispdesc_indirect_description (data, desc1->data2.descr);
 		const char *dobj = * (const char **) rdata;
 		if (dobj)
-		  mark_struct_contents (dobj, sdesc, count);
+		  mark_struct_contents (dobj, sdesc, count, level, pos);
 		break;
 	      }
 	    case XD_BLOCK_ARRAY:
@@ -3534,7 +3674,7 @@
 		const struct sized_memory_description *sdesc =
 		  lispdesc_indirect_description (data, desc1->data2.descr);
 		      
-		mark_struct_contents (rdata, sdesc, count);
+		mark_struct_contents (rdata, sdesc, count, level, pos);
 		break;
 	      }
 	    case XD_UNION:
@@ -3546,6 +3686,7 @@
 		    
 	    default:
 	      stderr_out ("Unsupported description type : %d\n", desc1->type);
+	      kkcc_backtrace ();
 	      ABORT ();
 	    }
 	}
@@ -4735,7 +4876,7 @@
 #ifdef USE_KKCC
   /* initialize kkcc stack */
   kkcc_gc_stack_init();
-#define mark_object kkcc_gc_stack_push_lisp_object
+#define mark_object(obj) kkcc_gc_stack_push_lisp_object (obj, 0, -1)
 #endif /* USE_KKCC */
 
   { /* staticpro() */