changeset 4560:730eb43a23d8

Merge
author zgu
date Thu, 13 Jun 2013 04:13:42 -0700
parents 2d9b536bb027 520dc34d4114
children b43a5b3a4249
files src/os/bsd/vm/os_bsd.cpp src/os/bsd/vm/perfMemory_bsd.cpp src/os/linux/vm/os_linux.cpp src/os/linux/vm/perfMemory_linux.cpp src/os/solaris/vm/os_solaris.cpp src/os/solaris/vm/perfMemory_solaris.cpp src/os/windows/vm/os_windows.cpp src/os/windows/vm/perfMemory_windows.cpp src/share/vm/memory/klassInfoClosure.hpp src/share/vm/runtime/os.cpp
diffstat 28 files changed, 619 insertions(+), 203 deletions(-) [+]
line wrap: on
line diff
--- a/src/cpu/sparc/vm/assembler_sparc.cpp	Wed Jun 12 20:35:29 2013 -0400
+++ b/src/cpu/sparc/vm/assembler_sparc.cpp	Thu Jun 13 04:13:42 2013 -0700
@@ -3958,7 +3958,8 @@
 
   if (CMSIncrementalMode || !Universe::heap()->supports_inline_contig_alloc()) {
     // No allocation in the shared eden.
-    ba_short(slow_case);
+    ba(slow_case);
+    delayed()->nop();
   } else {
     // get eden boundaries
     // note: we need both top & top_addr!
--- a/src/os/bsd/vm/os_bsd.cpp	Wed Jun 12 20:35:29 2013 -0400
+++ b/src/os/bsd/vm/os_bsd.cpp	Thu Jun 13 04:13:42 2013 -0700
@@ -2889,6 +2889,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
@@ -2897,12 +2904,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
@@ -2930,7 +2947,25 @@
   }
 #endif
 
-  return commit_memory(addr, size, exec);
+  // alignment_hint is ignored on this OS
+  return pd_commit_memory(addr, size, exec);
+}
+
+void os::pd_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::pd_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::pd_realign_memory(char *addr, size_t bytes, size_t alignment_hint) {
@@ -3097,7 +3132,7 @@
 }
 
 bool os::pd_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
@@ -4665,7 +4700,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
--- a/src/os/bsd/vm/perfMemory_bsd.cpp	Wed Jun 12 20:35:29 2013 -0400
+++ b/src/os/bsd/vm/perfMemory_bsd.cpp	Thu Jun 13 04:13:42 2013 -0700
@@ -60,7 +60,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");
     }
--- a/src/os/linux/vm/os_linux.cpp	Wed Jun 12 20:35:29 2013 -0400
+++ b/src/os/linux/vm/os_linux.cpp	Thu Jun 13 04:13:42 2013 -0700
@@ -2640,11 +2640,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::pd_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);
@@ -2652,9 +2690,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::pd_commit_memory(char* addr, size_t size, bool exec) {
+  return os::Linux::commit_memory_impl(addr, size, exec) == 0;
+}
+
+void os::pd_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.
@@ -2667,8 +2728,9 @@
 #define MADV_HUGEPAGE 14
 #endif
 
-bool os::pd_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 =
@@ -2679,16 +2741,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::pd_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::pd_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::pd_realign_memory(char *addr, size_t bytes, size_t alignment_hint) {
@@ -2706,7 +2797,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);
   }
 }
 
@@ -2959,7 +3050,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
@@ -3080,7 +3171,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) {
@@ -4421,7 +4512,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
--- a/src/os/linux/vm/os_linux.hpp	Wed Jun 12 20:35:29 2013 -0400
+++ b/src/os/linux/vm/os_linux.hpp	Thu Jun 13 04:13:42 2013 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2012, 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
@@ -76,6 +76,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; }
 
