changeset 3130:7d844153dc95

S8013057: Detect mmap() commit failures in Linux and Solaris os::commit_memory() impls and call vm_exit_out_of_memory() S7151089: PS NUMA: NUMA allocator should not attempt to free pages when using SHM large pages S8026887: Make issues due to failed large pages allocations easier to debug 2014-03-17 Andrew John Hughes <gnu.andrew@redhat.com> * Makefile.am: (ICEDTEA_PATCHES): Add new patches. * NEWS: Updated. * patches/openjdk/7151089-numa_should_not_free_shm_large_pages.patch, * patches/openjdk/8013057-detect_mmap_commit_failures.patch, * patches/openjdk/8026887-make_large_page_allocations_easier_to_debug.patch: Backports to improve mmap failure output.
author Andrew John Hughes <gnu.andrew@redhat.com>
date Tue, 18 Mar 2014 12:32:37 +0000
parents 963a9ab43d7f
children 975cb4907b2e
files ChangeLog Makefile.am NEWS patches/openjdk/7151089-numa_should_not_free_shm_large_pages.patch patches/openjdk/8013057-detect_mmap_commit_failures.patch patches/openjdk/8026887-make_large_page_allocations_easier_to_debug.patch
diffstat 6 files changed, 996 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog	Thu Jan 30 21:38:08 2014 +0000
+++ b/ChangeLog	Tue Mar 18 12:32:37 2014 +0000
@@ -1,3 +1,13 @@
+2014-03-17  Andrew John Hughes  <gnu.andrew@redhat.com>
+
+	* Makefile.am:
+	(ICEDTEA_PATCHES): Add new patches.
+	* NEWS: Updated.
+	* patches/openjdk/7151089-numa_should_not_free_shm_large_pages.patch,
+	* patches/openjdk/8013057-detect_mmap_commit_failures.patch,
+	* patches/openjdk/8026887-make_large_page_allocations_easier_to_debug.patch:
+	Backports to improve mmap failure output.
+
 2014-01-30  Andrew John Hughes  <gnu.andrew@redhat.com>
 
 	* NEWS: Add 1.11.15 release notes.
--- a/Makefile.am	Thu Jan 30 21:38:08 2014 +0000
+++ b/Makefile.am	Tue Mar 18 12:32:37 2014 +0000
@@ -630,7 +630,10 @@
 	patches/windows-jdk-sizecalc.patch \
 	patches/shark_fixes_from_8003868.patch \
 	patches/8003992_support_6.patch \
-	patches/shark-drop_compile_method_arg_following_7083786.patch
+	patches/shark-drop_compile_method_arg_following_7083786.patch \
+	patches/openjdk/7151089-numa_should_not_free_shm_large_pages.patch \
+	patches/openjdk/8013057-detect_mmap_commit_failures.patch \
+	patches/openjdk/8026887-make_large_page_allocations_easier_to_debug.patch
 
 if WITH_RHINO
 ICEDTEA_PATCHES += \
--- a/NEWS	Thu Jan 30 21:38:08 2014 +0000
+++ b/NEWS	Tue Mar 18 12:32:37 2014 +0000
@@ -14,6 +14,11 @@
 
 New in release 1.14.0 (201X-XX-XX):
 
