[Gc] Finalization statistics improvement

Ivan Maidanski ivmai at mail.ru
Fri Nov 21 00:07:03 PST 2008


Hi!

It seems to me that GC_dump() (printing huge amount of info) is not the appropriate place to call GC_print_finalization_stats() (printing just 2 lines of statistics) - it's better to have GC_print_finalization_stats() logging finalization statistics regulary among other info about the current collection.

So, this patch moves GC_print_finalization_stats() call from GC_dump() to GC_finish_collection() (in addition, one more parameter is logged in GC_print_finalization_stats() now - the mount of disappearing links cleared during the current collection).

Also, a missing "\n" is added for GC_err/log_printf() calls in GC_return_mark_stack() and GC_dirty_init().

And, also, the in-line logging atomicity is ensured in GC_stopped_mark().

Bye.

-------------- next part --------------
diff -ru bdwgc/alloc.c updated/bdwgc/alloc.c
--- bdwgc/alloc.c	2008-11-20 12:04:40.000000000 +0300
+++ updated/bdwgc/alloc.c	2008-11-20 18:49:26.000000000 +0300
@@ -551,10 +551,10 @@
     STOP_WORLD();
     IF_THREADS(GC_world_stopped = TRUE);
     if (GC_print_stats) {
-	GC_log_printf("--> Marking for collection %lu ",
-		  (unsigned long)GC_gc_no + 1);
-	GC_log_printf("after %lu allocd bytes\n",
-	   	   (unsigned long) GC_bytes_allocd);
+	/* Output blank line for convenience here */
+	GC_log_printf(
+	      "\n--> Marking for collection %lu after %lu allocated bytes\n",
+	      (unsigned long)GC_gc_no + 1, (unsigned long) GC_bytes_allocd);
     }
 #   ifdef MAKE_BACK_GRAPH
       if (GC_print_back_height) {
@@ -570,8 +570,8 @@
 	for(i = 0;;i++) {
 	    if ((*stop_func)()) {
 		    if (GC_print_stats) {
-		    	GC_log_printf("Abandoned stopped marking after ");
-			GC_log_printf("%u iterations\n", i);
+		    	GC_log_printf("Abandoned stopped marking after "
+				"%u iterations\n", i);
 		    }
 		    GC_deficit = i; /* Give the mutator a chance. */
                     IF_THREADS(GC_world_stopped = FALSE);
@@ -851,6 +851,10 @@
 #   ifndef SMALL_CONFIG
       if (GC_print_stats) {
 	GET_TIME(done_time);
+
+	/* A convenient place to output finalization statistics. */
+	GC_print_finalization_stats();
+
 	GC_log_printf("Finalize + initiate sweep took %lu + %lu msecs\n",
 	              MS_TIME_DIFF(finalize_time,start_time),
 	              MS_TIME_DIFF(done_time,finalize_time));
diff -ru bdwgc/finalize.c updated/bdwgc/finalize.c
--- bdwgc/finalize.c	2008-11-20 12:00:32.000000000 +0300
+++ updated/bdwgc/finalize.c	2008-11-20 20:20:36.000000000 +0300
@@ -484,6 +484,10 @@
 }
 #endif
 
+#ifndef SMALL_CONFIG
+  STATIC word GC_old_dl_entries; /* for stats printing */
+#endif
+
 /* Called with held lock (but the world is running).			*/
 /* Cause disappearing links to disappear, and invoke finalizers.	*/
 void GC_finalize(void)
@@ -495,6 +499,11 @@
     size_t dl_size = (log_dl_table_size == -1 ) ? 0 : (1 << log_dl_table_size);
     size_t fo_size = (log_fo_table_size == -1 ) ? 0 : (1 << log_fo_table_size);
     
+#   ifndef SMALL_CONFIG
+      /* Save current GC_dl_entries value for stats printing */
+      GC_old_dl_entries = GC_dl_entries;
+#   endif
+
   /* Make disappearing links disappear */
     for (i = 0; i < dl_size; i++) {
       curr_dl = dl_head[i];
@@ -851,17 +860,20 @@
     return(result);
 }
 
-#if !defined(NO_DEBUGGING)
+#ifndef SMALL_CONFIG
 
 void GC_print_finalization_stats(void)
 {
     struct finalizable_object *fo = GC_finalize_now;
-    unsigned ready = 0;
+    unsigned long ready = 0;
 
-    GC_printf("%u finalization table entries; %u disappearing links\n",
-	       (unsigned)GC_fo_entries, (unsigned)GC_dl_entries);
+    GC_log_printf(
+	"%lu finalization table entries; %lu disappearing links alive\n",
+	(unsigned long)GC_fo_entries, (unsigned long)GC_dl_entries);
     for (; 0 != fo; fo = fo_next(fo)) ++ready;
-    GC_printf("%u objects are eligible for immediate finalization\n", ready);
+    GC_log_printf("%lu objects are eligible for immediate finalization; "
+		  "%ld links cleared\n",
+		  ready, (long)GC_old_dl_entries - (long)GC_dl_entries);
 }
 
-#endif /* NO_DEBUGGING */
+#endif /* SMALL_CONFIG */
diff -ru bdwgc/mark.c updated/bdwgc/mark.c
--- bdwgc/mark.c	2008-11-17 12:31:36.000000000 +0300
+++ updated/bdwgc/mark.c	2008-11-20 18:30:08.000000000 +0300
@@ -922,7 +922,7 @@
     my_start = my_top + 1;
     if (my_start - GC_mark_stack + stack_size > GC_mark_stack_size) {
       if (GC_print_stats) {
-	  GC_log_printf("No room to copy back mark stack.");
+	  GC_log_printf("No room to copy back mark stack\n");
       }
       GC_mark_state = MS_INVALID;
       GC_mark_stack_too_small = TRUE;
diff -ru bdwgc/misc.c updated/bdwgc/misc.c
--- bdwgc/misc.c	2008-11-18 23:25:44.000000000 +0300
+++ updated/bdwgc/misc.c	2008-11-20 17:57:14.809572300 +0300
@@ -1223,8 +1223,6 @@
     GC_print_hblkfreelist();
     GC_printf("\n***Blocks in use:\n");
     GC_print_block_list();
-    GC_printf("\n***Finalization statistics:\n");
-    GC_print_finalization_stats();
 }
 
 #endif /* NO_DEBUGGING */
diff -ru bdwgc/os_dep.c updated/bdwgc/os_dep.c
--- bdwgc/os_dep.c	2008-11-20 11:55:14.000000000 +0300
+++ updated/bdwgc/os_dep.c	2008-11-20 18:57:18.000000000 +0300
@@ -2838,7 +2838,7 @@
 	GC_old_segv_handler_used_si = FALSE;
       }
       if (GC_old_segv_handler == (SIG_HNDLR_PTR)SIG_IGN) {
-	GC_err_printf("Previously ignored segmentation violation!?");
+	GC_err_printf("Previously ignored segmentation violation!?\n");
 	GC_old_segv_handler = (SIG_HNDLR_PTR)SIG_DFL;
       }
       if (GC_old_segv_handler != (SIG_HNDLR_PTR)SIG_DFL) {
@@ -2856,7 +2856,7 @@
 	GC_old_bus_handler_used_si = FALSE;
       }
       if (GC_old_bus_handler == (SIG_HNDLR_PTR)SIG_IGN) {
-	     GC_err_printf("Previously ignored bus error!?");
+	     GC_err_printf("Previously ignored bus error!?\n");
 	     GC_old_bus_handler = (SIG_HNDLR_PTR)SIG_DFL;
       }
       if (GC_old_bus_handler != (SIG_HNDLR_PTR)SIG_DFL) {
@@ -3557,7 +3557,7 @@
 	    /* This will fail if the thread dies, but the thread */
 	    /* shouldn't die... */
 #           ifdef BROKEN_EXCEPTION_HANDLING
-	      GC_err_printf("mach_msg failed with %d %s while sending"
+	      GC_err_printf("mach_msg failed with %d %s while sending "
 			    "exc reply\n", (int)r,mach_error_string(r));
 #           else
 	      ABORT("mach_msg failed while sending exception reply");


More information about the Gc mailing list