Merge
authordcubed
Fri, 31 Oct 2014 10:15:29 -0700
changeset 27464 37671dcc4d8d
parent 27446 c461dfe64745 (current diff)
parent 27462 2fef16b8c70f (diff)
child 27465 cba6e4a24ad9
Merge
hotspot/src/share/vm/compiler/compileBroker.cpp
hotspot/src/share/vm/compiler/compileBroker.hpp
--- a/hotspot/src/os/bsd/vm/os_bsd.cpp	Fri Oct 31 08:00:09 2014 +0000
+++ b/hotspot/src/os/bsd/vm/os_bsd.cpp	Fri Oct 31 10:15:29 2014 -0700
@@ -4118,7 +4118,18 @@
 }
 
 
-// Refer to the comments in os_solaris.cpp park-unpark.
+// Refer to the comments in os_solaris.cpp park-unpark. The next two
+// comment paragraphs are worth repeating here:
+//
+// Assumption:
+//    Only one parker can exist on an event, which is why we allocate
+//    them per-thread. Multiple unparkers can coexist.
+//
+// _Event serves as a restricted-range semaphore.
+//   -1 : thread is blocked, i.e. there is a waiter
+//    0 : neutral: thread is running or ready,
+//        could have been signaled after a wait started
+//    1 : signaled - thread is running or ready
 //
 // Beware -- Some versions of NPTL embody a flaw where pthread_cond_timedwait() can
 // hang indefinitely.  For instance NPTL 0.60 on 2.4.21-4ELsmp is vulnerable.
@@ -4203,6 +4214,11 @@
 }
 
 void os::PlatformEvent::park() {       // AKA "down()"
+  // Transitions for _Event:
+  //   -1 => -1 : illegal
+  //    1 =>  0 : pass - return immediately
+  //    0 => -1 : block; then set _Event to 0 before returning
+
   // Invariant: Only the thread associated with the Event/PlatformEvent
   // may call park().
   // TODO: assert that _Assoc != NULL or _Assoc == Self
@@ -4240,6 +4256,11 @@
 }
 
 int os::PlatformEvent::park(jlong millis) {
+  // Transitions for _Event:
+  //   -1 => -1 : illegal
+  //    1 =>  0 : pass - return immediately
+  //    0 => -1 : block; then set _Event to 0 before returning
+
   guarantee(_nParked == 0, "invariant");
 
   int v;
@@ -4303,11 +4324,11 @@
 
 void os::PlatformEvent::unpark() {
   // Transitions for _Event:
-  //    0 :=> 1
-  //    1 :=> 1
-  //   -1 :=> either 0 or 1; must signal target thread
-  //          That is, we can safely transition _Event from -1 to either
-  //          0 or 1.
+  //    0 => 1 : just return
+  //    1 => 1 : just return
+  //   -1 => either 0 or 1; must signal target thread
+  //         That is, we can safely transition _Event from -1 to either
+  //         0 or 1.
   // See also: "Semaphores in Plan 9" by Mullender & Cox
   //
   // Note: Forcing a transition from "-1" to "1" on an unpark() means
@@ -4330,15 +4351,16 @@
   status = pthread_mutex_unlock(_mutex);
   assert_status(status == 0, status, "mutex_unlock");
   if (AnyWaiters != 0) {
+    // Note that we signal() *after* dropping the lock for "immortal" Events.
+    // This is safe and avoids a common class of  futile wakeups.  In rare
+    // circumstances this can cause a thread to return prematurely from
+    // cond_{timed}wait() but the spurious wakeup is benign and the victim
+    // will simply re-test the condition and re-park itself.
+    // This provides particular benefit if the underlying platform does not
+    // provide wait morphing.
     status = pthread_cond_signal(_cond);
     assert_status(status == 0, status, "cond_signal");
   }
-
-  // Note that we signal() _after dropping the lock for "immortal" Events.
-  // This is safe and avoids a common class of  futile wakeups.  In rare
-  // circumstances this can cause a thread to return prematurely from
-  // cond_{timed}wait() but the spurious wakeup is benign and the victim will
-  // simply re-test the condition and re-park itself.
 }
 
 
--- a/hotspot/src/os/linux/vm/os_linux.cpp	Fri Oct 31 08:00:09 2014 +0000
+++ b/hotspot/src/os/linux/vm/os_linux.cpp	Fri Oct 31 10:15:29 2014 -0700
@@ -5103,9 +5103,38 @@
     errno = ENAMETOOLONG;
     return -1;
   }
