summaryrefslogtreecommitdiff
path: root/gcc/ggc-common.c
diff options
context:
space:
mode:
authorgeoffk <geoffk@138bc75d-0d04-0410-961f-82ee72b054a4>2004-08-09 20:19:30 +0000
committergeoffk <geoffk@138bc75d-0d04-0410-961f-82ee72b054a4>2004-08-09 20:19:30 +0000
commit4cb2b0ddbbeeb80df6f8ce7fc37c0a6b1a348994 (patch)
treedf6c93a853578b39eba773b6fd6680e05533dc64 /gcc/ggc-common.c
parenta8046f6028a5b566796bea8409ceea78b0c9c5f2 (diff)
downloadgcc-4cb2b0ddbbeeb80df6f8ce7fc37c0a6b1a348994.tar.gz
* ggc-common.c (ggc_rlimit_bound): Don't check RSS limit.
Check DATA limit only if there's no AS limit. Ignore insanely low DATA limits. (ggc_min_heapsize_heuristic): Don't divide AS or RSS limits by 8, but take care that the AS limit isn't overrun. * doc/invoke.texi: Update documentation of min-heapsize parameter. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@85722 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/ggc-common.c')
-rw-r--r--gcc/ggc-common.c67
1 files changed, 45 insertions, 22 deletions
diff --git a/gcc/ggc-common.c b/gcc/ggc-common.c
index cc0dc93be84..5c99175d663 100644
--- a/gcc/ggc-common.c
+++ b/gcc/ggc-common.c
@@ -669,30 +669,34 @@ mmap_gt_pch_use_address (void *base, size_t size, int fd, size_t offset)
}
#endif /* HAVE_MMAP_FILE */
-/* Modify the bound based on rlimits. Keep the smallest number found. */
+/* Modify the bound based on rlimits. */
static double
ggc_rlimit_bound (double limit)
{
#if defined(HAVE_GETRLIMIT)
struct rlimit rlim;
-# ifdef RLIMIT_RSS
- if (getrlimit (RLIMIT_RSS, &rlim) == 0
+# if defined (RLIMIT_AS)
+ /* RLIMIT_AS is what POSIX says is the limit on mmap. Presumably
+ any OS which has RLIMIT_AS also has a working mmap that GCC will use. */
+ if (getrlimit (RLIMIT_AS, &rlim) == 0
&& rlim.rlim_cur != (rlim_t) RLIM_INFINITY
&& rlim.rlim_cur < limit)
limit = rlim.rlim_cur;
-# endif
-# ifdef RLIMIT_DATA
+# elif defined (RLIMIT_DATA)
+ /* ... but some older OSs bound mmap based on RLIMIT_DATA, or we
+ might be on an OS that has a broken mmap. (Others don't bound
+ mmap at all, apparently.) */
if (getrlimit (RLIMIT_DATA, &rlim) == 0
&& rlim.rlim_cur != (rlim_t) RLIM_INFINITY
- && rlim.rlim_cur < limit)
- limit = rlim.rlim_cur;
-# endif
-# ifdef RLIMIT_AS
- if (getrlimit (RLIMIT_AS, &rlim) == 0
- && rlim.rlim_cur != (rlim_t) RLIM_INFINITY
- && rlim.rlim_cur < limit)
+ && rlim.rlim_cur < limit
+ /* Darwin has this horribly bogus default setting of
+ RLIMIT_DATA, to 6144Kb. No-one notices because RLIMIT_DATA
+ appears to be ignored. Ignore such silliness. If a limit
+ this small was actually effective for mmap, GCC wouldn't even
+ start up. */
+ && rlim.rlim_cur >= 8 * 1024 * 1024)
limit = rlim.rlim_cur;
-# endif
+# endif /* RLIMIT_AS or RLIMIT_DATA */
#endif /* HAVE_GETRLIMIT */
return limit;
@@ -721,20 +725,39 @@ ggc_min_expand_heuristic (void)
int
ggc_min_heapsize_heuristic (void)
{
- double min_heap_kbytes = physmem_total();
-
- /* Adjust for rlimits. */
- min_heap_kbytes = ggc_rlimit_bound (min_heap_kbytes);
+ double phys_kbytes = physmem_total();
+ double limit_kbytes = ggc_rlimit_bound (phys_kbytes * 2);
- min_heap_kbytes /= 1024; /* Convert to Kbytes. */
+ phys_kbytes /= 1024; /* Convert to Kbytes. */
+ limit_kbytes /= 1024;
/* The heuristic is RAM/8, with a lower bound of 4M and an upper
bound of 128M (when RAM >= 1GB). */
- min_heap_kbytes /= 8;
- min_heap_kbytes = MAX (min_heap_kbytes, 4 * 1024);
- min_heap_kbytes = MIN (min_heap_kbytes, 128 * 1024);
+ phys_kbytes /= 8;
+
+#if defined(HAVE_GETRLIMIT) && defined (RLIMIT_RSS)
+ /* Try not to overrun the RSS limit while doing garbage collection.
+ The RSS limit is only advisory, so no margin is subtracted. */
+ {
+ struct rlimit rlim;
+ if (getrlimit (RLIMIT_RSS, &rlim) == 0
+ && rlim.rlim_cur != (rlim_t) RLIM_INFINITY)
+ phys_kbytes = MIN (phys_kbytes, rlim.rlim_cur / 1024);
+ }
+# endif
+
+ /* Don't blindly run over our data limit; do GC at least when the
+ *next* GC would be within 16Mb of the limit. If GCC does hit the
+ data limit, compilation will fail, so this tries to be
+ conservative. */
+ limit_kbytes = MAX (0, limit_kbytes - 16 * 1024);
+ limit_kbytes = (limit_kbytes * 100) / (110 + ggc_min_expand_heuristic());
+ phys_kbytes = MIN (phys_kbytes, limit_kbytes);
+
+ phys_kbytes = MAX (phys_kbytes, 4 * 1024);
+ phys_kbytes = MIN (phys_kbytes, 128 * 1024);
- return min_heap_kbytes;
+ return phys_kbytes;
}
void