This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[trunk r143197] patch adding optional extra marking to GGC


Hello All

The attached patch is a very small improvement. The code change is minuscule.

The idea is to add, for some peculiar users (I am explicitly thinking of future plugin facilities), the ability to invoke a marking routine on some data during GGC collection.
The implementation is straightforward. The collector internally calls the extra provided marking routine (if it is not null) after having marked roots. The old behavior is kept when no marking routine is provided (ie it is a null pointer).


Most of the patch is comments & documentation. I also documented briefly (in *.texi form) the usual ggc_collect routine which does not seem to be documented yet, and the newly available ggc_collect_extra_marking routine.

I don't know in which kind of stage this small patch fits in. It provide a small extra internal functionality trivially implemented. This functionality is not actively used yet here in the trunk (but the MELT branch has effectively used it for many months without issues).

Bootstrapped on x86-64-linux with --enable-languages c,c++ and --disable-multilib


Changelog is: 2009-01-08 Basile Starynkevitch <basile@starynkevitch.net> * doc/gty.texi: Added documentation of ggc_collect and ggc_collect_extra_marking. * gcc/ggc.h: Updated copyright year. (ggc_mark_roots_extra_marking) added declaration. * gcc/ggc-common.c: Updated copyright year. (ggc_mark_roots): Becomes just a wrapper. (ggc_mark_root_extra_marking) New function, doing what former ggc_mark_roots did and also call the provided extramarker on the provided data if not null. * ggc/ggc-zone.c: Updated copyright year. (ggc_collect_1) Added extra marking arguments and uses them. * ggc/ggc-page.c: Updated copyright year. (ggc_collect) Renamed as ggc_collect_extra_marking and make the extra marking. (ggc_collect_extra_marking) Added.



Comments are welcome. Ok for trunk?

Happy new year 2009 to everyone.

Regards.

--
Basile STARYNKEVITCH         http://starynkevitch.net/Basile/
email: basile<at>starynkevitch<dot>net mobile: +33 6 8501 2359
8, rue de la Faiencerie, 92340 Bourg La Reine, France
*** opinions {are only mines, sont seulement les miennes} ***
membre de l'APRIL "promouvoir et défendre le logiciel libre"
Rejoignez maitenant pplus de 3700 adhérents http://www.april.org

Index: gcc/doc/gty.texi
===================================================================
--- gcc/doc/gty.texi	(revision 143199)
+++ gcc/doc/gty.texi	(working copy)
@@ -1,4 +1,4 @@
-@c Copyright (C) 2002, 2003, 2004, 2007, 2008
+@c Copyright (C) 2002, 2003, 2004, 2007, 2008, 2009
 @c Free Software Foundation, Inc.
 @c This is part of the GCC manual.
 @c For copying conditions, see the file gcc.texi.
@@ -69,6 +69,7 @@ These don't need to be marked.
 * GTY Options::         What goes inside a @code{GTY(())}.
 * GGC Roots::           Making global variables GGC roots.
 * Files::               How the generated files work.
+* Invoking the garbage collector::   How to invoke the garbage collector.
 @end menu
 
 @node GTY Options
@@ -448,3 +449,39 @@ source file.  Don't forget to mention this file as
 For language frontends, there is another file that needs to be included
 somewhere.  It will be called @file{gtype-@var{lang}.h}, where
 @var{lang} is the name of the subdirectory the language is contained in.
+
+
+
+@node Invoking the garbage collector
+@section How to invoke the garbage collector
+@cindex garbage collector, invocation
+@findex ggc_collect
+@findex ggc_collect_extra_marking
+
+The GCC garbage collector GGC is only invoked explicitly. In contrast
+with many other garbage collectors, it is not implicitly invoked by
+allocation routines when a lot of memory has been consumed. So the
+only way to have GGC reclaim storage it to call the @code{ggc_collect}
+function explicitly. This call is an expensive operation, as it may
+have to scan the entire heap. Beware that local variables (on the GCC
+call stack) are not followed by such an invocation (as many other
+garbage collectors do): you should reference all your data from static
+or external @code{GTY}-ed variables, and it is advised to call
+@code{ggc_collect} with a shallow call stack. The GGC is an exact mark
+and sweep garbage collector (so it does not scan the call stack for
+pointers). In practice GCC passes don't often call @code{ggc_collect}
+themselves, because it is called by the pass manager between passes.
+
+Expert developers could also invoke the
+@code{ggc_collect_extra_marking} function. This function takes an
+extra pointer walking/marking routine with a client data pointer. If
+the walking/marking routine is not NULL, the garbage collector invokes
+the walking routine on the client data pointer during collection,
+after having marked all @code{GTY}-ed static or external data and
+before the sweeping and cleaning phases of the collector. The
+walking/marking routine is expected to mark the client data or
+whatever. Expert developers could pass a @code{gengtype}-d generated
+walking/marking routine with the address of a single data item on the
+stack. Use this facility carefully! When the walking/marking routine
+is NULL, @code{ggc_collect_extra_marking} behaves exactly as the plain
+@code{ggc_collect} function.
Index: gcc/ggc.h
===================================================================
--- gcc/ggc.h	(revision 143199)
+++ gcc/ggc.h	(working copy)
@@ -1,5 +1,5 @@
 /* Garbage collection for the GNU compiler.
-   Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008
+   Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008, 2009
    Free Software Foundation, Inc.
 
 This file is part of GCC.
@@ -124,9 +124,12 @@ extern void ggc_mark_stringpool	(void);
 extern void ggc_purge_stringpool (void);
 
 /* Call ggc_set_mark on all the roots.  */