+* Backports
+  - S7151089: PS NUMA: NUMA allocator should not attempt to free pages when using SHM large pages
+  - S8013057: Detect mmap() commit failures in Linux and Solaris os::commit_memory() impls and call vm_exit_out_of_memory()
+  - S8026887: Make issues due to failed large pages allocations easier to debug
+
 New in release 1.11.15 (2014-01-21):
 
 * Security fixes
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/patches/openjdk/7151089-numa_should_not_free_shm_large_pages.patch	Tue Mar 18 12:32:37 2014 +0000
@@ -0,0 +1,29 @@
+# HG changeset patch
+# User iveresov
+# Date 1331583127 25200
+#      Mon Mar 12 13:12:07 2012 -0700
+# Node ID 3f0dff7a9cf590ef3e5d7f2dcf6c8247b65c9d10
+# Parent  3442eb7ef2d216d6bf655d537929a2d31a76a321
+7151089: PS NUMA: NUMA allocator should not attempt to free pages when using SHM large pages
+Summary: Don't attempt to uncommit SHM-based large pages
+Reviewed-by: kvn
+
+diff -r 3442eb7ef2d2 -r 3f0dff7a9cf5 src/os/linux/vm/os_linux.cpp
+--- openjdk/hotspot/src/os/linux/vm/os_linux.cpp	Tue Jan 14 20:24:44 2014 -0500
++++ openjdk/hotspot/src/os/linux/vm/os_linux.cpp	Mon Mar 12 13:12:07 2012 -0700
+@@ -2568,7 +2568,14 @@
+ }
+ 
+ void os::free_memory(char *addr, size_t bytes, size_t alignment_hint) {
+-  commit_memory(addr, bytes, alignment_hint, false);
++  // This method works by doing an mmap over an existing mmaping and effectively discarding
++  // the existing pages. However it won't work for SHM-based large pages that cannot be
++  // uncommitted at all. We don't do anything in this case to avoid creating a segment with
++  // small pages on top of the SHM segment. This method always works for small pages, so we
++  // allow that in any case.
++  if (alignment_hint <= (size_t)os::vm_page_size() || !UseSHM) {
++    commit_memory(addr, bytes, alignment_hint, false);
++  }
+ }
+ 
+ void os::numa_make_global(char *addr, size_t bytes) {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/patches/openjdk/8013057-detect_mmap_commit_failures.patch	Tue Mar 18 12:32:37 2014 +0000
@@ -0,0 +1,867 @@
+# HG changeset patch
+# User dcubed
+# Date 1394474985 0
+#      Mon Mar 10 18:09:45 2014 +0000
+# Node ID cbdd11a54b82eb7731d16abbc6df3c9b4d42c78b
+# Parent  3f0dff7a9cf590ef3e5d7f2dcf6c8247b65c9d10
+8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
+Summary: Detect mmap() commit failures in Linux and Solaris os::commit_memory() impls and call vm_exit_out_of_memory(). Add os::commit_memory_or_exit(). Also tidy up some NMT accounting and some mmap() return value checking.
+Reviewed-by: zgu, stefank, dholmes, dsamersoff
+
+diff -r 3f0dff7a9cf5 -r cbdd11a54b82 src/os/bsd/vm/os_bsd.cpp
+--- openjdk/hotspot/src/os/bsd/vm/os_bsd.cpp	Mon Mar 12 13:12:07 2012 -0700
++++ openjdk/hotspot/src/os/bsd/vm/os_bsd.cpp	Mon Mar 10 18:09:45 2014 +0000
+@@ -2762,6 +2762,13 @@
+   }
+ }
+ 
++static void warn_fail_commit_memory(char* addr, size_t size, bool exec,
++                                    int err) {
++  warning("INFO: os::commit_memory(" PTR_FORMAT ", " SIZE_FORMAT
++          ", %d) failed; error='%s' (errno=%d)", addr, size, exec,
++          strerror(err), err);
++}
++
+ // NOTE: Bsd kernel does not really reserve the pages for us.
+ //       All it does is to check if there are enough free pages
+ //       left at the time of mmap(). This could be a potential
+@@ -2770,12 +2777,22 @@
+   int prot = exec ? PROT_READ|PROT_WRITE|PROT_EXEC : PROT_READ|PROT_WRITE;
+ #ifdef __OpenBSD__
+   // XXX: Work-around mmap/MAP_FIXED bug temporarily on OpenBSD
+-  return ::mprotect(addr, size, prot) == 0;
++  if (::mprotect(addr, size, prot) == 0) {
++    return true;
++  }
+ #else
+   uintptr_t res = (uintptr_t) ::mmap(addr, size, prot,
+                                    MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0);
+-  return res != (uintptr_t) MAP_FAILED;
++  if (res != (uintptr_t) MAP_FAILED) {
++    return true;
++  }
+ #endif
++
++  // Warn about any commit errors we see in non-product builds just
++  // in case mmap() doesn't work as described on the man page.
++  NOT_PRODUCT(warn_fail_commit_memory(addr, size, exec, errno);)
++
++  return false;
+ }
+ 
+ #ifndef _ALLBSD_SOURCE
+@@ -2803,9 +2820,27 @@
+   }
+ #endif
+ 
++  // alignment_hint is ignored on this OS
+   return commit_memory(addr, size, exec);
+ }
+ 
++void os::commit_memory_or_exit(char* addr, size_t size, bool exec,
++			       const char* mesg) {
++  assert(mesg != NULL, "mesg must be specified");
++  if (!pd_commit_memory(addr, size, exec)) {
++    // add extra info in product mode for vm_exit_out_of_memory():
++    PRODUCT_ONLY(warn_fail_commit_memory(addr, size, exec, errno);)
++    vm_exit_out_of_memory(size, mesg);
++  }
++}
++
++void os::commit_memory_or_exit(char* addr, size_t size,
++			       size_t alignment_hint, bool exec,
++			       const char* mesg) {
++  // alignment_hint is ignored on this OS
++  pd_commit_memory_or_exit(addr, size, exec, mesg);
++}
++
+ void os::realign_memory(char *addr, size_t bytes, size_t alignment_hint) {
+ #ifndef _ALLBSD_SOURCE
+   if (UseHugeTLBFS && alignment_hint > (size_t)vm_page_size()) {
+@@ -2970,7 +3005,7 @@
+ }
+ 
+ bool os::create_stack_guard_pages(char* addr, size_t size) {
+-  return os::commit_memory(addr, size);
++  return os::commit_memory(addr, size, !ExecMem);
+ }
+ 
+ // If this is a growable mapping, remove the guard pages entirely by
+@@ -4467,7 +4502,7 @@
+ 
+   if (!UseMembar) {
+     address mem_serialize_page = (address) ::mmap(NULL, Bsd::page_size(), PROT_READ | PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
+-    guarantee( mem_serialize_page != NULL, "mmap Failed for memory serialize page");
++    guarantee( mem_serialize_page != MAP_FAILED, "mmap Failed for memory serialize page");
+     os::set_memory_serialize_page( mem_serialize_page );
+ 
+ #ifndef PRODUCT
+diff -r 3f0dff7a9cf5 -r cbdd11a54b82 src/os/bsd/vm/perfMemory_bsd.cpp
+--- openjdk/hotspot/src/os/bsd/vm/perfMemory_bsd.cpp	Mon Mar 12 13:12:07 2012 -0700
++++ openjdk/hotspot/src/os/bsd/vm/perfMemory_bsd.cpp	Mon Mar 10 18:09:45 2014 +0000
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+  *
+  * This code is free software; you can redistribute it and/or modify it
+@@ -59,7 +59,7 @@
+   }
+ 
+   // commit memory
+-  if (!os::commit_memory(mapAddress, size)) {
++  if (!os::commit_memory(mapAddress, size, !ExecMem)) {
+     if (PrintMiscellaneous && Verbose) {
+       warning("Could not commit PerfData memory\n");
+     }
+diff -r 3f0dff7a9cf5 -r cbdd11a54b82 src/os/linux/vm/os_linux.cpp
+--- openjdk/hotspot/src/os/linux/vm/os_linux.cpp	Mon Mar 12 13:12:07 2012 -0700
++++ openjdk/hotspot/src/os/linux/vm/os_linux.cpp	Mon Mar 10 18:09:45 2014 +0000
+@@ -2508,11 +2508,49 @@
+   }
+ }
+ 
++static bool recoverable_mmap_error(int err) {
++  // See if the error is one we can let the caller handle. This
++  // list of errno values comes from JBS-6843484. I can't find a
++  // Linux man page that documents this specific set of errno
++  // values so while this list currently matches Solaris, it may
++  // change as we gain experience with this failure mode.
++  switch (err) {
++  case EBADF:
++  case EINVAL:
++  case ENOTSUP:
++    // let the caller deal with these errors
++    return true;
++
++  default:
++    // Any remaining errors on this OS can cause our reserved mapping
++    // to be lost. That can cause confusion where different data
++    // structures think they have the same memory mapped. The worst
++    // scenario is if both the VM and a library think they have the
++    // same memory mapped.
++    return false;
++  }
++}
++
++static void warn_fail_commit_memory(char* addr, size_t size, bool exec,
++                                    int err) {
++  warning("INFO: os::commit_memory(" PTR_FORMAT ", " SIZE_FORMAT
++          ", %d) failed; error='%s' (errno=%d)", addr, size, exec,
++          strerror(err), err);
++}
++
++static void warn_fail_commit_memory(char* addr, size_t size,
++                                    size_t alignment_hint, bool exec,
++                                    int err) {
++  warning("INFO: os::commit_memory(" PTR_FORMAT ", " SIZE_FORMAT
++          ", " SIZE_FORMAT ", %d) failed; error='%s' (errno=%d)", addr, size,
++          alignment_hint, exec, strerror(err), err);
++}
++
+ // NOTE: Linux kernel does not really reserve the pages for us.
+ //       All it does is to check if there are enough free pages
+ //       left at the time of mmap(). This could be a potential
+ //       problem.
+-bool os::commit_memory(char* addr, size_t size, bool exec) {
++int os::Linux::commit_memory_impl(char* addr, size_t size, bool exec) {
+   int prot = exec ? PROT_READ|PROT_WRITE|PROT_EXEC : PROT_READ|PROT_WRITE;
+   uintptr_t res = (uintptr_t) ::mmap(addr, size, prot,
+                                    MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0);
+@@ -2520,9 +2558,32 @@
+     if (UseNUMAInterleaving) {
+       numa_make_global(addr, size);
+     }
+-    return true;
+-  }
+-  return false;
++    return 0;
++  }
++
++  int err = errno;  // save errno from mmap() call above
++
++  if (!recoverable_mmap_error(err)) {
++    warn_fail_commit_memory(addr, size, exec, err);
++    vm_exit_out_of_memory(size, "committing reserved memory.");
++  }
++
++  return err;
++}
++
++bool os::commit_memory(char* addr, size_t size, bool exec) {
++  return os::Linux::commit_memory_impl(addr, size, exec) == 0;
++}
++
++void os::commit_memory_or_exit(char* addr, size_t size, bool exec,
++                                  const char* mesg) {
++  assert(mesg != NULL, "mesg must be specified");
++  int err = os::Linux::commit_memory_impl(addr, size, exec);
++  if (err != 0) {
++    // the caller wants all commit errors to exit with the specified mesg:
++    warn_fail_commit_memory(addr, size, exec, err);
++    vm_exit_out_of_memory(size, mesg);
++  }
+ }
+ 
+ // Define MAP_HUGETLB here so we can build HotSpot on old systems.
+@@ -2535,8 +2596,9 @@
+ #define MADV_HUGEPAGE 14
+ #endif
+ 
+-bool os::commit_memory(char* addr, size_t size, size_t alignment_hint,
+-                       bool exec) {
++int os::Linux::commit_memory_impl(char* addr, size_t size,
++                                  size_t alignment_hint, bool exec) {
++  int err;
+   if (UseHugeTLBFS && alignment_hint > (size_t)vm_page_size()) {
+     int prot = exec ? PROT_READ|PROT_WRITE|PROT_EXEC : PROT_READ|PROT_WRITE;
+     uintptr_t res =
+@@ -2547,16 +2609,45 @@
+       if (UseNUMAInterleaving) {
+         numa_make_global(addr, size);
+       }
+-      return true;
++      return 0;
++    }
++
++    err = errno;  // save errno from mmap() call above
++
++    if (!recoverable_mmap_error(err)) {
++      // However, it is not clear that this loss of our reserved mapping
++      // happens with large pages on Linux or that we cannot recover
++      // from the loss. For now, we just issue a warning and we don't
++      // call vm_exit_out_of_memory(). This issue is being tracked by
++      // JBS-8007074.
++      warn_fail_commit_memory(addr, size, alignment_hint, exec, err);
++//    vm_exit_out_of_memory(size, "committing reserved memory.");
+     }
+     // Fall through and try to use small pages
+   }
+ 
+-  if (commit_memory(addr, size, exec)) {
++  err = os::Linux::commit_memory_impl(addr, size, exec);
++  if (err == 0) {
+     realign_memory(addr, size, alignment_hint);
+-    return true;
+-  }
+-  return false;
++  }
++  return err;
++}
++
++bool os::commit_memory(char* addr, size_t size, size_t alignment_hint,
++                          bool exec) {
++  return os::Linux::commit_memory_impl(addr, size, alignment_hint, exec) == 0;
++}
++
++void os::commit_memory_or_exit(char* addr, size_t size,
++                                  size_t alignment_hint, bool exec,
++                                  const char* mesg) {
++  assert(mesg != NULL, "mesg must be specified");
++  int err = os::Linux::commit_memory_impl(addr, size, alignment_hint, exec);
++  if (err != 0) {
++    // the caller wants all commit errors to exit with the specified mesg:
++    warn_fail_commit_memory(addr, size, alignment_hint, exec, err);
++    vm_exit_out_of_memory(size, mesg);
++  }
+ }
+ 
+ void os::realign_memory(char *addr, size_t bytes, size_t alignment_hint) {
+@@ -2574,7 +2665,7 @@
+   // small pages on top of the SHM segment. This method always works for small pages, so we
+   // allow that in any case.
+   if (alignment_hint <= (size_t)os::vm_page_size() || !UseSHM) {
+-    commit_memory(addr, bytes, alignment_hint, false);
++    commit_memory(addr, bytes, alignment_hint, !ExecMem);
+   }
+ }
+ 
+@@ -2827,7 +2918,7 @@
+       ::munmap((void*)stack_extent, (uintptr_t)addr - stack_extent);
+   }
+ 
+-  return os::commit_memory(addr, size);
++  return os::commit_memory(addr, size, !ExecMem);
+ }
+ 
+ // If this is a growable mapping, remove the guard pages entirely by
+@@ -2948,7 +3039,7 @@
+                   MAP_ANONYMOUS|MAP_PRIVATE|MAP_HUGETLB,
+                   -1, 0);
+ 
+-  if (p != (void *) -1) {
++  if (p != MAP_FAILED) {
+     // We don't know if this really is a huge page or not.
+     FILE *fp = fopen("/proc/self/maps", "r");
+     if (fp) {
+@@ -4225,7 +4316,7 @@
+ 
+   if (!UseMembar) {
+     address mem_serialize_page = (address) ::mmap(NULL, Linux::page_size(), PROT_READ | PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
+-    guarantee( mem_serialize_page != NULL, "mmap Failed for memory serialize page");
++    guarantee( mem_serialize_page != MAP_FAILED, "mmap Failed for memory serialize page");
+     os::set_memory_serialize_page( mem_serialize_page );
+ 
+ #ifndef PRODUCT
+diff -r 3f0dff7a9cf5 -r cbdd11a54b82 src/os/linux/vm/os_linux.hpp
+--- openjdk/hotspot/src/os/linux/vm/os_linux.hpp	Mon Mar 12 13:12:07 2012 -0700
++++ openjdk/hotspot/src/os/linux/vm/os_linux.hpp	Mon Mar 10 18:09:45 2014 +0000
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+  *
+  * This code is free software; you can redistribute it and/or modify it
+@@ -75,6 +75,10 @@
+   static julong physical_memory() { return _physical_memory; }
+   static void initialize_system_info();
+ 
++  static int commit_memory_impl(char* addr, size_t bytes, bool exec);
++  static int commit_memory_impl(char* addr, size_t bytes,
++                                size_t alignment_hint, bool exec);
++
+   static void set_glibc_version(const char *s)      { _glibc_version = s; }
+   static void set_libpthread_version(const char *s) { _libpthread_version = s; }
+ 
+diff -r 3f0dff7a9cf5 -r cbdd11a54b82 src/os/linux/vm/perfMemory_linux.cpp
+--- openjdk/hotspot/src/os/linux/vm/perfMemory_linux.cpp	Mon Mar 12 13:12:07 2012 -0700
++++ openjdk/hotspot/src/os/linux/vm/perfMemory_linux.cpp	Mon Mar 10 18:09:45 2014 +0000
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+  *
+  * This code is free software; you can redistribute it and/or modify it
+@@ -59,7 +59,7 @@
+   }
+ 
+   // commit memory
+-  if (!os::commit_memory(mapAddress, size)) {
++  if (!os::commit_memory(mapAddress, size, !ExecMem)) {
+     if (PrintMiscellaneous && Verbose) {
+       warning("Could not commit PerfData memory\n");
+     }
+diff -r 3f0dff7a9cf5 -r cbdd11a54b82 src/os/solaris/vm/os_solaris.cpp
+--- openjdk/hotspot/src/os/solaris/vm/os_solaris.cpp	Mon Mar 12 13:12:07 2012 -0700
++++ openjdk/hotspot/src/os/solaris/vm/os_solaris.cpp	Mon Mar 10 18:09:45 2014 +0000
+@@ -2769,7 +2769,42 @@
+   return page_size;
+ }
+ 
+-bool os::commit_memory(char* addr, size_t bytes, bool exec) {
++static bool recoverable_mmap_error(int err) {
++  // See if the error is one we can let the caller handle. This
++  // list of errno values comes from the Solaris mmap(2) man page.
++  switch (err) {
++  case EBADF:
++  case EINVAL:
++  case ENOTSUP:
++    // let the caller deal with these errors
++    return true;
++
++  default:
++    // Any remaining errors on this OS can cause our reserved mapping
++    // to be lost. That can cause confusion where different data
++    // structures think they have the same memory mapped. The worst
++    // scenario is if both the VM and a library think they have the
++    // same memory mapped.
++    return false;
++  }
++}
++
++static void warn_fail_commit_memory(char* addr, size_t bytes, bool exec,
++                                    int err) {
++  warning("INFO: os::commit_memory(" PTR_FORMAT ", " SIZE_FORMAT
++          ", %d) failed; error='%s' (errno=%d)", addr, bytes, exec,
++          strerror(err), err);
++}
++
++static void warn_fail_commit_memory(char* addr, size_t bytes,
++                                    size_t alignment_hint, bool exec,
++                                    int err) {
++  warning("INFO: os::commit_memory(" PTR_FORMAT ", " SIZE_FORMAT
++          ", " SIZE_FORMAT ", %d) failed; error='%s' (errno=%d)", addr, bytes,
++          alignment_hint, exec, strerror(err), err);
++}
++
++int os::Solaris::commit_memory_impl(char* addr, size_t bytes, bool exec) {
+   int prot = exec ? PROT_READ|PROT_WRITE|PROT_EXEC : PROT_READ|PROT_WRITE;
+   size_t size = bytes;
+   char *res = Solaris::mmap_chunk(addr, size, MAP_PRIVATE|MAP_FIXED, prot);
+@@ -2777,14 +2812,38 @@
+     if (UseNUMAInterleaving) {
+       numa_make_global(addr, bytes);
+     }
+-    return true;
+-  }
+-  return false;
+-}
+-
+-bool os::commit_memory(char* addr, size_t bytes, size_t alignment_hint,
+-                       bool exec) {
+-  if (commit_memory(addr, bytes, exec)) {
++    return 0;
++  }
++
++  int err = errno;  // save errno from mmap() call in mmap_chunk()
++
++  if (!recoverable_mmap_error(err)) {
++    warn_fail_commit_memory(addr, bytes, exec, err);
++    vm_exit_out_of_memory(bytes, "committing reserved memory.");
++  }
++
++  return err;
++}
++
++bool os::commit_memory(char* addr, size_t bytes, bool exec) {
++  return Solaris::commit_memory_impl(addr, bytes, exec) == 0;
++}
++
++void os::commit_memory_or_exit(char* addr, size_t bytes, bool exec,
++                                  const char* mesg) {
++  assert(mesg != NULL, "mesg must be specified");
++  int err = os::Solaris::commit_memory_impl(addr, bytes, exec);
++  if (err != 0) {
++    // the caller wants all commit errors to exit with the specified mesg:
++    warn_fail_commit_memory(addr, bytes, exec, err);
++    vm_exit_out_of_memory(bytes, mesg);
++  }
++}
++
++int os::Solaris::commit_memory_impl(char* addr, size_t bytes,
++                                    size_t alignment_hint, bool exec) {
++  int err = Solaris::commit_memory_impl(addr, bytes, exec);
++  if (err == 0) {
+     if (UseMPSS && alignment_hint > (size_t)vm_page_size()) {
+       // If the large page size has been set and the VM
+       // is using large pages, use the large page size
+@@ -2806,9 +2865,25 @@
+       // Since this is a hint, ignore any failures.
+       (void)Solaris::set_mpss_range(addr, bytes, page_size);
+     }
+-    return true;
+-  }
+-  return false;
++  }
++  return err;
++}
++
++bool os::commit_memory(char* addr, size_t bytes, size_t alignment_hint,
++                          bool exec) {
++  return Solaris::commit_memory_impl(addr, bytes, alignment_hint, exec) == 0;
++}
++
++void os::commit_memory_or_exit(char* addr, size_t bytes,
++                                  size_t alignment_hint, bool exec,
++                                  const char* mesg) {
++  assert(mesg != NULL, "mesg must be specified");
++  int err = os::Solaris::commit_memory_impl(addr, bytes, alignment_hint, exec);
++  if (err != 0) {
++    // the caller wants all commit errors to exit with the specified mesg:
++    warn_fail_commit_memory(addr, bytes, alignment_hint, exec, err);
++    vm_exit_out_of_memory(bytes, mesg);
++  }
+ }
+ 
+ // Uncommit the pages in a specified region.
+@@ -2820,7 +2895,7 @@
+ }
+ 
+ bool os::create_stack_guard_pages(char* addr, size_t size) {
+-  return os::commit_memory(addr, size);
++  return os::commit_memory(addr, size, !ExecMem);
+ }
+ 
+ bool os::remove_stack_guard_pages(char* addr, size_t size) {
+diff -r 3f0dff7a9cf5 -r cbdd11a54b82 src/os/solaris/vm/os_solaris.hpp
+--- openjdk/hotspot/src/os/solaris/vm/os_solaris.hpp	Mon Mar 12 13:12:07 2012 -0700
++++ openjdk/hotspot/src/os/solaris/vm/os_solaris.hpp	Mon Mar 10 18:09:45 2014 +0000
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+  *
+  * This code is free software; you can redistribute it and/or modify it
+@@ -166,6 +166,9 @@
+   static int _dev_zero_fd;
+   static int get_dev_zero_fd() { return _dev_zero_fd; }
+   static void set_dev_zero_fd(int fd) { _dev_zero_fd = fd; }
++  static int commit_memory_impl(char* addr, size_t bytes, bool exec);
++  static int commit_memory_impl(char* addr, size_t bytes,
++                                size_t alignment_hint, bool exec);
+   static char* mmap_chunk(char *addr, size_t size, int flags, int prot);
+   static char* anon_mmap(char* requested_addr, size_t bytes, size_t alignment_hint, bool fixed);
+   static bool mpss_sanity_check(bool warn, size_t * page_size);
+diff -r 3f0dff7a9cf5 -r cbdd11a54b82 src/os/solaris/vm/perfMemory_solaris.cpp
+--- openjdk/hotspot/src/os/solaris/vm/perfMemory_solaris.cpp	Mon Mar 12 13:12:07 2012 -0700
++++ openjdk/hotspot/src/os/solaris/vm/perfMemory_solaris.cpp	Mon Mar 10 18:09:45 2014 +0000
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+  *
+  * This code is free software; you can redistribute it and/or modify it
+@@ -61,7 +61,7 @@
+   }
+ 
+   // commit memory
+-  if (!os::commit_memory(mapAddress, size)) {
++  if (!os::commit_memory(mapAddress, size, !ExecMem)) {
+     if (PrintMiscellaneous && Verbose) {
+       warning("Could not commit PerfData memory\n");
+     }
+diff -r 3f0dff7a9cf5 -r cbdd11a54b82 src/os/windows/vm/os_windows.cpp
+--- openjdk/hotspot/src/os/windows/vm/os_windows.cpp	Mon Mar 12 13:12:07 2012 -0700
++++ openjdk/hotspot/src/os/windows/vm/os_windows.cpp	Mon Mar 10 18:09:45 2014 +0000
+@@ -2410,7 +2410,7 @@
+                   addr = (address)((uintptr_t)addr &
+                          (~((uintptr_t)os::vm_page_size() - (uintptr_t)1)));
+                   os::commit_memory((char *)addr, thread->stack_base() - addr,
+-                                    false );
++                                    !ExecMem);
+                   return EXCEPTION_CONTINUE_EXECUTION;
+           }
+           else
+@@ -3067,6 +3067,15 @@
+ void os::print_statistics() {
+ }
+ 
++static void warn_fail_commit_memory(char* addr, size_t bytes, bool exec) {
++  int err = os::get_last_error();
++  char buf[256];
++  size_t buf_len = os::lasterror(buf, sizeof(buf));
++  warning("INFO: os::commit_memory(" PTR_FORMAT ", " SIZE_FORMAT
++          ", %d) failed; error='%s' (DOS error/errno=%d)", addr, bytes,
++          exec, buf_len != 0 ? buf : "<no_error_string>", err);
++}
++
+ bool os::commit_memory(char* addr, size_t bytes, bool exec) {
+   if (bytes == 0) {
+     // Don't bother the OS with noops.
+@@ -3081,11 +3090,17 @@
+   // is always within a reserve covered by a single VirtualAlloc
+   // in that case we can just do a single commit for the requested size
+   if (!UseNUMAInterleaving) {
+-    if (VirtualAlloc(addr, bytes, MEM_COMMIT, PAGE_READWRITE) == NULL) return false;
++    if (VirtualAlloc(addr, bytes, MEM_COMMIT, PAGE_READWRITE) == NULL) {
++      NOT_PRODUCT(warn_fail_commit_memory(addr, bytes, exec);)
++      return false;
++    }
+     if (exec) {
+       DWORD oldprot;
+       // Windows doc says to use VirtualProtect to get execute permissions
+-      if (!VirtualProtect(addr, bytes, PAGE_EXECUTE_READWRITE, &oldprot)) return false;
++      if (!VirtualProtect(addr, bytes, PAGE_EXECUTE_READWRITE, &oldprot)) {
++        NOT_PRODUCT(warn_fail_commit_memory(addr, bytes, exec);)
++        return false;
++      }
+     }
+     return true;
+   } else {
+@@ -3100,12 +3115,20 @@
+       MEMORY_BASIC_INFORMATION alloc_info;
+       VirtualQuery(next_alloc_addr, &alloc_info, sizeof(alloc_info));
+       size_t bytes_to_rq = MIN2(bytes_remaining, (size_t)alloc_info.RegionSize);
+-      if (VirtualAlloc(next_alloc_addr, bytes_to_rq, MEM_COMMIT, PAGE_READWRITE) == NULL)
++      if (VirtualAlloc(next_alloc_addr, bytes_to_rq, MEM_COMMIT,
++                       PAGE_READWRITE) == NULL) {
++        NOT_PRODUCT(warn_fail_commit_memory(next_alloc_addr, bytes_to_rq,
++                                            exec);)
+         return false;
++      }
+       if (exec) {
+         DWORD oldprot;
+-        if (!VirtualProtect(next_alloc_addr, bytes_to_rq, PAGE_EXECUTE_READWRITE, &oldprot))
++        if (!VirtualProtect(next_alloc_addr, bytes_to_rq,
++                            PAGE_EXECUTE_READWRITE, &oldprot)) {
++          NOT_PRODUCT(warn_fail_commit_memory(next_alloc_addr, bytes_to_rq,
++                                              exec);)
+           return false;
++        }
+       }
+       bytes_remaining -= bytes_to_rq;
+       next_alloc_addr += bytes_to_rq;
+@@ -3117,9 +3140,26 @@
+ 
+ bool os::commit_memory(char* addr, size_t size, size_t alignment_hint,
+                        bool exec) {
++  // alignment_hint is ignored on this OS
+   return commit_memory(addr, size, exec);
+ }
+ 
++void os::commit_memory_or_exit(char* addr, size_t size, bool exec,
++                                  const char* mesg) {
++  assert(mesg != NULL, "mesg must be specified");
++  if (!pd_commit_memory(addr, size, exec)) {
++    warn_fail_commit_memory(addr, size, exec);
++    vm_exit_out_of_memory(size, mesg);
++  }
++}
++
++void os::commit_memory_or_exit(char* addr, size_t size,
++                                  size_t alignment_hint, bool exec,
++                                  const char* mesg) {
++  // alignment_hint is ignored on this OS
++  pd_commit_memory_or_exit(addr, size, exec, mesg);
++}
++
+ bool os::uncommit_memory(char* addr, size_t bytes) {
+   if (bytes == 0) {
+     // Don't bother the OS with noops.
+@@ -3135,7 +3175,7 @@
+ }
+ 
+ bool os::create_stack_guard_pages(char* addr, size_t size) {
+-  return os::commit_memory(addr, size);
++  return os::commit_memory(addr, size, !ExecMem);
+ }
+ 
+ bool os::remove_stack_guard_pages(char* addr, size_t size) {
+@@ -3159,8 +3199,9 @@
+ 
+   // Strange enough, but on Win32 one can change protection only for committed
+   // memory, not a big deal anyway, as bytes less or equal than 64K
+-  if (!is_committed && !commit_memory(addr, bytes, prot == MEM_PROT_RWX)) {
+-    fatal("cannot commit protection page");
++  if (!is_committed) {
++    commit_memory_or_exit(addr, bytes, prot == MEM_PROT_RWX,
++                          "cannot commit protection page");
+   }
+   // One cannot use os::guard_memory() here, as on Win32 guard page
+   // have different (one-shot) semantics, from MSDN on PAGE_GUARD:
+diff -r 3f0dff7a9cf5 -r cbdd11a54b82 src/os/windows/vm/perfMemory_windows.cpp
+--- openjdk/hotspot/src/os/windows/vm/perfMemory_windows.cpp	Mon Mar 12 13:12:07 2012 -0700
++++ openjdk/hotspot/src/os/windows/vm/perfMemory_windows.cpp	Mon Mar 10 18:09:45 2014 +0000
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+  *
+  * This code is free software; you can redistribute it and/or modify it
+@@ -57,7 +57,7 @@
+   }
+ 
+   // commit memory
+-  if (!os::commit_memory(mapAddress, size)) {
++  if (!os::commit_memory(mapAddress, size, !ExecMem)) {
+     if (PrintMiscellaneous && Verbose) {
+       warning("Could not commit PerfData memory\n");
+     }
+diff -r 3f0dff7a9cf5 -r cbdd11a54b82 src/share/vm/gc_implementation/parallelScavenge/cardTableExtension.cpp
+--- openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/cardTableExtension.cpp	Mon Mar 12 13:12:07 2012 -0700
++++ openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/cardTableExtension.cpp	Mon Mar 10 18:09:45 2014 +0000
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+  *
+  * This code is free software; you can redistribute it and/or modify it
+@@ -649,11 +649,9 @@
+     if(new_start_aligned < new_end_for_commit) {
+       MemRegion new_committed =
+         MemRegion(new_start_aligned, new_end_for_commit);
+-      if (!os::commit_memory((char*)new_committed.start(),
+-                             new_committed.byte_size())) {
+-        vm_exit_out_of_memory(new_committed.byte_size(),
+-                              "card table expansion");
+-      }
++      os::commit_memory_or_exit((char*)new_committed.start(),
++                                new_committed.byte_size(), !ExecMem,
++                                "card table expansion");
+     }
+     result = true;
+   } else if (new_start_aligned > cur_committed.start()) {
+diff -r 3f0dff7a9cf5 -r cbdd11a54b82 src/share/vm/gc_implementation/parallelScavenge/psVirtualspace.cpp
+--- openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/psVirtualspace.cpp	Mon Mar 12 13:12:07 2012 -0700
++++ openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/psVirtualspace.cpp	Mon Mar 10 18:09:45 2014 +0000
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+  *
+  * This code is free software; you can redistribute it and/or modify it
+@@ -101,7 +101,8 @@
+   }
+ 
+   char* const base_addr = committed_high_addr();
+-  bool result = special() || os::commit_memory(base_addr, bytes, alignment());
++  bool result = special() ||
++         os::commit_memory(base_addr, bytes, alignment(), !ExecMem);
+   if (result) {
+     _committed_high_addr += bytes;
+   }
+@@ -154,7 +155,7 @@
+   if (tmp_bytes > 0) {
+     char* const commit_base = committed_high_addr();
+     if (other_space->special() ||
+-        os::commit_memory(commit_base, tmp_bytes, alignment())) {
++        os::commit_memory(commit_base, tmp_bytes, alignment(), !ExecMem)) {
+       // Reduce the reserved region in the other space.
+       other_space->set_reserved(other_space->reserved_low_addr() + tmp_bytes,
+                                 other_space->reserved_high_addr(),
+@@ -269,7 +270,8 @@
+   }
+ 
+   char* const base_addr = committed_low_addr() - bytes;
+-  bool result = special() || os::commit_memory(base_addr, bytes, alignment());
++  bool result = special() ||
++         os::commit_memory(base_addr, bytes, alignment(), !ExecMem);
+   if (result) {
+     _committed_low_addr -= bytes;
+   }
+@@ -322,7 +324,7 @@
+   if (tmp_bytes > 0) {
+     char* const commit_base = committed_low_addr() - tmp_bytes;
+     if (other_space->special() ||
+-        os::commit_memory(commit_base, tmp_bytes, alignment())) {
++        os::commit_memory(commit_base, tmp_bytes, alignment(), !ExecMem)) {
+       // Reduce the reserved region in the other space.
+       other_space->set_reserved(other_space->reserved_low_addr(),
+                                 other_space->reserved_high_addr() - tmp_bytes,
+diff -r 3f0dff7a9cf5 -r cbdd11a54b82 src/share/vm/memory/cardTableModRefBS.cpp
+--- openjdk/hotspot/src/share/vm/memory/cardTableModRefBS.cpp	Mon Mar 12 13:12:07 2012 -0700
++++ openjdk/hotspot/src/share/vm/memory/cardTableModRefBS.cpp	Mon Mar 10 18:09:45 2014 +0000
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+  *
+  * This code is free software; you can redistribute it and/or modify it
+@@ -109,10 +109,8 @@
+   jbyte* guard_card = &_byte_map[_guard_index];
+   uintptr_t guard_page = align_size_down((uintptr_t)guard_card, _page_size);
+   _guard_region = MemRegion((HeapWord*)guard_page, _page_size);
+-  if (!os::commit_memory((char*)guard_page, _page_size, _page_size)) {
+-    // Do better than this for Merlin
+-    vm_exit_out_of_memory(_page_size, "card table last card");
+-  }
++  os::commit_memory_or_exit((char*)guard_page, _page_size, _page_size,
++                            !ExecMem, "card table last card");
+   *guard_card = last_card;
+ 
+    _lowest_non_clean =
+@@ -283,12 +281,9 @@
+         MemRegion(cur_committed.end(), new_end_for_commit);
+ 
+       assert(!new_committed.is_empty(), "Region should not be empty here");
+-      if (!os::commit_memory((char*)new_committed.start(),
+-                             new_committed.byte_size(), _page_size)) {
+-        // Do better than this for Merlin
+-        vm_exit_out_of_memory(new_committed.byte_size(),
+-                "card table expansion");
+-      }
++      os::commit_memory_or_exit((char*)new_committed.start(),
++                                new_committed.byte_size(), _page_size,
++                                !ExecMem, "card table expansion");
+     // Use new_end_aligned (as opposed to new_end_for_commit) because
+     // the cur_committed region may include the guard region.
+     } else if (new_end_aligned < cur_committed.end()) {
+diff -r 3f0dff7a9cf5 -r cbdd11a54b82 src/share/vm/runtime/os.cpp
+--- openjdk/hotspot/src/share/vm/runtime/os.cpp	Mon Mar 12 13:12:07 2012 -0700
++++ openjdk/hotspot/src/share/vm/runtime/os.cpp	Mon Mar 10 18:09:45 2014 +0000
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+  *
+  * This code is free software; you can redistribute it and/or modify it
+diff -r 3f0dff7a9cf5 -r cbdd11a54b82 src/share/vm/runtime/os.hpp
+--- openjdk/hotspot/src/share/vm/runtime/os.hpp	Mon Mar 12 13:12:07 2012 -0700
++++ openjdk/hotspot/src/share/vm/runtime/os.hpp	Mon Mar 10 18:09:45 2014 +0000
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+  *
+  * This code is free software; you can redistribute it and/or modify it
+@@ -78,6 +78,10 @@
+   CriticalPriority = 11      // Critical thread priority
+ };
+ 
++// Executable parameter flag for os::commit_memory() and
++// os::commit_memory_or_exit().
++const bool ExecMem = true;
++
+ // Typedef for structured exception handling support
+ typedef void (*java_call_t)(JavaValue* value, methodHandle* method, JavaCallArguments* args, Thread* thread);
+ 
+@@ -237,10 +241,16 @@
+   static char*  attempt_reserve_memory_at(size_t bytes, char* addr);
+   static void   split_reserved_memory(char *base, size_t size,
+                                       size_t split, bool realloc);
+-  static bool   commit_memory(char* addr, size_t bytes,
+-                              bool executable = false);
++  static bool   commit_memory(char* addr, size_t bytes, bool executable);
+   static bool   commit_memory(char* addr, size_t size, size_t alignment_hint,
+-                              bool executable = false);
++                                 bool executable);
++  // Same as commit_memory() that either succeeds or calls
++  // vm_exit_out_of_memory() with the specified mesg.
++  static void   commit_memory_or_exit(char* addr, size_t bytes,
++				      bool executable, const char* mesg);
++  static void   commit_memory_or_exit(char* addr, size_t size,
++				      size_t alignment_hint,
++				      bool executable, const char* mesg);
+   static bool   uncommit_memory(char* addr, size_t bytes);
+   static bool   release_memory(char* addr, size_t bytes);
+ 
+diff -r 3f0dff7a9cf5 -r cbdd11a54b82 src/share/vm/runtime/virtualspace.cpp
+--- openjdk/hotspot/src/share/vm/runtime/virtualspace.cpp	Mon Mar 12 13:12:07 2012 -0700
++++ openjdk/hotspot/src/share/vm/runtime/virtualspace.cpp	Mon Mar 10 18:09:45 2014 +0000
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+  *
+  * This code is free software; you can redistribute it and/or modify it
+@@ -704,11 +704,13 @@
+            lower_high() + lower_needs <= lower_high_boundary(),
+            "must not expand beyond region");
+     if (!os::commit_memory(lower_high(), lower_needs, _executable)) {
+-      debug_only(warning("os::commit_memory failed"));
++      debug_only(warning("INFO: os::commit_memory(" PTR_FORMAT
++                         ", lower_needs=" SIZE_FORMAT ", %d) failed",
++                         lower_high(), lower_needs, _executable);)
+       return false;
+     } else {
+       _lower_high += lower_needs;
+-     }
++    }
+   }
+   if (middle_needs > 0) {
+     assert(lower_high_boundary() <= middle_high() &&
+@@ -716,7 +718,10 @@
+            "must not expand beyond region");
+     if (!os::commit_memory(middle_high(), middle_needs, middle_alignment(),
+                            _executable)) {
+-      debug_only(warning("os::commit_memory failed"));
++      debug_only(warning("INFO: os::commit_memory(" PTR_FORMAT
++                         ", middle_needs=" SIZE_FORMAT ", " SIZE_FORMAT
++                         ", %d) failed", middle_high(), middle_needs,
++                         middle_alignment(), _executable);)
+       return false;
+     }
+     _middle_high += middle_needs;
+@@ -726,7 +731,9 @@
+            upper_high() + upper_needs <= upper_high_boundary(),
+            "must not expand beyond region");
+     if (!os::commit_memory(upper_high(), upper_needs, _executable)) {
+-      debug_only(warning("os::commit_memory failed"));
++      debug_only(warning("INFO: os::commit_memory(" PTR_FORMAT
++                         ", upper_needs=" SIZE_FORMAT ", %d) failed",
++                         upper_high(), upper_needs, _executable);)
+       return false;
+     } else {
+       _upper_high += upper_needs;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/patches/openjdk/8026887-make_large_page_allocations_easier_to_debug.patch	Tue Mar 18 12:32:37 2014 +0000
@@ -0,0 +1,81 @@
+# HG changeset patch
+# User aeriksso
+# Date 1394477299 0
+#      Mon Mar 10 18:48:19 2014 +0000
+# Node ID 24391b7e49b5230d2239a2e48f1f07c08c4fe270
+# Parent  cbdd11a54b82eb7731d16abbc6df3c9b4d42c78b
+8026887: Make issues due to failed large pages allocations easier to debug
+Reviewed-by: stefank, mcastegr, poonam
+
+diff -r cbdd11a54b82 -r 24391b7e49b5 src/os/linux/vm/os_linux.cpp
+--- openjdk/hotspot/src/os/linux/vm/os_linux.cpp	Mon Mar 10 18:09:45 2014 +0000
++++ openjdk/hotspot/src/os/linux/vm/os_linux.cpp	Mon Mar 10 18:48:19 2014 +0000
+@@ -2546,6 +2546,14 @@
+           alignment_hint, exec, strerror(err), err);
+ }
+ 
++static void warn_fail_commit_memory(char* addr, size_t size,
++                                    size_t alignment_hint, bool exec,
++                                    int err, const char* msg) {
++  warning("INFO: os::commit_memory(" PTR_FORMAT ", " SIZE_FORMAT
++          ", " SIZE_FORMAT ", %d) failed; error='%s' (errno=%d); %s", addr, size,
++          alignment_hint, exec, strerror(err), err, msg);
++}
++
+ // NOTE: Linux kernel does not really reserve the pages for us.
+ //       All it does is to check if there are enough free pages
+ //       left at the time of mmap(). This could be a potential
+@@ -2596,6 +2604,8 @@
+ #define MADV_HUGEPAGE 14
+ #endif
+ 
++volatile jint os::Linux::num_largepage_commit_fails = 0;
++
+ int os::Linux::commit_memory_impl(char* addr, size_t size,
+                                   size_t alignment_hint, bool exec) {
+   int err;
+@@ -2620,7 +2630,9 @@
+       // from the loss. For now, we just issue a warning and we don't
+       // call vm_exit_out_of_memory(). This issue is being tracked by
+       // JBS-8007074.
+-      warn_fail_commit_memory(addr, size, alignment_hint, exec, err);
++      Atomic::inc(&os::Linux::num_largepage_commit_fails);
++      warn_fail_commit_memory(addr, size, alignment_hint, exec, err,
++        "Cannot allocate large pages, falling back to regular pages");
+ //    vm_exit_out_of_memory(size, "committing reserved memory.");
+     }
+     // Fall through and try to use small pages
+diff -r cbdd11a54b82 -r 24391b7e49b5 src/os/linux/vm/os_linux.hpp
+--- openjdk/hotspot/src/os/linux/vm/os_linux.hpp	Mon Mar 10 18:09:45 2014 +0000
++++ openjdk/hotspot/src/os/linux/vm/os_linux.hpp	Mon Mar 10 18:48:19 2014 +0000
+@@ -98,6 +98,8 @@
+   static void print_libversion_info(outputStream* st);
+ 
+  public:
++  static volatile jint num_largepage_commit_fails;
++
+   static void init_thread_fpu_state();
+   static int  get_fpu_control_word();
+   static void set_fpu_control_word(int fpu_control);
+diff -r cbdd11a54b82 -r 24391b7e49b5 src/share/vm/utilities/vmError.cpp
+--- openjdk/hotspot/src/share/vm/utilities/vmError.cpp	Mon Mar 10 18:09:45 2014 +0000
++++ openjdk/hotspot/src/share/vm/utilities/vmError.cpp	Mon Mar 10 18:48:19 2014 +0000
+@@ -713,6 +713,18 @@
+        st->cr();
+      }
+ 
++#ifdef LINUX
++  STEP(193, "(printing large pages allocation errors)")
++
++     if (_verbose) {
++       jint largepage_failures = os::Linux::num_largepage_commit_fails;
++       if (largepage_failures > 0) {
++         st->print_cr("Large page allocation failures have occurred " INT32_FORMAT " times", largepage_failures);
++         st->cr();
++       }
++     }
++#endif
++
+   STEP(195, "(printing code cache information)" )
+ 
+      if (_verbose && Universe::is_fully_initialized()) {