diff options
author | geoffk <geoffk@138bc75d-0d04-0410-961f-82ee72b054a4> | 2004-08-09 20:19:30 +0000 |
---|---|---|
committer | geoffk <geoffk@138bc75d-0d04-0410-961f-82ee72b054a4> | 2004-08-09 20:19:30 +0000 |
commit | 4cb2b0ddbbeeb80df6f8ce7fc37c0a6b1a348994 (patch) | |
tree | df6c93a853578b39eba773b6fd6680e05533dc64 /gcc/ggc-common.c | |
parent | a8046f6028a5b566796bea8409ceea78b0c9c5f2 (diff) | |
download | gcc-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.c | 67 |
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 |