-
 extern void ggc_mark_roots (void);
 
+/* Likewise set mark on all roots and also call an extra marking
+   routine if it is not null. */
+extern void ggc_mark_roots_extra_marking (gt_pointer_walker, void*);
+
 /* Save and restore the string pool entries for PCH.  */
 
 extern void gt_pch_save_stringpool (void);
@@ -270,6 +273,9 @@ extern const char *ggc_alloc_string (const char *c
    function is called, not during allocations.  */
 extern void ggc_collect	(void);
 
+/* Invoke the collector with an extra marking routine and data */
+extern void ggc_collect_extra_marking (gt_pointer_walker, void*);
+
 /* Return the number of bytes allocated at the indicated address.  */
 extern size_t ggc_get_size (const void *);
 
Index: gcc/ggc-common.c
===================================================================
--- gcc/ggc-common.c	(revision 143199)
+++ gcc/ggc-common.c	(working copy)
@@ -1,5 +1,5 @@
 /* Simple garbage collection for the GNU compiler.
-   Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
+   Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
    Free Software Foundation, Inc.
 
 This file is part of GCC.
@@ -87,10 +87,18 @@ ggc_htab_delete (void **slot, void *info)
 }
 
 /* Iterate through all registered roots and mark each element.  */
-
 void
 ggc_mark_roots (void)
 {
+  ggc_mark_roots_extra_marking ((gt_pointer_walker)0, (void*)0);
+}
+
+
+/* Iterate likewise through registered roots and also do some extra
+   marking. */
+void 
+ggc_mark_roots_extra_marking(gt_pointer_walker extramarker, void*extradata)
+{
   const struct ggc_root_tab *const *rt;
   const struct ggc_root_tab *rti;
   const struct ggc_cache_tab *const *ct;
@@ -109,6 +117,9 @@ ggc_mark_roots (void)
   if (ggc_protect_identifiers)
     ggc_mark_stringpool ();
 
+  if (extramarker)
+    (*extramarker) (extradata);
+
   /* Now scan all hash tables that have objects which are to be deleted if
      they are not already marked.  */
   for (ct = gt_ggc_cache_rtab; *ct; ct++)
@@ -1022,3 +1033,10 @@ dump_ggc_loc_statistics (bool final ATTRIBUTE_UNUS
   ggc_force_collect = false;
 #endif
 }
+
+/* Top level mark-and-sweep routine without extra marker. */
+void
+ggc_collect(void)
+{
+  ggc_collect_extra_marking ((gt_pointer_walker)0, (void*)0);
+}
Index: gcc/ggc-zone.c
===================================================================
--- gcc/ggc-zone.c	(revision 143199)
+++ gcc/ggc-zone.c	(working copy)
@@ -1,5 +1,5 @@
 /* "Bag-of-pages" zone garbage collector for the GNU compiler.
-   Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008
+   Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008, 2009
    Free Software Foundation, Inc.
 
    Contributed by Richard Henderson (rth@redhat.com) and Daniel Berlin
@@ -1915,7 +1915,7 @@ sweep_pages (struct alloc_zone *zone)
    if we collected, false otherwise.  */
 
 static bool
-ggc_collect_1 (struct alloc_zone *zone, bool need_marking)
+ggc_collect_1 (struct alloc_zone *zone, bool need_marking, gt_pointer_walker walkrout, void* walkdata)
 {
 #if 0
   /* */
@@ -1957,7 +1957,7 @@ static bool
   if (need_marking)
     {
       zone_allocate_marks ();
-      ggc_mark_roots ();
+      ggc_mark_roots_extra_marking (walkrout, walkdata);
 #ifdef GATHER_STATISTICS
       ggc_prune_overhead_list ();
 #endif
@@ -2000,7 +2000,7 @@ calculate_average_page_survival (struct alloc_zone
 /* Top level collection routine.  */
 
 void
-ggc_collect (void)
+ggc_collect_extra_marking (gt_pointer_walker walkrout, void* walkdata)
 {
   struct alloc_zone *zone;
   bool marked = false;
@@ -2031,7 +2031,7 @@ void
 
   /* Start by possibly collecting the main zone.  */
   main_zone.was_collected = false;
-  marked |= ggc_collect_1 (&main_zone, true);
+  marked |= ggc_collect_1 (&main_zone, true, walkrout, walkdata);
 
   /* In order to keep the number of collections down, we don't
      collect other zones unless we are collecting the main zone.  This
Index: gcc/ggc-page.c
===================================================================
--- gcc/ggc-page.c	(revision 143199)
+++ gcc/ggc-page.c	(working copy)
@@ -1,5 +1,5 @@
 /* "Bag-of-pages" garbage collector for the GNU compiler.
-   Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008
+   Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008, 2009
    Free Software Foundation, Inc.
 
 This file is part of GCC.
@@ -1904,10 +1904,11 @@ validate_free_objects (void)
 #define validate_free_objects()
 #endif
 
-/* Top level mark-and-sweep routine.  */
 
+
+/* Top level mark-and-sweep routine with extra marker  */
 void
-ggc_collect (void)
+ggc_collect_extra_marking (gt_pointer_walker walkrout, void* walkdata)
 {
   /* Avoid frequent unnecessary work by skipping collection if the
      total allocations haven't expanded much since the last
@@ -1938,7 +1939,7 @@ void
   G.context_depth_collections = ((unsigned long)1 << (G.context_depth + 1)) - 1;
 
   clear_marks ();
-  ggc_mark_roots ();
+  ggc_mark_roots_extra_marking (walkrout, walkdata);
 #ifdef GATHER_STATISTICS
   ggc_prune_overhead_list ();
 #endif

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]