diff options
-rw-r--r-- | gcc/ChangeLog | 10 | ||||
-rw-r--r-- | gcc/config.in | 6 | ||||
-rwxr-xr-x | gcc/configure | 2 | ||||
-rw-r--r-- | gcc/configure.ac | 2 | ||||
-rw-r--r-- | gcc/ggc-page.c | 48 |
5 files changed, 65 insertions, 3 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index f367a11..3c8b7b5 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,13 @@ +2011-10-08 Andi Kleen <ak@linux.intel.com> + + PR other/50636 + * config.in, configure: Regenerate. + * configure.ac (madvise): Add to AC_CHECK_FUNCS. + * ggc-page.c (USING_MADVISE): Add. + (page_entry): Add discarded field. + (alloc_page): Check for discarded pages. + (release_pages): Add USING_MADVISE branch. + 2011-10-17 Richard Guenther <rguenther@suse.de> PR tree-optimization/50729 diff --git a/gcc/config.in b/gcc/config.in index f2847d8..e8148b6 100644 --- a/gcc/config.in +++ b/gcc/config.in @@ -1276,6 +1276,12 @@ #endif +/* Define to 1 if you have the `madvise' function. */ +#ifndef USED_FOR_TARGET +#undef HAVE_MADVISE +#endif + + /* Define to 1 if you have the <malloc.h> header file. */ #ifndef USED_FOR_TARGET #undef HAVE_MALLOC_H diff --git a/gcc/configure b/gcc/configure index cb55dda..4a54adf 100755 --- a/gcc/configure +++ b/gcc/configure @@ -9001,7 +9001,7 @@ fi for ac_func in times clock kill getrlimit setrlimit atoll atoq \ sysconf strsignal getrusage nl_langinfo \ gettimeofday mbstowcs wcswidth mmap setlocale \ - clearerr_unlocked feof_unlocked ferror_unlocked fflush_unlocked fgetc_unlocked fgets_unlocked fileno_unlocked fprintf_unlocked fputc_unlocked fputs_unlocked fread_unlocked fwrite_unlocked getchar_unlocked getc_unlocked putchar_unlocked putc_unlocked + clearerr_unlocked feof_unlocked ferror_unlocked fflush_unlocked fgetc_unlocked fgets_unlocked fileno_unlocked fprintf_unlocked fputc_unlocked fputs_unlocked fread_unlocked fwrite_unlocked getchar_unlocked getc_unlocked putchar_unlocked putc_unlocked madvise do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" diff --git a/gcc/configure.ac b/gcc/configure.ac index a7b94e6..357902e 100644 --- a/gcc/configure.ac +++ b/gcc/configure.ac @@ -1027,7 +1027,7 @@ define(gcc_UNLOCKED_FUNCS, clearerr_unlocked feof_unlocked dnl AC_CHECK_FUNCS(times clock kill getrlimit setrlimit atoll atoq \ sysconf strsignal getrusage nl_langinfo \ gettimeofday mbstowcs wcswidth mmap setlocale \ - gcc_UNLOCKED_FUNCS) + gcc_UNLOCKED_FUNCS madvise) if test x$ac_cv_func_mbstowcs = xyes; then AC_CACHE_CHECK(whether mbstowcs works, gcc_cv_func_mbstowcs_works, diff --git a/gcc/ggc-page.c b/gcc/ggc-page.c index beee851..9b35291 100644 --- a/gcc/ggc-page.c +++ b/gcc/ggc-page.c @@ -50,6 +50,10 @@ along with GCC; see the file COPYING3. If not see #define USING_MALLOC_PAGE_GROUPS #endif +#if defined(HAVE_MADVISE) && defined(MADV_DONTNEED) +# define USING_MADVISE +#endif + /* Strategy: This garbage-collecting allocator allocates objects on one of a set @@ -277,6 +281,9 @@ typedef struct page_entry /* The lg of size of objects allocated from this page. */ unsigned char order; + /* Discarded page? */ + bool discarded; + /* A bit vector indicating whether or not objects are in use. The Nth bit is one if the Nth object on this page is allocated. This array is dynamically sized. */ @@ -740,6 +747,10 @@ alloc_page (unsigned order) if (p != NULL) { + if (p->discarded) + G.bytes_mapped += p->bytes; + p->discarded = false; + /* Recycle the allocated memory from this page ... */ *pp = p->next; page = p->page; @@ -956,7 +967,42 @@ free_page (page_entry *entry) static void release_pages (void) { -#ifdef USING_MMAP +#ifdef USING_MADVISE + page_entry *p, *start_p; + char *start; + size_t len; + + for (p = G.free_pages; p; ) + { + if (p->discarded) + { + p = p->next; + continue; + } + start = p->page; + len = p->bytes; + start_p = p; + p = p->next; + while (p && p->page == start + len) + { + len += p->bytes; + p = p->next; + } + /* Give the page back to the kernel, but don't free the mapping. + This avoids fragmentation in the virtual memory map of the + process. Next time we can reuse it by just touching it. */ + madvise (start, len, MADV_DONTNEED); + /* Don't count those pages as mapped to not touch the garbage collector + unnecessarily. */ + G.bytes_mapped -= len; + while (start_p != p) + { + start_p->discarded = true; + start_p = start_p->next; + } + } +#endif +#if defined(USING_MMAP) && !defined(USING_MADVISE) page_entry *p, *next; char *start; size_t len; |