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]

adding GGC events for plugins.


Hello All

The attached patch to trunk rev147426 add some events in plugins for GGC (the GCC garbage collector).

In particular, it provides the following features to future plugins:

The plugin events PLUGIN_GGC_START and PLUGIN_GGC_END are called by ggc_collect at start and at end of garbage collection.

The plugin event PLUGIN_GGC_MARKING is called by ggc_mark_roots and could be used by the plugins which need to mark some extra data.

The function ggc_register_root_tab is added to register extra GGC roots, and can be used by plugins using the plugin event PLUGIN_REGISTER_GGC_ROOTS.
Of course, what is missing is some extension to gengtype to generate the marking routines; together, that would enable plugins to have their own GTY-ed stuff.


A real-case scenario for these would be to make the MELT branch a mega-plugin itself. I documented on the wiki on http://gcc.gnu.org/wiki/memory%20management%20in%20MELT why all these features (or something equivalent) are essential for making MELT a plugin. This page also explains precisely the memory management in MELT (which I believe few people understand in details).

For people interested in MELT, I am also writing on the wiki some tutorial pages.

Is the attached patch ok for trunk.?


Respectful 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} ***

Index: gcc/doc/plugins.texi
===================================================================
--- gcc/doc/plugins.texi	(revision 147426)
+++ gcc/doc/plugins.texi	(working copy)
@@ -9,7 +9,7 @@
 
 @section Loading Plugins
 
-Plugins are supported on platforms that support @option{-ld
+Plugins are supported on platforms that support @option{-ldl
 -rdynamic}.  They are loaded by the compiler using @code{dlopen}
 and invoked at pre-determined locations in the compilation
 process.
@@ -71,6 +71,9 @@
   PLUGIN_FINISH_UNIT,           /* Useful for summary processing.  */
   PLUGIN_CXX_CP_PRE_GENERICIZE, /* Allows to see low level AST in C++ FE.  */
   PLUGIN_FINISH,                /* Called before GCC exits.  */
+  PLUGIN_GGC_START,		/* Called at start of Gcc Garbage Collection */
+  PLUGIN_GGC_MARKING,		/* To extend the GGC marking */
+  PLUGIN_GGC_END,		/* Called at end of GGC */
   PLUGIN_EVENT_LAST             /* Dummy event used for indexing callback
                                    array.  */
 @};
Index: gcc/ggc.h
===================================================================
--- gcc/ggc.h	(revision 147426)
+++ gcc/ggc.h	(working copy)
@@ -1,7 +1,8 @@
 /* Garbage collection for the GNU compiler.
-   Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008
-   Free Software Foundation, Inc.
 
+   Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007,
+   2008, 2009 Free Software Foundation, Inc.
+
 This file is part of GCC.
 
 GCC is free software; you can redistribute it and/or modify it under
@@ -270,6 +271,9 @@
    function is called, not during allocations.  */
 extern void ggc_collect	(void);
 
+/* Register an additional root tab. This can be useful to plugins */
+extern void ggc_register_root_tab (const struct ggc_root_tab*);
+
 /* Return the number of bytes allocated at the indicated address.  */
 extern size_t ggc_get_size (const void *);
 
Index: gcc/gcc-plugin.h
===================================================================
--- gcc/gcc-plugin.h	(revision 147426)
+++ gcc/gcc-plugin.h	(working copy)
@@ -29,6 +29,10 @@
   PLUGIN_CXX_CP_PRE_GENERICIZE, /* Allows to see low level AST in C++ FE.  */
   PLUGIN_FINISH,                /* Called before GCC exits.  */
   PLUGIN_INFO,                  /* Information about the plugin */
+  PLUGIN_GGC_START,		/* Called at start of Gcc Garbage Collection */
+  PLUGIN_GGC_MARKING,		/* To extend the GGC marking */
+  PLUGIN_GGC_END,		/* Called at end of GGC */
+  PLUGIN_REGISTER_GGC_ROOTS,	/* register an extra GGC root table */
   PLUGIN_EVENT_LAST             /* Dummy event used for indexing callback
                                    array.  */
 };
Index: gcc/ggc-common.c
===================================================================
--- gcc/ggc-common.c	(revision 147426)
+++ gcc/ggc-common.c	(working copy)
@@ -30,6 +30,7 @@
 #include "params.h"
 #include "hosthooks.h"
 #include "hosthooks-def.h"
+#include "plugin.h"
 
 #ifdef HAVE_SYS_RESOURCE_H
 # include <sys/resource.h>
