Add the --disable-munmap option.

Add the --disable-munmap option, remove the configure test that
attempted to detect the VM allocation quirk known to exist on Linux
x86[_64], and make --disable-munmap implicit on Linux.
diff --git a/INSTALL b/INSTALL
index a5942ec..04671a1 100644
--- a/INSTALL
+++ b/INSTALL
@@ -108,6 +108,13 @@
     released in bulk, thus reducing the total number of mutex operations.  See
     the "opt.tcache" option for usage details.
 
+--disable-munmap
+    Disable virtual memory deallocation via munmap(2); instead keep track of
+    the virtual memory for later use.  munmap() is disabled by default (i.e.
+    --disable-munmap is implied) on Linux, which has a quirk in its virtual
+    memory allocation algorithm that causes semi-permanent VM map holes under
+    normal jemalloc operation.
+
 --enable-dss
     Enable support for page allocation/deallocation via sbrk(2), in addition to
     mmap(2).
diff --git a/configure.ac b/configure.ac
index 5d0c726..90235f7 100644
--- a/configure.ac
+++ b/configure.ac
@@ -206,6 +206,7 @@
 dnl Define cpp macros in CPPFLAGS, rather than doing AC_DEFINE(macro), since the
 dnl definitions need to be seen before any headers are included, which is a pain
 dnl to make happen otherwise.
+default_munmap="1"
 case "${host}" in
   *-*-darwin*)
 	CFLAGS="$CFLAGS -fno-common"
@@ -230,6 +231,7 @@
 	AC_DEFINE([JEMALLOC_PURGE_MADVISE_DONTNEED], [ ])
 	AC_DEFINE([JEMALLOC_THREADED_INIT], [ ])
 	RPATH="-Wl,-rpath,"
+	default_munmap="0"
 	;;
   *-*-netbsd*)
 	AC_MSG_CHECKING([ABI])
@@ -667,6 +669,22 @@
 fi
 AC_SUBST([enable_tcache])
 