-  int fd;
-
-  fd = ::open64(path, oflag, mode);
+
+  // All file descriptors that are opened in the Java process and not
+  // specifically destined for a subprocess should have the close-on-exec
+  // flag set.  If we don't set it, then careless 3rd party native code
+  // might fork and exec without closing all appropriate file descriptors
+  // (e.g. as we do in closeDescriptors in UNIXProcess.c), and this in
+  // turn might:
+  //
+  // - cause end-of-file to fail to be detected on some file
+  //   descriptors, resulting in mysterious hangs, or
+  //
+  // - might cause an fopen in the subprocess to fail on a system
+  //   suffering from bug 1085341.
+  //
+  // (Yes, the default setting of the close-on-exec flag is a Unix
+  // design flaw)
+  //
+  // See:
+  // 1085341: 32-bit stdio routines should support file descriptors >255
+  // 4843136: (process) pipe file descriptor from Runtime.exec not being closed
+  // 6339493: (process) Runtime.exec does not close all file descriptors on Solaris 9
+  //
+  // Modern Linux kernels (after 2.6.23 2007) support O_CLOEXEC with open().
+  // O_CLOEXEC is preferable to using FD_CLOEXEC on an open file descriptor
+  // because it saves a system call and removes a small window where the flag
+  // is unset.  On ancient Linux kernels the O_CLOEXEC flag will be ignored
+  // and we fall back to using FD_CLOEXEC (see below).
+#ifdef O_CLOEXEC
+  oflag |= O_CLOEXEC;
+#endif
+
+  int fd = ::open64(path, oflag, mode);
   if (fd == -1) return -1;
 
   //If the open succeeded, the file might still be a directory
@@ -5126,32 +5155,17 @@
     }
   }
 
-  // All file descriptors that are opened in the JVM and not
-  // specifically destined for a subprocess should have the
-  // close-on-exec flag set.  If we don't set it, then careless 3rd
-  // party native code might fork and exec without closing all
-  // appropriate file descriptors (e.g. as we do in closeDescriptors in
-  // UNIXProcess.c), and this in turn might:
-  //
-  // - cause end-of-file to fail to be detected on some file
-  //   descriptors, resulting in mysterious hangs, or
-  //
-  // - might cause an fopen in the subprocess to fail on a system
-  //   suffering from bug 1085341.
-  //
-  // (Yes, the default setting of the close-on-exec flag is a Unix
-  // design flaw)
-  //
-  // See:
-  // 1085341: 32-bit stdio routines should support file descriptors >255
-  // 4843136: (process) pipe file descriptor from Runtime.exec not being closed
-  // 6339493: (process) Runtime.exec does not close all file descriptors on Solaris 9
-  //
 #ifdef FD_CLOEXEC
-  {
+  // Validate that the use of the O_CLOEXEC flag on open above worked.
+  // With recent kernels, we will perform this check exactly once.
+  static sig_atomic_t O_CLOEXEC_is_known_to_work = 0;
+  if (!O_CLOEXEC_is_known_to_work) {
     int flags = ::fcntl(fd, F_GETFD);
     if (flags != -1) {
-      ::fcntl(fd, F_SETFD, flags | FD_CLOEXEC);
+      if ((flags & FD_CLOEXEC) != 0)
+        O_CLOEXEC_is_known_to_work = 1;
+      else
+        ::fcntl(fd, F_SETFD, flags | FD_CLOEXEC);
     }
   }
 #endif
@@ -5401,7 +5415,18 @@
 }
 
 
-// Refer to the comments in os_solaris.cpp park-unpark.
+// Refer to the comments in os_solaris.cpp park-unpark. The next two
+// comment paragraphs are worth repeating here:
+//
+// Assumption:
+//    Only one parker can exist on an event, which is why we allocate
+//    them per-thread. Multiple unparkers can coexist.
+//
+// _Event serves as a restricted-range semaphore.
+//   -1 : thread is blocked, i.e. there is a waiter
+//    0 : neutral: thread is running or ready,
+//        could have been signaled after a wait started
+//    1 : signaled - thread is running or ready
 //
 // Beware -- Some versions of NPTL embody a flaw where pthread_cond_timedwait() can
 // hang indefinitely.  For instance NPTL 0.60 on 2.4.21-4ELsmp is vulnerable.