@@ -86,6 +87,37 @@
   return 1;
 }
 
+
+/* extra table of dynamically registers root tab, its count and allocated length */
+static const struct ggc_root_tab**extra_root_tab;
+static size_t extra_root_count;
+static size_t extra_root_length;
+
+void 
+ggc_register_root_tab (const struct ggc_root_tab* rt)
+{
+  if (!rt)
+    return;
+  if (!extra_root_tab) 
+    {
+      extra_root_length = 32;
+      extra_root_count = 0;
+      extra_root_tab = XNEWVEC (const struct ggc_root_tab*, extra_root_length);
+      memset(extra_root_tab, 0, sizeof(extra_root_tab[0]) * extra_root_length);
+    }
+  else if (extra_root_count >= extra_root_length)
+    {
+      const struct ggc_root_tab** oldtab = extra_root_tab;
+      size_t oldlen = extra_root_length;
+      extra_root_length *= 2;
+      extra_root_tab = XNEWVEC (const struct ggc_root_tab*, extra_root_length);
+      memcpy (extra_root_tab, oldtab, sizeof(extra_root_tab[0]) * extra_root_count);
+      memset (extra_root_tab + extra_root_count, 0, 
+	      sizeof(extra_root_tab[0]) * (extra_root_length - extra_root_count));
+    };
+  extra_root_tab[extra_root_count++] = rt;
+}
+
 /* Iterate through all registered roots and mark each element.  */
 
 void
@@ -106,6 +138,18 @@
       for (i = 0; i < rti->nelt; i++)
 	(*rti->cb)(*(void **)((char *)rti->base + rti->stride * i));
 
+  if (extra_root_tab)
+    {
+      i = 0;
+      for (i=0; i<extra_root_count; i++) 
+	{
+	  rt = extra_root_tab[i];
+	  for (rti = *rt; rti->base != NULL; rti++)
+	    for (i = 0; i < rti->nelt; i++)
+	      (*rti->cb)(*(void **)((char *)rti->base + rti->stride * i));
+	}
+    }
+
   if (ggc_protect_identifiers)
     ggc_mark_stringpool ();
 
@@ -123,6 +167,10 @@
 
   if (! ggc_protect_identifiers)
     ggc_purge_stringpool ();
+
+  /* some plugins may need to register their routine mark additional
+     data */
+  invoke_plugin_callbacks (PLUGIN_GGC_MARKING, NULL);
 }
 
 /* Allocate a block of memory, then clear it.  */
Index: gcc/ggc-zone.c
===================================================================
--- gcc/ggc-zone.c	(revision 147426)
+++ gcc/ggc-zone.c	(working copy)
@@ -2029,6 +2029,9 @@
 	}
     }
 
+  /* Some plugins may need to know when GGC is really starting */
+  invoke_plugin_callbacks (PLUGIN_GGC_START, NULL);
+
   /* Start by possibly collecting the main zone.  */
   main_zone.was_collected = false;
   marked |= ggc_collect_1 (&main_zone, true);
@@ -2093,6 +2096,9 @@
 	}
     }
 
+  /* Some plugins may need to know when GGC ended */
+  invoke_plugin_callbacks (PLUGIN_GGC_END, NULL);
+
   timevar_pop (TV_GC);
 }
 
Index: gcc/ggc-page.c
===================================================================
--- gcc/ggc-page.c	(revision 147426)
+++ gcc/ggc-page.c	(working copy)
@@ -31,6 +31,7 @@
 #include "timevar.h"
 #include "params.h"
 #include "tree-flow.h"
+#include "plugin.h"
 
 /* Prefer MAP_ANON(YMOUS) to /dev/zero, since we don't need to keep a
    file open.  Prefer either to valloc.  */
@@ -1937,6 +1938,9 @@
   /* Indicate that we've seen collections at this context depth.  */
   G.context_depth_collections = ((unsigned long)1 << (G.context_depth + 1)) - 1;
 
+  /* Some plugins may need to know when GGC is really starting */
+  invoke_plugin_callbacks (PLUGIN_GGC_START, NULL);
+
   clear_marks ();
   ggc_mark_roots ();
 #ifdef GATHER_STATISTICS
@@ -1948,6 +1952,9 @@
 
   G.allocated_last_gc = G.allocated;
 
+  /* Some plugins may need to know when GGC ended */
+  invoke_plugin_callbacks (PLUGIN_GGC_END, NULL);
+
   timevar_pop (TV_GC);
 
   if (!quiet_flag)
