From d37e6b50362c82ee6bcb630a949e7e38830901ba Mon Sep 17 00:00:00 2001 From: Geoffrey Keating Date: Mon, 9 Aug 2004 20:19:30 +0000 Subject: [PATCH] ggc-common.c (ggc_rlimit_bound): Don't check RSS limit. * 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. From-SVN: r85722 --- gcc/ChangeLog | 9 ++++++ gcc/doc/invoke.texi | 18 ++++++------ gcc/ggc-common.c | 67 ++++++++++++++++++++++++++++++--------------- 3 files changed, 63 insertions(+), 31 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 359f0cfb79e..8ce8ab9705d 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,12 @@ +2004-08-09 Geoffrey Keating + + * 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. + 2004-08-09 Jeff Law * Makefile.in (OBJC-common): Add tree-ssa-threadupdate.c diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index 0018fc60183..bf41ffb426a 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -5310,7 +5310,7 @@ generation. The default is 30% + 70% * (RAM/1GB) with an upper bound of 100% when RAM >= 1GB. If @code{getrlimit} is available, the notion of "RAM" is -the smallest of actual RAM, RLIMIT_RSS, RLIMIT_DATA and RLIMIT_AS. If +the smallest of actual RAM and RLIMIT_DATA or RLIMIT_AS. If GCC is not able to calculate RAM on a particular platform, the lower bound of 30% is used. Setting this parameter and @option{ggc-min-heapsize} to zero causes a full collection to occur at @@ -5325,14 +5325,14 @@ by @option{ggc-min-expand}% beyond @option{ggc-min-heapsize}. Again, tuning this may improve compilation speed, and has no effect on code generation. -The default is RAM/8, with a lower bound of 4096 (four megabytes) and an -upper bound of 131072 (128 megabytes). If @code{getrlimit} is -available, the notion of "RAM" is the smallest of actual RAM, -RLIMIT_RSS, RLIMIT_DATA and RLIMIT_AS. If GCC is not able to calculate -RAM on a particular platform, the lower bound is used. Setting this -parameter very large effectively disables garbage collection. Setting -this parameter and @option{ggc-min-expand} to zero causes a full -collection to occur at every opportunity. +The default is the smaller of RAM/8, RLIMIT_RSS, or a limit which +tries to ensure that RLIMIT_DATA or RLIMIT_AS are not exceeded, but +with a lower bound of 4096 (four megabytes) and an upper bound of +131072 (128 megabytes). If GCC is not able to calculate RAM on a +particular platform, the lower bound is used. Setting this parameter +very large effectively disables garbage collection. Setting this +parameter and @option{ggc-min-expand} to zero causes a full collection +to occur at every opportunity. @item max-reload-search-insns The maximum number of instruction reload should look backward for equivalent 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 -- 2.30.2