@@ -5500,6 +5525,11 @@
 }
 
 void os::PlatformEvent::park() {       // AKA "down()"
+  // Transitions for _Event:
+  //   -1 => -1 : illegal
+  //    1 =>  0 : pass - return immediately
+  //    0 => -1 : block; then set _Event to 0 before returning
+
   // Invariant: Only the thread associated with the Event/PlatformEvent
   // may call park().
   // TODO: assert that _Assoc != NULL or _Assoc == Self
@@ -5537,6 +5567,11 @@
 }
 
 int os::PlatformEvent::park(jlong millis) {
+  // Transitions for _Event:
+  //   -1 => -1 : illegal
+  //    1 =>  0 : pass - return immediately
+  //    0 => -1 : block; then set _Event to 0 before returning
+
   guarantee(_nParked == 0, "invariant");
 
   int v;
@@ -5600,11 +5635,11 @@
 
 void os::PlatformEvent::unpark() {
   // Transitions for _Event:
-  //    0 :=> 1
-  //    1 :=> 1
-  //   -1 :=> either 0 or 1; must signal target thread
-  //          That is, we can safely transition _Event from -1 to either
-  //          0 or 1.
+  //    0 => 1 : just return
+  //    1 => 1 : just return
+  //   -1 => either 0 or 1; must signal target thread
+  //         That is, we can safely transition _Event from -1 to either
+  //         0 or 1.
   // See also: "Semaphores in Plan 9" by Mullender & Cox
   //
   // Note: Forcing a transition from "-1" to "1" on an unpark() means
@@ -5627,15 +5662,16 @@
   status = pthread_mutex_unlock(_mutex);
   assert_status(status == 0, status, "mutex_unlock");
   if (AnyWaiters != 0) {
+    // Note that we signal() *after* dropping the lock for "immortal" Events.
+    // This is safe and avoids a common class of  futile wakeups.  In rare
+    // circumstances this can cause a thread to return prematurely from
+    // cond_{timed}wait() but the spurious wakeup is benign and the victim
+    // will simply re-test the condition and re-park itself.
+    // This provides particular benefit if the underlying platform does not
+    // provide wait morphing.
     status = pthread_cond_signal(_cond);
     assert_status(status == 0, status, "cond_signal");
   }
-
-  // Note that we signal() _after dropping the lock for "immortal" Events.
-  // This is safe and avoids a common class of  futile wakeups.  In rare
-  // circumstances this can cause a thread to return prematurely from
-  // cond_{timed}wait() but the spurious wakeup is benign and the victim will
-  // simply re-test the condition and re-park itself.
 }
 
 
--- a/hotspot/src/os/solaris/vm/os_solaris.cpp	Fri Oct 31 08:00:09 2014 +0000
+++ b/hotspot/src/os/solaris/vm/os_solaris.cpp	Fri Oct 31 10:15:29 2014 -0700
@@ -5372,31 +5372,32 @@
 // to immediately return 0 your code should still work,
 // albeit degenerating to a spin loop.
 //
-// An interesting optimization for park() is to use a trylock()
-// to attempt to acquire the mutex.  If the trylock() fails
-// then we know that a concurrent unpark() operation is in-progress.
-// in that case the park() code could simply set _count to 0
-// and return immediately.  The subsequent park() operation *might*
-// return immediately.  That's harmless as the caller of park() is
-// expected to loop.  By using trylock() we will have avoided a
-// avoided a context switch caused by contention on the per-thread mutex.
+// In a sense, park()-unpark() just provides more polite spinning
+// and polling with the key difference over naive spinning being
+// that a parked thread needs to be explicitly unparked() in order
+// to wake up and to poll the underlying condition.
 //
-// TODO-FIXME:
-// 1.  Reconcile Doug's JSR166 j.u.c park-unpark with the
-//     objectmonitor implementation.
-// 2.  Collapse the JSR166 parker event, and the
-//     objectmonitor ParkEvent into a single "Event" construct.
-// 3.  In park() and unpark() add:
-//     assert (Thread::current() == AssociatedWith).
-// 4.  add spurious wakeup injection on a -XX:EarlyParkReturn=N switch.
-//     1-out-of-N park() operations will return immediately.
+// Assumption:
+//    Only one parker can exist on an event, which is why we allocate
+//    them per-thread. Multiple unparkers can coexist.
 //
 // _Event transitions in park()
 //   -1 => -1 : illegal
 //    1 =>  0 : pass - return immediately
-//    0 => -1 : block
+//    0 => -1 : block; then set _Event to 0 before returning
+//
+// _Event transitions in unpark()
+//    0 => 1 : just return
+//    1 => 1 : just return
+//   -1 => either 0 or 1; must signal target thread
+//         That is, we can safely transition _Event from -1 to either
+//         0 or 1.
 //
 // _Event serves as a restricted-range semaphore.
+//   -1 : thread is blocked, i.e. there is a waiter
+//    0 : neutral: thread is running or ready,
+//        could have been signaled after a wait started
+//    1 : signaled - thread is running or ready
 //
 // Another possible encoding of _Event would be with
 // explicit "PARKED" == 01b and "SIGNALED" == 10b bits.
@@ -5456,6 +5457,11 @@
 }
 
 void os::PlatformEvent::park() {           // AKA: down()
+  // Transitions for _Event:
+  //   -1 => -1 : illegal
+  //    1 =>  0 : pass - return immediately
+  //    0 => -1 : block; then set _Event to 0 before returning
+
   // Invariant: Only the thread associated with the Event/PlatformEvent
   // may call park().
   assert(_nParked == 0, "invariant");
@@ -5497,6 +5503,11 @@
 }
 
 int os::PlatformEvent::park(jlong millis) {
+  // Transitions for _Event:
+  //   -1 => -1 : illegal
+  //    1 =>  0 : pass - return immediately
+  //    0 => -1 : block; then set _Event to 0 before returning
+
   guarantee(_nParked == 0, "invariant");
   int v;
   for (;;) {
@@ -5542,11 +5553,11 @@
 
 void os::PlatformEvent::unpark() {
   // Transitions for _Event:
-  //    0 :=> 1
-  //    1 :=> 1
-  //   -1 :=> either 0 or 1; must signal target thread
-  //          That is, we can safely transition _Event from -1 to either
-  //          0 or 1.
+  //    0 => 1 : just return
+  //    1 => 1 : just return
+  //   -1 => either 0 or 1; must signal target thread
+  //         That is, we can safely transition _Event from -1 to either
+  //         0 or 1.
   // See also: "Semaphores in Plan 9" by Mullender & Cox
   //
   // Note: Forcing a transition from "-1" to "1" on an unpark() means
@@ -5566,8 +5577,13 @@
   assert_status(status == 0, status, "mutex_unlock");
   guarantee(AnyWaiters == 0 || AnyWaiters == 1, "invariant");
   if (AnyWaiters != 0) {
-    // We intentional signal *after* dropping the lock
-    // to avoid a common class of futile wakeups.
+    // Note that we signal() *after* dropping the lock for "immortal" Events.
+    // This is safe and avoids a common class of  futile wakeups.  In rare
+    // circumstances this can cause a thread to return prematurely from
+    // cond_{timed}wait() but the spurious wakeup is benign and the victim
+    // will simply re-test the condition and re-park itself.
+    // This provides particular benefit if the underlying platform does not
+    // provide wait morphing.
     status = os::Solaris::cond_signal(_cond);
     assert_status(status == 0, status, "cond_signal");
   }
--- a/hotspot/src/os/windows/vm/os_windows.cpp	Fri Oct 31 08:00:09 2014 +0000
+++ b/hotspot/src/os/windows/vm/os_windows.cpp	Fri Oct 31 10:15:29 2014 -0700
@@ -436,9 +436,9 @@
   }
 
   // Diagnostic code to investigate JDK-6573254
-  int res = 90115;  // non-java thread
+  int res = 50115;  // non-java thread
   if (thread->is_Java_thread()) {
-    res = 60115;    // java thread
+    res = 40115;    // java thread
   }
 
   // Install a win32 structured exception handler around every thread created
@@ -3740,68 +3740,134 @@
   return NULL;
 }
 
-#define MIN_EXIT_MUTEXES 1
-#define MAX_EXIT_MUTEXES 16
-
-struct ExitMutexes {
-  DWORD count;
-  HANDLE handles[MAX_EXIT_MUTEXES];
-};
-
-static BOOL CALLBACK init_muts_call(PINIT_ONCE, PVOID ppmuts, PVOID*) {
-  static ExitMutexes muts;
-
-  muts.count = os::processor_count();
-  if (muts.count < MIN_EXIT_MUTEXES) {
-    muts.count = MIN_EXIT_MUTEXES;
-  } else if (muts.count > MAX_EXIT_MUTEXES) {
-    muts.count = MAX_EXIT_MUTEXES;
-  }
-
-  for (DWORD i = 0; i < muts.count; ++i) {
-    muts.handles[i] = CreateMutex(NULL, FALSE, NULL);
-    if (muts.handles[i] == NULL) {
-      return FALSE;
-    }
-  }
-  *((ExitMutexes**)ppmuts) = &muts;
+#define MAX_EXIT_HANDLES    16
+#define EXIT_TIMEOUT      1000 /* 1 sec */
+
+static BOOL CALLBACK init_crit_sect_call(PINIT_ONCE, PVOID pcrit_sect, PVOID*) {
+  InitializeCriticalSection((CRITICAL_SECTION*)pcrit_sect);
   return TRUE;
 }
 
 int os::win32::exit_process_or_thread(Ept what, int exit_code) {
+  // Basic approach:
+  //  - Each exiting thread registers its intent to exit and then does so.
+  //  - A thread trying to terminate the process must wait for all
+  //    threads currently exiting to complete their exit.
+
   if (os::win32::has_exit_bug()) {
-    static INIT_ONCE init_once_muts = INIT_ONCE_STATIC_INIT;
-    static ExitMutexes* pmuts;
-
-    if (!InitOnceExecuteOnce(&init_once_muts, init_muts_call, &pmuts, NULL)) {
-      warning("ExitMutex initialization failed in %s: %d\n", __FILE__, __LINE__);
-    } else if (WaitForMultipleObjects(pmuts->count, pmuts->handles,
-                                      (what != EPT_THREAD), // exiting process waits for all mutexes
-                                      INFINITE) == WAIT_FAILED) {
-      warning("ExitMutex acquisition failed in %s: %d\n", __FILE__, __LINE__);
+    // The array holds handles of the threads that have started exiting by calling
+    // _endthreadex().
+    // Should be large enough to avoid blocking the exiting thread due to lack of
+    // a free slot.
+    static HANDLE handles[MAX_EXIT_HANDLES];
+    static int handle_count = 0;
+
+    static INIT_ONCE init_once_crit_sect = INIT_ONCE_STATIC_INIT;
+    static CRITICAL_SECTION crit_sect;
+    int i, j;
+    DWORD res;
+    HANDLE hproc, hthr;
+
+    // The first thread that reached this point, initializes the critical section.
+    if (!InitOnceExecuteOnce(&init_once_crit_sect, init_crit_sect_call, &crit_sect, NULL)) {
+      warning("crit_sect initialization failed in %s: %d\n", __FILE__, __LINE__);
+    } else {
+      EnterCriticalSection(&crit_sect);
+
+      if (what == EPT_THREAD) {
+        // Remove from the array those handles of the threads that have completed exiting.
+        for (i = 0, j = 0; i < handle_count; ++i) {
+          res = WaitForSingleObject(handles[i], 0 /* don't wait */);
+          if (res == WAIT_TIMEOUT) {
+            handles[j++] = handles[i];
+          } else {
+            if (res != WAIT_OBJECT_0) {
+              warning("WaitForSingleObject failed in %s: %d\n", __FILE__, __LINE__);
+              // Don't keep the handle, if we failed waiting for it.
+            }
+            CloseHandle(handles[i]);
+          }
+        }
+
+        // If there's no free slot in the array of the kept handles, we'll have to
+        // wait until at least one thread completes exiting.
+        if ((handle_count = j) == MAX_EXIT_HANDLES) {
+          res = WaitForMultipleObjects(MAX_EXIT_HANDLES, handles, FALSE, EXIT_TIMEOUT);
+          if (res >= WAIT_OBJECT_0 && res < (WAIT_OBJECT_0 + MAX_EXIT_HANDLES)) {
+            i = (res - WAIT_OBJECT_0);
+            handle_count = MAX_EXIT_HANDLES - 1;
+            for (; i < handle_count; ++i) {
+              handles[i] = handles[i + 1];
+            }
+          } else {
+            warning("WaitForMultipleObjects failed in %s: %d\n", __FILE__, __LINE__);
+            // Don't keep handles, if we failed waiting for them.
+            for (i = 0; i < MAX_EXIT_HANDLES; ++i) {
+              CloseHandle(handles[i]);
+            }
+            handle_count = 0;
+          }
+        }
+
+        // Store a duplicate of the current thread handle in the array of handles.
+        hproc = GetCurrentProcess();
+        hthr = GetCurrentThread();
+        if (!DuplicateHandle(hproc, hthr, hproc, &handles[handle_count],
+                             0, FALSE, DUPLICATE_SAME_ACCESS)) {
+          warning("DuplicateHandle failed in %s: %d\n", __FILE__, __LINE__);
+        } else {
+          ++handle_count;
+        }
+
+        // The current exiting thread has stored its handle in the array, and now
+        // should leave the critical section before calling _endthreadex().
+
+      } else { // what != EPT_THREAD
+        if (handle_count > 0) {
+          // Before ending the process, make sure all the threads that had called
+          // _endthreadex() completed.
+          res = WaitForMultipleObjects(handle_count, handles, TRUE, EXIT_TIMEOUT);
+          if (res == WAIT_FAILED) {
+            warning("WaitForMultipleObjects failed in %s: %d\n", __FILE__, __LINE__);
+          }
+          for (i = 0; i < handle_count; ++i) {
+            CloseHandle(handles[i]);
+          }
+          handle_count = 0;
+        }
+
+        // End the process, not leaving critical section.
+        // This makes sure no other thread executes exit-related code at the same
+        // time, thus a race is avoided.
+        if (what == EPT_PROCESS) {
+          ::exit(exit_code);
+        } else {
+          _exit(exit_code);
+        }
+      }
+
+      LeaveCriticalSection(&crit_sect);
     }
   }
 
-  switch (what) {
-  case EPT_THREAD:
+  // We are here if either
+  // - there's no 'race at exit' bug on this OS release;
+  // - initialization of the critical section failed (unlikely);
+  // - the current thread has stored its handle and left the critical section.
+  if (what == EPT_THREAD) {
     _endthreadex((unsigned)exit_code);
-    break;
-
-  case EPT_PROCESS:
+  } else if (what == EPT_PROCESS) {
     ::exit(exit_code);
-    break;
-
-  case EPT_PROCESS_DIE:
+  } else {
     _exit(exit_code);
-    break;
-  }
-
-  // should not reach here
+  }
+
+  // Should not reach here
   return exit_code;
 }
 
-#undef MIN_EXIT_MUTEXES
-#undef MAX_EXIT_MUTEXES
+#undef MAX_EXIT_HANDLES
+#undef EXIT_TIMEOUT
 
 void os::win32::setmode_streams() {
   _setmode(_fileno(stdin), _O_BINARY);
@@ -4792,27 +4858,46 @@
 // 3.  Collapse the interrupt_event, the JSR166 parker event, and the objectmonitor ParkEvent
 //     into a single win32 CreateEvent() handle.
 //
+// Assumption:
+//    Only one parker can exist on an event, which is why we allocate
+//    them per-thread. Multiple unparkers can coexist.
+//
 // _Event transitions in park()
 //   -1 => -1 : illegal
 //    1 =>  0 : pass - return immediately
-//    0 => -1 : block
+//    0 => -1 : block; then set _Event to 0 before returning
+//
+// _Event transitions in unpark()
+//    0 => 1 : just return
+//    1 => 1 : just return
+//   -1 => either 0 or 1; must signal target thread
+//         That is, we can safely transition _Event from -1 to either
+//         0 or 1.
 //
-// _Event serves as a restricted-range semaphore :
-//    -1 : thread is blocked
-//     0 : neutral  - thread is running or ready
-//     1 : signaled - thread is running or ready
+// _Event serves as a restricted-range semaphore.
+//   -1 : thread is blocked, i.e. there is a waiter
+//    0 : neutral: thread is running or ready,
+//        could have been signaled after a wait started
+//    1 : signaled - thread is running or ready
 //
-// Another possible encoding of _Event would be
-// with explicit "PARKED" and "SIGNALED" bits.
+// Another possible encoding of _Event would be with
+// explicit "PARKED" == 01b and "SIGNALED" == 10b bits.
+//
 
 int os::PlatformEvent::park(jlong Millis) {
+  // Transitions for _Event:
+  //   -1 => -1 : illegal
+  //    1 =>  0 : pass - return immediately
+  //    0 => -1 : block; then set _Event to 0 before returning
+
   guarantee(_ParkHandle != NULL , "Invariant");
   guarantee(Millis > 0          , "Invariant");
-  int v;
 
   // CONSIDER: defer assigning a CreateEvent() handle to the Event until
   // the initial park() operation.
-
+  // Consider: use atomic decrement instead of CAS-loop
+
+  int v;
   for (;;) {
     v = _Event;
     if (Atomic::cmpxchg(v-1, &_Event, v) == v) break;
@@ -4860,9 +4945,15 @@
 }
 
 void os::PlatformEvent::park() {
+  // Transitions for _Event:
+  //   -1 => -1 : illegal
+  //    1 =>  0 : pass - return immediately
+  //    0 => -1 : block; then set _Event to 0 before returning
+
   guarantee(_ParkHandle != NULL, "Invariant");
   // Invariant: Only the thread associated with the Event/PlatformEvent
   // may call park().
+  // Consider: use atomic decrement instead of CAS-loop
   int v;
   for (;;) {
     v = _Event;
@@ -4891,11 +4982,11 @@
   guarantee(_ParkHandle != NULL, "Invariant");
 
   // Transitions for _Event:
-  //    0 :=> 1
-  //    1 :=> 1
-  //   -1 :=> either 0 or 1; must signal target thread
-  //          That is, we can safely transition _Event from -1 to either
-  //          0 or 1.
+  //    0 => 1 : just return
+  //    1 => 1 : just return
+  //   -1 => either 0 or 1; must signal target thread
+  //         That is, we can safely transition _Event from -1 to either
+  //         0 or 1.
   // See also: "Semaphores in Plan 9" by Mullender & Cox
   //
   // Note: Forcing a transition from "-1" to "1" on an unpark() means
--- a/hotspot/src/share/vm/classfile/classLoaderData.cpp	Fri Oct 31 08:00:09 2014 +0000
+++ b/hotspot/src/share/vm/classfile/classLoaderData.cpp	Fri Oct 31 10:15:29 2014 -0700
@@ -553,6 +553,7 @@
 ClassLoaderData* ClassLoaderDataGraph::_saved_head = NULL;
 
 bool ClassLoaderDataGraph::_should_purge = false;
+bool ClassLoaderDataGraph::_metaspace_oom = false;
 
 // Add a new class loader data node to the list.  Assign the newly created
 // ClassLoaderData into the java/lang/ClassLoader object as a hidden field
@@ -804,12 +805,17 @@
   ClassLoaderData* list = _unloading;
   _unloading = NULL;
   ClassLoaderData* next = list;
+  bool classes_unloaded = false;
   while (next != NULL) {
     ClassLoaderData* purge_me = next;
     next = purge_me->next();
     delete purge_me;
+    classes_unloaded = true;
   }
-  Metaspace::purge();
+  if (classes_unloaded) {
+    Metaspace::purge();
+    set_metaspace_oom(false);
+  }
 }
 
 void ClassLoaderDataGraph::post_class_unload_events(void) {
--- a/hotspot/src/share/vm/classfile/classLoaderData.hpp	Fri Oct 31 08:00:09 2014 +0000
+++ b/hotspot/src/share/vm/classfile/classLoaderData.hpp	Fri Oct 31 10:15:29 2014 -0700
@@ -68,6 +68,9 @@
   static ClassLoaderData* _saved_head;
   static ClassLoaderData* _saved_unloading;
   static bool _should_purge;
+  // OOM has been seen in metaspace allocation. Used to prevent some
+  // allocations until class unloading
+  static bool _metaspace_oom;
 
   static ClassLoaderData* add(Handle class_loader, bool anonymous, TRAPS);
   static void post_class_unload_events(void);
@@ -107,6 +110,9 @@
     }
   }
 
+  static bool has_metaspace_oom()           { return _metaspace_oom; }
+  static void set_metaspace_oom(bool value) { _metaspace_oom = value; }
+
   static void free_deallocate_lists();
 
   static void dump_on(outputStream * const out) PRODUCT_RETURN;
--- a/hotspot/src/share/vm/compiler/compileBroker.cpp	Fri Oct 31 08:00:09 2014 +0000
+++ b/hotspot/src/share/vm/compiler/compileBroker.cpp	Fri Oct 31 10:15:29 2014 -0700
@@ -185,6 +185,14 @@
     lm.print("\n");
     log(thread, "%s", (const char*)lm);
   }
+
+  void log_metaspace_failure(const char* reason) {
+    ResourceMark rm;
+    StringLogMessage lm;
+    lm.print("%4d   COMPILE PROFILING SKIPPED: %s", -1, reason);
+    lm.print("\n");
+    log(JavaThread::current(), "%s", (const char*)lm);
+  }
 };
 
 static CompilationLog* _compilation_log = NULL;
@@ -1817,6 +1825,18 @@
     warning("Cannot open log file: %s", file_name);
 }
 
+void CompileBroker::log_metaspace_failure() {
+  const char* message = "some methods may not be compiled because metaspace "
+                        "is out of memory";
+  if (_compilation_log != NULL) {
+    _compilation_log->log_metaspace_failure(message);
+  }
+  if (PrintCompilation) {
+    tty->print_cr("COMPILE PROFILING SKIPPED: %s", message);
+  }
+}
+
+
 // ------------------------------------------------------------------
 // CompileBroker::set_should_block
 //
--- a/hotspot/src/share/vm/compiler/compileBroker.hpp	Fri Oct 31 08:00:09 2014 +0000
+++ b/hotspot/src/share/vm/compiler/compileBroker.hpp	Fri Oct 31 10:15:29 2014 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2014, 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
@@ -471,6 +471,9 @@
   static int get_sum_nmethod_code_size() {        return _sum_nmethod_code_size; }
   static long get_peak_compilation_time() {       return _peak_compilation_time; }
   static long get_total_compilation_time() {      return _t_total_compilation.milliseconds(); }
+
+  // Log that compilation profiling is skipped because metaspace is full.
+  static void log_metaspace_failure();
 };
 
 #endif // SHARE_VM_COMPILER_COMPILEBROKER_HPP
--- a/hotspot/src/share/vm/oops/method.cpp	Fri Oct 31 08:00:09 2014 +0000
+++ b/hotspot/src/share/vm/oops/method.cpp	Fri Oct 31 10:15:29 2014 -0700
@@ -368,6 +368,13 @@
 // Build a MethodData* object to hold information about this method
 // collected in the interpreter.
 void Method::build_interpreter_method_data(methodHandle method, TRAPS) {
+  // Do not profile the method if metaspace has hit an OOM previously
+  // allocating profiling data. Callers clear pending exception so don't
+  // add one here.
+  if (ClassLoaderDataGraph::has_metaspace_oom()) {
+    return;
+  }
+
   // Do not profile method if current thread holds the pending list lock,
   // which avoids deadlock for acquiring the MethodData_lock.
   if (InstanceRefKlass::owns_pending_list_lock((JavaThread*)THREAD)) {
@@ -379,7 +386,13 @@
   MutexLocker ml(MethodData_lock, THREAD);
   if (method->method_data() == NULL) {
     ClassLoaderData* loader_data = method->method_holder()->class_loader_data();
-    MethodData* method_data = MethodData::allocate(loader_data, method, CHECK);
+    MethodData* method_data = MethodData::allocate(loader_data, method, THREAD);
+    if (HAS_PENDING_EXCEPTION) {
+      CompileBroker::log_metaspace_failure();
+      ClassLoaderDataGraph::set_metaspace_oom(true);
+      return;   // return the exception (which is cleared)
+    }
+
     method->set_method_data(method_data);
     if (PrintMethodData && (Verbose || WizardMode)) {
       ResourceMark rm(THREAD);
@@ -392,9 +405,19 @@
 }
 
 MethodCounters* Method::build_method_counters(Method* m, TRAPS) {
+  // Do not profile the method if metaspace has hit an OOM previously
+  if (ClassLoaderDataGraph::has_metaspace_oom()) {
+    return NULL;
+  }
+
   methodHandle mh(m);
   ClassLoaderData* loader_data = mh->method_holder()->class_loader_data();
-  MethodCounters* counters = MethodCounters::allocate(loader_data, CHECK_NULL);
+  MethodCounters* counters = MethodCounters::allocate(loader_data, THREAD);
+  if (HAS_PENDING_EXCEPTION) {
+    CompileBroker::log_metaspace_failure();
+    ClassLoaderDataGraph::set_metaspace_oom(true);
+    return NULL;   // return the exception (which is cleared)
+  }
   if (!mh->init_method_counters(counters)) {
     MetadataFactory::free_metadata(loader_data, counters);
   }
--- a/hotspot/src/share/vm/services/runtimeService.cpp	Fri Oct 31 08:00:09 2014 +0000
+++ b/hotspot/src/share/vm/services/runtimeService.cpp	Fri Oct 31 10:15:29 2014 -0700
@@ -38,6 +38,7 @@
 PerfCounter*  RuntimeService::_total_safepoints = NULL;
 PerfCounter*  RuntimeService::_safepoint_time_ticks = NULL;
 PerfCounter*  RuntimeService::_application_time_ticks = NULL;
+double RuntimeService::_last_safepoint_sync_time_sec = 0.0;
 
 void RuntimeService::init() {
   // Make sure the VM version is initialized
@@ -96,6 +97,7 @@
 
   // update the time stamp to begin recording safepoint time
   _safepoint_timer.update();
+  _last_safepoint_sync_time_sec = 0.0;
   if (UsePerfData) {
     _total_safepoints->inc();
     if (_app_timer.is_updated()) {
@@ -108,6 +110,9 @@
   if (UsePerfData) {
     _sync_time_ticks->inc(_safepoint_timer.ticks_since_update());
   }
+  if (PrintGCApplicationStoppedTime) {
+    _last_safepoint_sync_time_sec = last_safepoint_time_sec();
+  }
 }
 
 void RuntimeService::record_safepoint_end() {
@@ -119,8 +124,10 @@
     gclog_or_tty->date_stamp(PrintGCDateStamps);
     gclog_or_tty->stamp(PrintGCTimeStamps);
     gclog_or_tty->print_cr("Total time for which application threads "
-                           "were stopped: %3.7f seconds",
-                           last_safepoint_time_sec());
+                           "were stopped: %3.7f seconds, "
+                           "Stopping threads took: %3.7f seconds",
+                           last_safepoint_time_sec(),
+                           _last_safepoint_sync_time_sec);
   }
 
   // update the time stamp to begin recording app time
--- a/hotspot/src/share/vm/services/runtimeService.hpp	Fri Oct 31 08:00:09 2014 +0000
+++ b/hotspot/src/share/vm/services/runtimeService.hpp	Fri Oct 31 10:15:29 2014 -0700
@@ -37,6 +37,7 @@
 
   static TimeStamp _safepoint_timer;
   static TimeStamp _app_timer;
+  static double _last_safepoint_sync_time_sec;
 
 public:
   static void init();
--- a/hotspot/test/serviceability/threads/TestFalseDeadLock.java	Fri Oct 31 08:00:09 2014 +0000
+++ b/hotspot/test/serviceability/threads/TestFalseDeadLock.java	Fri Oct 31 10:15:29 2014 -0700
@@ -27,6 +27,7 @@
 
 /*
  * @test
+ * @ignore 8061157
  * @bug 8016304
  * @summary Make sure no deadlock is reported for this program which has no deadlocks.
  * @run main/othervm TestFalseDeadLock