+dnl Enable VM deallocation via munmap() by default.
+AC_ARG_ENABLE([munmap],
+  [AS_HELP_STRING([--disable-munmap], [Disable VM deallocation via munmap(2)])],
+[if test "x$enable_munmap" = "xno" ; then
+  enable_munmap="0"
+else
+  enable_munmap="1"
+fi
+],
+[enable_munmap="${default_munmap}"]
+)
+if test "x$enable_munmap" = "x1" ; then
+  AC_DEFINE([JEMALLOC_MUNMAP], [ ])
+fi
+AC_SUBST([enable_munmap])
+
 dnl Do not enable allocation from DSS by default.
 AC_ARG_ENABLE([dss],
   [AS_HELP_STRING([--enable-dss], [Enable allocation from DSS])],
@@ -817,72 +835,6 @@
    AC_MSG_ERROR([cannot determine value for STATIC_PAGE_SHIFT])
 fi
 
-dnl Determine whether common sequences of mmap()/munmap() calls will leave
-dnl semi-permanent VM map holes.  If so, disable munmap.
-AC_CACHE_CHECK([whether munmap() leaves semi-permanent VM map holes],
-               [je_cv_vmmap_hole],
-               AC_RUN_IFELSE([AC_LANG_PROGRAM(
-[[#include <stdio.h>
-#include <stdlib.h>
-#include <sys/mman.h>
-
-#define	MMAP_SIZE	((size_t)(1U << 22))
-
-static void *
-do_mmap(size_t size)
-{
-	void *ret;
-
-	ret = mmap(NULL, size, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANON, -1,
-	    0);
-	if (ret == MAP_FAILED) {
-		fprintf(stderr, "mmap() error\n");
-		exit(1);
-	}
-
-	return (ret);
-}
-
-static void
-do_munmap(void *ptr, size_t size)
-{
-	if (munmap(ptr, size) == -1) {
-		fprintf(stderr, "munmap() error\n");
-		exit(1);
-	}
-}
-]],
-[[
-	void *p0, *p1, *p2, *p3, *p4;
-	FILE *f;
-
-	f = fopen("conftest.out", "w");
-	if (f == NULL)
-		exit(1);
-
-	p0 = do_mmap(MMAP_SIZE);
-	p1 = do_mmap(MMAP_SIZE);
-	p2 = do_mmap(MMAP_SIZE);
-	do_munmap(p1, MMAP_SIZE);
-	p3 = do_mmap(MMAP_SIZE * 2);
-	do_munmap(p3, MMAP_SIZE * 2);
-	p4 = do_mmap(MMAP_SIZE);
-	if (p4 != p1) {
-		fprintf(stderr, "Hoped for %p, got %p\n", p1, p4);
-		fprintf(stderr, "%p..%p..%p..%p..%p\n", p0, p1, p2, p3, p4);
-		fprintf(f, "yes\n");
-	} else
-		fprintf(f, "no\n");
-
-	fclose(f);
-	return (0);
-]])],
-                             [je_cv_vmmap_hole=`cat conftest.out`],
-                             [je_cv_vmmap_hole=unknown]))
-if test "x$je_cv_vmmap_hole" = "xno" ; then
-  AC_DEFINE([JEMALLOC_MUNMAP], [ ])
-fi
-
 dnl ============================================================================
 dnl jemalloc configuration.
 dnl 
@@ -1198,6 +1150,7 @@
 AC_MSG_RESULT([utrace             : ${enable_utrace}])
 AC_MSG_RESULT([valgrind           : ${enable_valgrind}])
 AC_MSG_RESULT([xmalloc            : ${enable_xmalloc}])
+AC_MSG_RESULT([munmap             : ${enable_munmap}])
 AC_MSG_RESULT([dss                : ${enable_dss}])
 AC_MSG_RESULT([lazy_lock          : ${enable_lazy_lock}])
 AC_MSG_RESULT([tls                : ${enable_tls}])
diff --git a/doc/jemalloc.xml.in b/doc/jemalloc.xml.in
index ee60c98..98d0ba4 100644
--- a/doc/jemalloc.xml.in
+++ b/doc/jemalloc.xml.in
@@ -652,6 +652,16 @@
 
       <varlistentry>
         <term>
+          <mallctl>config.munmap</mallctl>
+          (<type>bool</type>)
+          <literal>r-</literal>
+        </term>
+        <listitem><para><option>--enable-munmap</option> was specified during
+        build configuration.</para></listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term>
           <mallctl>config.prof</mallctl>
           (<type>bool</type>)
           <literal>r-</literal>
diff --git a/src/ctl.c b/src/ctl.c
index 6be4056..a6a02cc 100644
--- a/src/ctl.c
+++ b/src/ctl.c
@@ -50,6 +50,7 @@
 CTL_PROTO(config_dss)
 CTL_PROTO(config_fill)
 CTL_PROTO(config_lazy_lock)
+CTL_PROTO(config_munmap)
 CTL_PROTO(config_prof)
 CTL_PROTO(config_prof_libgcc)
 CTL_PROTO(config_prof_libunwind)
@@ -176,6 +177,7 @@
 	{NAME("dss"),			CTL(config_dss)},
 	{NAME("fill"),			CTL(config_fill)},
 	{NAME("lazy_lock"),		CTL(config_lazy_lock)},
+	{NAME("munmap"),		CTL(config_munmap)},
 	{NAME("prof"),			CTL(config_prof)},
 	{NAME("prof_libgcc"),		CTL(config_prof_libgcc)},
 	{NAME("prof_libunwind"),	CTL(config_prof_libunwind)},
@@ -1087,6 +1089,7 @@
 CTL_RO_BOOL_CONFIG_GEN(config_dss)
 CTL_RO_BOOL_CONFIG_GEN(config_fill)
 CTL_RO_BOOL_CONFIG_GEN(config_lazy_lock)
+CTL_RO_BOOL_CONFIG_GEN(config_munmap)
 CTL_RO_BOOL_CONFIG_GEN(config_prof)
 CTL_RO_BOOL_CONFIG_GEN(config_prof_libgcc)
 CTL_RO_BOOL_CONFIG_GEN(config_prof_libunwind)