--- a/src/os/linux/vm/perfMemory_linux.cpp	Wed Jun 12 20:35:29 2013 -0400
+++ b/src/os/linux/vm/perfMemory_linux.cpp	Thu Jun 13 04:13:42 2013 -0700
@@ -60,7 +60,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");
     }
--- a/src/os/solaris/vm/os_solaris.cpp	Wed Jun 12 20:35:29 2013 -0400
+++ b/src/os/solaris/vm/os_solaris.cpp	Thu Jun 13 04:13:42 2013 -0700
@@ -2808,7 +2808,42 @@
   return page_size;
 }
 
-bool os::pd_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);
@@ -2816,14 +2851,38 @@
     if (UseNUMAInterleaving) {
       numa_make_global(addr, bytes);
     }
-    return true;
-  }
-  return false;
-}
-
-bool os::pd_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::pd_commit_memory(char* addr, size_t bytes, bool exec) {
+  return Solaris::commit_memory_impl(addr, bytes, exec) == 0;
+}
+
+void os::pd_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
@@ -2845,9 +2904,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::pd_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::pd_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.
@@ -2859,7 +2934,7 @@
 }
 
 bool os::pd_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) {
--- a/src/os/solaris/vm/os_solaris.hpp	Wed Jun 12 20:35:29 2013 -0400
+++ b/src/os/solaris/vm/os_solaris.hpp	Thu Jun 13 04:13:42 2013 -0700
@@ -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
@@ -168,6 +168,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);
--- a/src/os/solaris/vm/perfMemory_solaris.cpp	Wed Jun 12 20:35:29 2013 -0400
+++ b/src/os/solaris/vm/perfMemory_solaris.cpp	Thu Jun 13 04:13:42 2013 -0700
@@ -62,7 +62,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");
     }