Index: gcc/plugin.c
===================================================================
--- gcc/plugin.c	(revision 147426)
+++ gcc/plugin.c	(working copy)
@@ -38,6 +38,8 @@
 #include "intl.h"
 #include "plugin.h"
 #include "timevar.h"
+#include "ggc.h"
+
 #ifdef ENABLE_PLUGIN
 #include "plugin-version.h"
 #endif
@@ -51,6 +53,10 @@
   "PLUGIN_CXX_CP_PRE_GENERICIZE",
   "PLUGIN_FINISH",
   "PLUGIN_INFO",
+  "PLUGIN_GGC_START",
+  "PLUGIN_GGC_MARKING",
+  "PLUGIN_GGC_END",
+  "PLUGIN_REGISTER_GGC_ROOTS",
   "PLUGIN_EVENT_LAST"
 };
 
@@ -490,9 +496,15 @@
       case PLUGIN_INFO:
 	register_plugin_info (plugin_name, (struct plugin_info *) user_data);
 	break;
+      case PLUGIN_REGISTER_GGC_ROOTS:
+        ggc_register_root_tab ((const struct ggc_root_tab*) user_data);
+	break;
       case PLUGIN_FINISH_TYPE:
       case PLUGIN_FINISH_UNIT:
       case PLUGIN_CXX_CP_PRE_GENERICIZE:
+      case PLUGIN_GGC_START:
+      case PLUGIN_GGC_MARKING:
+      case PLUGIN_GGC_END:
       case PLUGIN_FINISH:
         {
           struct callback_info *new_callback;
@@ -535,6 +547,9 @@
       case PLUGIN_FINISH_UNIT:
       case PLUGIN_CXX_CP_PRE_GENERICIZE:
       case PLUGIN_FINISH:
+      case PLUGIN_GGC_START:
+      case PLUGIN_GGC_MARKING:
+      case PLUGIN_GGC_END:
         {
           /* Iterate over every callback registered with this event and
              call it.  */
@@ -546,6 +561,7 @@
 
       case PLUGIN_PASS_MANAGER_SETUP:
       case PLUGIN_EVENT_LAST:
+      case PLUGIN_REGISTER_GGC_ROOTS:
       default:
         gcc_assert (false);
     }
Index: gcc/Makefile.in
===================================================================
--- gcc/Makefile.in	(revision 147426)
+++ gcc/Makefile.in	(working copy)
@@ -2481,7 +2481,7 @@
    gt-passes.h $(DF_H) $(PREDICT_H)
 
 plugin.o : plugin.c $(PLUGIN_H) $(CONFIG_H) $(SYSTEM_H) coretypes.h \
-   $(TOPLEV_H) $(TREE_H) $(TREE_PASS_H) intl.h $(PLUGIN_VERSION_H)
+   $(TOPLEV_H) $(TREE_H) $(TREE_PASS_H) intl.h $(PLUGIN_VERSION_H) $(GGC_H)
 
 main.o : main.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TOPLEV_H)
 
2009-05-12  Basile Starynkevitch  <basile@starynkevitch.net>
	* gcc/doc/plugins.texi: Mentioned PLUGIN_GGC_START,
	PLUGIN_GGC_MARKING, PLUGIN_GGC_END.
	* gcc/ggc.h: Declared ggc_register_root_tab.
	* gcc/gcc-plugin.h (enum plugin_event): Added PLUGIN_GGC_START,
	PLUGIN_GGC_MARKING, PLUGIN_GGC_END, PLUGIN_REGISTER_GGC_ROOTS.
	* gcc/ggc-common.c: including "plugin.h".
	(extra_root_tab, extra_root_count, extra_root_length): new static
	variables.
	(ggc_register_root_tab): added new function.
	(ggc_mark_roots): scan the extra_root_tab if needed, and do the
	PLUGIN_GGC_MARKING callback.
	* gcc/ggc-zone.c (ggc_collect): call PLUGIN_GGC_START &
	PLUGIN_GGC_END callbacks.
	* gcc/ggc-page.c (ggc_collect): likewise.
	* gcc/plugin.c (plugin_event_name, register_callback)
	(invoke_plugin_callbacks): handle PLUGIN_GGC_START,
	PLUGIN_GGC_MARKING, PLUGIN_GGC_END, PLUGIN_REGISTER_GGC_ROOTS.
	* gcc/Makefile.in: plugin.o also depends upon $(GGC_H).

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