Reducing memory consumption

Martin v. Loewis martin@loewis.home.cs.tu-berlin.de
Sat Mar 18 09:42:00 GMT 2000


This patch reduces the memory consumption of g++ by collecting garbage
even during the "parsing" phase, rather than waiting for the first
time when code is generated.

It introduces a new trigger function gcc_collect_rarely, which only
triggers collection when memory consumption has at least doubled; in
the beginning, it even needs to triple until something is done.

The full bootstrap + test suite of this patch was done on
i586-pc-linux-gnu.

Regards,
Martin

2000-03-18  Martin v. Löwis  <loewis@informatik.hu-berlin.de>

	* ggc-page.c (ggc_collect_rarely, ggc_collect_body): New
	functions.
	* ggc-simple.c (ggc_collect_rarely, ggc_collect_body): Likewise.
        * ggc.h (ggc_collect_rarely): Declare it.

2000-03-18  Martin v. Löwis  <loewis@informatik.hu-berlin.de>

	* parse.y (extdefs): Call ggc_collect_rarely.

Index: ggc-page.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/ggc-page.c,v
retrieving revision 1.24
diff -u -p -r1.24 ggc-page.c
--- ggc-page.c	2000/03/07 20:39:05	1.24
+++ ggc-page.c	2000/03/18 17:30:29
@@ -1100,19 +1100,11 @@ poison_pages ()
 
 /* Top level mark-and-sweep routine.  */
 
-void
-ggc_collect ()
+static void
+ggc_collect_body ()
 {
   int time;
 
-  /* Avoid frequent unnecessary work by skipping collection if the
-     total allocations haven't expanded much since the last
-     collection.  */
-#ifndef GGC_ALWAYS_COLLECT
-  if (G.allocated < GGC_MIN_EXPAND_FOR_GC * G.allocated_last_gc)
-    return;
-#endif
-
   time = get_run_time ();
   if (!quiet_flag)
     fprintf (stderr, " {GC %luk -> ", (unsigned long)G.allocated / 1024);
@@ -1146,6 +1138,32 @@ ggc_collect ()
       fprintf (stderr, "%luk in %.3f}", 
 	       (unsigned long) G.allocated / 1024, time * 1e-6);
     }
+}
+
+void
+ggc_collect ()
+{
+  /* Avoid frequent unnecessary work by skipping collection if the
+     total allocations haven't expanded much since the last
+     collection.  */
+#ifndef GGC_ALWAYS_COLLECT
+  if (G.allocated < GGC_MIN_EXPAND_FOR_GC * G.allocated_last_gc)
+    return;
+#endif
+  ggc_collect_body ();
+}
+
+void
+ggc_collect_rarely ()
+{
+  /* This gives a higher threshold than ggc_collect: When memory usage
+     is low, it has to at least triple before this functions activates
+     collection; if memory consumption is high, it has to double.  */
+#ifndef GGC_ALWAYS_COLLECT
+  if (G.allocated < 2 * G.allocated_last_gc + GGC_MIN_LAST_ALLOCATED)
+    return;
+#endif
+  ggc_collect_body ();
 }
 
 /* Print allocation statistics.  */
Index: ggc-simple.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/ggc-simple.c,v
retrieving revision 1.31
diff -u -p -r1.31 ggc-simple.c
--- ggc-simple.c	2000/03/07 20:39:05	1.31
+++ ggc-simple.c	2000/03/18 17:30:29
@@ -336,16 +336,11 @@ sweep_objs (root)
 
 /* The top level mark-and-sweep routine.  */
 
-void
-ggc_collect ()
+static void
+ggc_collect_body ()
 {
   int time;
 
-#ifndef GGC_ALWAYS_COLLECT
-  if (G.allocated < GGC_MIN_EXPAND_FOR_GC * G.allocated_last_gc)
-    return;
-#endif
-
 #ifdef GGC_BALANCE
   debug_ggc_balance ();
 #endif
@@ -377,6 +372,26 @@ ggc_collect ()
 #ifdef GGC_BALANCE
   debug_ggc_balance ();
 #endif
+}
+
+void
+ggc_collect ()
+{
+#ifndef GGC_ALWAYS_COLLECT
+  if (G.allocated < GGC_MIN_EXPAND_FOR_GC * G.allocated_last_gc)
+    return;
+#endif
+  ggc_collect_body ();
+}
+
+void
+ggc_collect_rarely ()
+{
+#ifndef GGC_ALWAYS_COLLECT
+  if (G.allocated < 2 * G.allocated_last_gc + GGC_MIN_LAST_ALLOCATED)
+    return;
+#endif
+  ggc_collect_body ();
 }
 
 /* Called once to initialize the garbage collector.  */
Index: ggc.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/ggc.h,v
retrieving revision 1.24
diff -u -p -r1.24 ggc.h
--- ggc.h	2000/03/07 20:39:05	1.24
+++ ggc.h	2000/03/18 17:30:29
@@ -146,6 +146,10 @@ char *ggc_alloc_string PARAMS ((const ch
    the simple collector, the only time it will happen.  */
 void ggc_collect PARAMS ((void));
 
+/* Invoke the collector.  This function should be used when there is
+   probably not much garbage since the last collection.  */
+void ggc_collect_rarely PARAMS ((void));
+
 /* Actually set the mark on a particular region of memory, but don't
    follow pointers.  This function is called by ggc_mark_*.  It
    returns zero if the object was not previously marked; non-zero if
Index: cp/parse.y
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/parse.y,v
retrieving revision 1.168
diff -u -p -r1.168 parse.y
--- parse.y	2000/02/26 20:15:46	1.168
+++ parse.y	2000/03/18 17:30:48
@@ -441,9 +441,9 @@ program:
 extdefs:
 		{ $<ttype>$ = NULL_TREE; }
 	  lang_extdef
-		{ $<ttype>$ = NULL_TREE; }
+		{ $<ttype>$ = NULL_TREE; ggc_collect_rarely (); }
 	| extdefs lang_extdef
-		{ $<ttype>$ = NULL_TREE; }
+		{ $<ttype>$ = NULL_TREE; ggc_collect_rarely (); }
 	;
 
 extdefs_opt:


More information about the Gcc-patches mailing list