--- a/src/os/windows/vm/os_windows.cpp	Wed Jun 12 20:35:29 2013 -0400
+++ b/src/os/windows/vm/os_windows.cpp	Thu Jun 13 04:13:42 2013 -0700
@@ -2426,7 +2426,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
@@ -3108,6 +3108,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::pd_commit_memory(char* addr, size_t bytes, bool exec) {
   if (bytes == 0) {
     // Don't bother the OS with noops.
@@ -3122,11 +3131,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 {
@@ -3141,12 +3156,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;
@@ -3158,7 +3181,24 @@
 
 bool os::pd_commit_memory(char* addr, size_t size, size_t alignment_hint,
                        bool exec) {
-  return commit_memory(addr, size, exec);
+  // alignment_hint is ignored on this OS
+  return pd_commit_memory(addr, size, exec);
+}
+
+void os::pd_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::pd_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::pd_uncommit_memory(char* addr, size_t bytes) {
@@ -3176,7 +3216,7 @@
 }
 
 bool os::pd_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) {
@@ -3200,8 +3240,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:
--- a/src/os/windows/vm/perfMemory_windows.cpp	Wed Jun 12 20:35:29 2013 -0400
+++ b/src/os/windows/vm/perfMemory_windows.cpp	Thu Jun 13 04:13:42 2013 -0700
@@ -58,7 +58,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");
     }
--- a/src/share/vm/gc_implementation/parallelScavenge/cardTableExtension.cpp	Wed Jun 12 20:35:29 2013 -0400
+++ b/src/share/vm/gc_implementation/parallelScavenge/cardTableExtension.cpp	Thu Jun 13 04:13:42 2013 -0700
@@ -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()) {
--- a/src/share/vm/gc_implementation/parallelScavenge/psVirtualspace.cpp	Wed Jun 12 20:35:29 2013 -0400
+++ b/src/share/vm/gc_implementation/parallelScavenge/psVirtualspace.cpp	Thu Jun 13 04:13:42 2013 -0700
@@ -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,
--- a/src/share/vm/gc_implementation/shared/gcTrace.cpp	Wed Jun 12 20:35:29 2013 -0400
+++ b/src/share/vm/gc_implementation/shared/gcTrace.cpp	Thu Jun 13 04:13:42 2013 -0700
@@ -23,13 +23,15 @@
  */
 
 #include "precompiled.hpp"
+#include "gc_implementation/shared/copyFailedInfo.hpp"
 #include "gc_implementation/shared/gcHeapSummary.hpp"
 #include "gc_implementation/shared/gcTimer.hpp"
 #include "gc_implementation/shared/gcTrace.hpp"
-#include "gc_implementation/shared/copyFailedInfo.hpp"
+#include "gc_implementation/shared/objectCountEventSender.hpp"
 #include "memory/heapInspection.hpp"
 #include "memory/iterator.hpp"
 #include "memory/referenceProcessorStats.hpp"
+#include "runtime/os.hpp"
 #include "utilities/globalDefinitions.hpp"
 
 #ifndef SERIALGC
@@ -91,35 +93,60 @@
   send_reference_stats_event(REF_PHANTOM, rps.phantom_count());
 }
 
-void ObjectCountEventSenderClosure::do_cinfo(KlassInfoEntry* entry) {
-  if (should_send_event(entry)) {
-    send_event(entry);
+class ObjectCountEventSenderClosure : public KlassInfoClosure {
+  const GCId _gc_id;
+  const double _size_threshold_percentage;
+  const size_t _total_size_in_words;
+  const jlong _timestamp;
+
+ public:
+  ObjectCountEventSenderClosure(GCId gc_id, size_t total_size_in_words, jlong timestamp) :
+    _gc_id(gc_id),
+    _size_threshold_percentage(ObjectCountCutOffPercent / 100),
+    _total_size_in_words(total_size_in_words),
+    _timestamp(timestamp)
+  {}
+
+  virtual void do_cinfo(KlassInfoEntry* entry) {
+    if (should_send_event(entry)) {
+      ObjectCountEventSender::send(entry, _gc_id, _timestamp);
+    }
   }
-}
 
-void ObjectCountEventSenderClosure::send_event(KlassInfoEntry* entry) {
-  _gc_tracer->send_object_count_after_gc_event(entry->klass(), entry->count(),
-                                               entry->words() * BytesPerWord);
-}
+ private:
+  bool should_send_event(const KlassInfoEntry* entry) const {
+    double percentage_of_heap = ((double) entry->words()) / _total_size_in_words;
+    return percentage_of_heap >= _size_threshold_percentage;
+  }
+};
 
-bool ObjectCountEventSenderClosure::should_send_event(KlassInfoEntry* entry) const {
-  double percentage_of_heap = ((double) entry->words()) / _total_size_in_words;
-  return percentage_of_heap > _size_threshold_percentage;
-}
+class ObjectCountFilter : public BoolObjectClosure {
+  BoolObjectClosure* _is_alive;
 
-bool ObjectCountFilter::do_object_b(oop obj) {
-  bool is_alive = _is_alive == NULL? true : _is_alive->do_object_b(obj);
-  return is_alive && is_externally_visible_klass(obj->klass());
-}
+ public:
+  ObjectCountFilter(BoolObjectClosure* is_alive) : _is_alive(is_alive) {
+    assert(is_alive != NULL, "Must supply function to check liveness");
+  }
 
-bool ObjectCountFilter::is_externally_visible_klass(klassOop k) const {
-  // Do not expose internal implementation specific classes
-  return (k->klass_part()->oop_is_instance() || k->klass_part()->oop_is_array()) &&
-         k != Universe::systemObjArrayKlassObj();
-}
+  bool do_object_b(oop obj) {
+    return _is_alive->do_object_b(obj) && is_externally_visible_klass(obj->klass());
+  }
+
+  void do_object(oop obj) { ShouldNotReachHere(); }
+
+ private:
+  bool is_externally_visible_klass(klassOop k) const {
+    // Do not expose internal implementation specific classes
+    return (k->klass_part()->oop_is_instance() || k->klass_part()->oop_is_array()) &&
+           k != Universe::systemObjArrayKlassObj();
+  }
+};
 
 void GCTracer::report_object_count_after_gc(BoolObjectClosure *is_alive_cl) {
-  if (should_send_object_count_after_gc_event()) {
+  assert_set_gc_id();
+  assert(is_alive_cl != NULL, "Must supply function to check liveness");
+
+  if (ObjectCountEventSender::should_send_event()) {
     ResourceMark rm;
 
     KlassInfoTable cit(HeapInspection::start_of_perm_gen());
@@ -127,7 +154,8 @@
       ObjectCountFilter object_filter(is_alive_cl);
       HeapInspection::populate_table(&cit, false, &object_filter);
 
-      ObjectCountEventSenderClosure event_sender(this, cit.size_of_instances_in_words());
+      jlong timestamp = os::elapsed_counter();
+      ObjectCountEventSenderClosure event_sender(_shared_gc_info.id(), cit.size_of_instances_in_words(), timestamp);
       cit.iterate(&event_sender);
     }
   }
--- a/src/share/vm/gc_implementation/shared/gcTrace.hpp	Wed Jun 12 20:35:29 2013 -0400
+++ b/src/share/vm/gc_implementation/shared/gcTrace.hpp	Thu Jun 13 04:13:42 2013 -0700
@@ -30,7 +30,6 @@
 #include "gc_implementation/shared/gcWhen.hpp"
 #include "gc_implementation/shared/copyFailedInfo.hpp"
 #include "memory/allocation.hpp"
-#include "memory/klassInfoClosure.hpp"
 #include "memory/referenceType.hpp"
 #ifndef SERIALGC
 #include "gc_implementation/g1/g1YCTypes.hpp"
@@ -112,7 +111,6 @@
 #endif // SERIALGC
 
 class GCTracer : public ResourceObj {
-  friend class ObjectCountEventSenderClosure;
  protected:
   SharedGCInfo _shared_gc_info;
 
@@ -136,35 +134,6 @@
   void send_perm_gen_summary_event(GCWhen::Type when, const PermGenSummary& perm_gen_summary) const;
   void send_reference_stats_event(ReferenceType type, size_t count) const;
   void send_phase_events(TimePartitions* time_partitions) const;
-  void send_object_count_after_gc_event(klassOop klass, jlong count, julong total_size) const;
-  bool should_send_object_count_after_gc_event() const;
-};
-
-class ObjectCountEventSenderClosure : public KlassInfoClosure {
-  GCTracer* _gc_tracer;
-  const double _size_threshold_percentage;
-  const size_t _total_size_in_words;
- public:
-  ObjectCountEventSenderClosure(GCTracer* gc_tracer, size_t total_size_in_words) :
-    _gc_tracer(gc_tracer),
-    _size_threshold_percentage(ObjectCountCutOffPercent / 100),
-    _total_size_in_words(total_size_in_words)
-  {}
-  virtual void do_cinfo(KlassInfoEntry* entry);
- protected:
-  virtual void send_event(KlassInfoEntry* entry);
- private:
-  bool should_send_event(KlassInfoEntry* entry) const;
-};
-
-class ObjectCountFilter : public BoolObjectClosure {
-  BoolObjectClosure* _is_alive;
- public:
-  ObjectCountFilter(BoolObjectClosure* is_alive = NULL) : _is_alive(is_alive) {}
-  bool do_object_b(oop obj);
-  void do_object(oop obj) { ShouldNotReachHere(); }
- private:
-  bool is_externally_visible_klass(klassOop k) const;
 };
 
 class YoungGCTracer : public GCTracer {
--- a/src/share/vm/gc_implementation/shared/gcTraceSend.cpp	Wed Jun 12 20:35:29 2013 -0400
+++ b/src/share/vm/gc_implementation/shared/gcTraceSend.cpp	Thu Jun 13 04:13:42 2013 -0700
@@ -123,25 +123,6 @@
   }
 }
 
-void GCTracer::send_object_count_after_gc_event(klassOop klass, jlong count, julong total_size) const {
-  EventObjectCountAfterGC e;
-  if (e.should_commit()) {
-    e.set_gcId(_shared_gc_info.id());
-    e.set_class(klass);
-    e.set_count(count);
-    e.set_totalSize(total_size);
-    e.commit();
-  }
-}
-
-bool GCTracer::should_send_object_count_after_gc_event() const {
-#if INCLUDE_TRACE
-  return Tracing::is_event_enabled(EventObjectCountAfterGC::eventId);
-#else
-  return false;
-#endif
-}
-
 #ifndef SERIALGC
 void G1NewTracer::send_g1_young_gc_event() {
   EventGCG1GarbageCollection e(UNTIMED);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/vm/gc_implementation/shared/objectCountEventSender.cpp	Thu Jun 13 04:13:42 2013 -0700
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+
+#include "precompiled.hpp"
+#include "gc_implementation/shared/objectCountEventSender.hpp"
+#include "memory/heapInspection.hpp"
+#include "trace/tracing.hpp"
+#include "utilities/globalDefinitions.hpp"
+
+void ObjectCountEventSender::send(const KlassInfoEntry* entry, GCId gc_id, jlong timestamp) {
+  assert(Tracing::is_event_enabled(EventObjectCountAfterGC::eventId),
+         "Only call this method if the event is enabled");
+
+  EventObjectCountAfterGC event(UNTIMED);
+  event.set_gcId(gc_id);
+  event.set_class(entry->klass());
+  event.set_count(entry->count());
+  event.set_totalSize(entry->words() * BytesPerWord);
+  event.set_endtime(timestamp);
+  event.commit();
+}
+
+bool ObjectCountEventSender::should_send_event() {
+#if INCLUDE_TRACE
+  return Tracing::is_event_enabled(EventObjectCountAfterGC::eventId);
+#else
+  return false;
+#endif
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/vm/gc_implementation/shared/objectCountEventSender.hpp	Thu Jun 13 04:13:42 2013 -0700
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#ifndef SHARE_VM_OBJECT_COUNT_EVENT_SENDER_HPP
+#define SHARE_VM_OBJECT_COUNT_EVENT_SENDER_HPP
+
+#include "gc_implementation/shared/gcTrace.hpp"
+#include "memory/allocation.hpp"
+
+class KlassInfoEntry;
+
+class ObjectCountEventSender : public AllStatic {
+ public:
+  static void send(const KlassInfoEntry* entry, GCId gc_id, jlong timestamp);
+  static bool should_send_event();
+};
+
+#endif // SHARE_VM_OBJECT_COUNT_EVENT_SENDER
--- a/src/share/vm/memory/allocation.inline.hpp	Wed Jun 12 20:35:29 2013 -0400
+++ b/src/share/vm/memory/allocation.inline.hpp	Thu Jun 13 04:13:42 2013 -0700
@@ -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
@@ -128,10 +128,7 @@
     vm_exit_out_of_memory(_size, "Allocator (reserve)");
   }
 
-  bool success = os::commit_memory(_addr, _size, false /* executable */);
-  if (!success) {
-    vm_exit_out_of_memory(_size, "Allocator (commit)");
-  }
+  os::commit_memory_or_exit(_addr, _size, !ExecMem, "Allocator (commit)");
 
   return (E*)_addr;
 }
--- a/src/share/vm/memory/cardTableModRefBS.cpp	Wed Jun 12 20:35:29 2013 -0400
+++ b/src/share/vm/memory/cardTableModRefBS.cpp	Thu Jun 13 04:13:42 2013 -0700
@@ -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
@@ -113,10 +113,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;
 
@@ -288,12 +286,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()) {
--- a/src/share/vm/memory/heapInspection.hpp	Wed Jun 12 20:35:29 2013 -0400
+++ b/src/share/vm/memory/heapInspection.hpp	Thu Jun 13 04:13:42 2013 -0700
@@ -26,7 +26,6 @@
 #define SHARE_VM_MEMORY_HEAPINSPECTION_HPP
 
 #include "memory/allocation.inline.hpp"
-#include "memory/klassInfoClosure.hpp"
 #include "oops/oop.inline.hpp"
 
 
@@ -56,15 +55,21 @@
   {}
   KlassInfoEntry* next()     { return _next; }
   bool is_equal(klassOop k)  { return k == _klass; }
-  klassOop klass()           { return _klass; }
-  long count()               { return _instance_count; }
+  klassOop klass() const     { return _klass; }
+  long count() const         { return _instance_count; }
   void set_count(long ct)    { _instance_count = ct; }
-  size_t words()             { return _instance_words; }
+  size_t words() const       { return _instance_words; }
   void set_words(size_t wds) { _instance_words = wds; }
   int compare(KlassInfoEntry* e1, KlassInfoEntry* e2);
   void print_on(outputStream* st) const;
 };
 
+class KlassInfoClosure : public StackObj {
+ public:
+  // Called for each KlassInfoEntry.
+  virtual void do_cinfo(KlassInfoEntry* cie) = 0;
+};
+
 class KlassInfoBucket: public CHeapObj<mtInternal> {
  private:
   KlassInfoEntry* _list;
--- a/src/share/vm/memory/klassInfoClosure.hpp	Wed Jun 12 20:35:29 2013 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,36 +0,0 @@
-/*
- * Copyright (c) 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
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-#ifndef SHARE_VM_MEMORY_KLASSINFOCLOSURE_HPP
-#define SHARE_VM_MEMORY_KLASSINFOCLOSURE_HPP
-
-class KlassInfoEntry;
-
-class KlassInfoClosure : public StackObj {
- public:
-  // Called for each KlassInfoEntry.
-  virtual void do_cinfo(KlassInfoEntry* cie) = 0;
-};
-
-#endif // SHARE_VM_MEMORY_KLASSINFOCLOSURE_HPP
--- a/src/share/vm/prims/whitebox.cpp	Wed Jun 12 20:35:29 2013 -0400
+++ b/src/share/vm/prims/whitebox.cpp	Thu Jun 13 04:13:42 2013 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 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,7 +109,7 @@
 
 
 WB_ENTRY(void, WB_NMTCommitMemory(JNIEnv* env, jobject o, jlong addr, jlong size))
-  os::commit_memory((char *)(uintptr_t)addr, size);
+  os::commit_memory((char *)(uintptr_t)addr, size, !ExecMem);
   MemTracker::record_virtual_memory_type((address)(uintptr_t)addr, mtTest);
 WB_END
 
--- a/src/share/vm/runtime/os.cpp	Wed Jun 12 20:35:29 2013 -0400
+++ b/src/share/vm/runtime/os.cpp	Thu Jun 13 04:13:42 2013 -0700
@@ -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
@@ -1448,6 +1448,18 @@
   return res;
 }
 
+void os::commit_memory_or_exit(char* addr, size_t bytes, bool executable,
+                               const char* mesg) {
+  pd_commit_memory_or_exit(addr, bytes, executable, mesg);
+  MemTracker::record_virtual_memory_commit((address)addr, bytes, CALLER_PC);
+}
+
+void os::commit_memory_or_exit(char* addr, size_t size, size_t alignment_hint,
+                               bool executable, const char* mesg) {
+  os::pd_commit_memory_or_exit(addr, size, alignment_hint, executable, mesg);
+  MemTracker::record_virtual_memory_commit((address)addr, size, CALLER_PC);
+}
+
 bool os::uncommit_memory(char* addr, size_t bytes) {
   MemTracker::Tracker tkr = MemTracker::get_virtual_memory_uncommit_tracker();
   bool res = pd_uncommit_memory(addr, bytes);
--- a/src/share/vm/runtime/os.hpp	Wed Jun 12 20:35:29 2013 -0400
+++ b/src/share/vm/runtime/os.hpp	Thu Jun 13 04:13:42 2013 -0700
@@ -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);
 
@@ -104,9 +108,16 @@
   static char*  pd_attempt_reserve_memory_at(size_t bytes, char* addr);
   static void   pd_split_reserved_memory(char *base, size_t size,
                                       size_t split, bool realloc);
-  static bool   pd_commit_memory(char* addr, size_t bytes, bool executable = false);
+  static bool   pd_commit_memory(char* addr, size_t bytes, bool executable);
   static bool   pd_commit_memory(char* addr, size_t size, size_t alignment_hint,
-                              bool executable = false);
+                                 bool executable);
+  // Same as pd_commit_memory() that either succeeds or calls
+  // vm_exit_out_of_memory() with the specified mesg.
+  static void   pd_commit_memory_or_exit(char* addr, size_t bytes,
+                                         bool executable, const char* mesg);
+  static void   pd_commit_memory_or_exit(char* addr, size_t size,
+                                         size_t alignment_hint,
+                                         bool executable, const char* mesg);
   static bool   pd_uncommit_memory(char* addr, size_t bytes);
   static bool   pd_release_memory(char* addr, size_t bytes);
 
@@ -261,9 +272,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);
   static bool   can_release_partial_region();
--- a/src/share/vm/runtime/virtualspace.cpp	Wed Jun 12 20:35:29 2013 -0400
+++ b/src/share/vm/runtime/virtualspace.cpp	Thu Jun 13 04:13:42 2013 -0700
@@ -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
@@ -746,11 +746,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() &&
@@ -758,7 +760,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;
@@ -768,7 +773,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/test/runtime/CommandLine/CompilerConfigFileWarning.java	Thu Jun 13 04:13:42 2013 -0700
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 7167142
+ * @summary Warn if unused .hotspot_compiler file is present
+ * @library /testlibrary
+ */
+
+import java.io.PrintWriter;
+import com.oracle.java.testlibrary.*;
+
+public class CompilerConfigFileWarning {
+    public static void main(String[] args) throws Exception {
+        String vmVersion = System.getProperty("java.vm.version");
+        if (vmVersion.toLowerCase().contains("debug") || vmVersion.toLowerCase().contains("jvmg")) {
+            System.out.println("Skip on debug builds since we'll always read the file there");
+            return;
+        }
+
+        PrintWriter pw = new PrintWriter(".hotspot_compiler");
+        pw.println("aa");
+        pw.close();
+
+        ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("-version");
+        OutputAnalyzer output = new OutputAnalyzer(pb.start());
+        output.shouldContain("warning: .hotspot_compiler file is present but has been ignored.  Run with -XX:CompileCommandFile=.hotspot_compiler to load the file.");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/runtime/CommandLine/ConfigFileWarning.java	Thu Jun 13 04:13:42 2013 -0700
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 7167142
+ * @summary Warn if unused .hotspot_rc file is present
+ * @library /testlibrary
+ */
+
+import java.io.PrintWriter;
+import com.oracle.java.testlibrary.*;
+
+public class ConfigFileWarning {
+    public static void main(String[] args) throws Exception {
+        String vmVersion = System.getProperty("java.vm.version");
+        if (vmVersion.toLowerCase().contains("debug") || vmVersion.toLowerCase().contains("jvmg")) {
+            System.out.println("Skip on debug builds since we'll always read the file there");
+            return;
+        }
+
+        PrintWriter pw = new PrintWriter(".hotspotrc");
+        pw.println("aa");
+        pw.close();
+
+        ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("-version");
+        OutputAnalyzer output = new OutputAnalyzer(pb.start());
+        output.shouldContain("warning: .hotspotrc file is present but has been ignored.  Run with -XX:Flags=.hotspotrc to load the file.");
+    }
+}