This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Reducing memory consumption
- To: gcc-patches at gcc dot gnu dot org
- Subject: Reducing memory consumption
- From: "Martin v. Loewis" <martin at loewis dot home dot cs dot tu-berlin dot de>
- Date: Sat, 18 Mar 2000 18:38:35 +0100
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: