Merge
authordcubed
Tue, 16 Feb 2016 12:01:37 -0800
changeset 36103 363dc2b4fc1c
parent 35952 a99b4b16202c (current diff)
parent 36102 84546518799d (diff)
child 36104 65f01ec9666f
child 36173 31a3af05892d
Merge
hotspot/src/cpu/aarch64/vm/globals_aarch64.hpp
hotspot/src/share/vm/runtime/globals.hpp
--- a/hotspot/.hgignore	Thu Feb 11 13:58:41 2016 -0800
+++ b/hotspot/.hgignore	Tue Feb 16 12:01:37 2016 -0800
@@ -10,7 +10,6 @@
 .igv.log
 ^.hgtip
 .DS_Store
-\.class$
 ^\.mx.jvmci/env
 ^\.mx.jvmci/.*\.pyc
 ^\.mx.jvmci/eclipse-launches/.*
--- a/hotspot/src/cpu/aarch64/vm/globals_aarch64.hpp	Thu Feb 11 13:58:41 2016 -0800
+++ b/hotspot/src/cpu/aarch64/vm/globals_aarch64.hpp	Tue Feb 16 12:01:37 2016 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.
  * Copyright (c) 2015, Red Hat Inc. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
@@ -32,7 +32,6 @@
 // Sets the default values for platform dependent flags used by the runtime system.
 // (see globals.hpp)
 
-define_pd_global(bool, ConvertSleepToYield,      true);
 define_pd_global(bool, ShareVtableStubs,         true);
 define_pd_global(bool, NeedsDeoptSuspend,        false); // only register window machines need this
 
--- a/hotspot/src/cpu/ppc/vm/globals_ppc.hpp	Thu Feb 11 13:58:41 2016 -0800
+++ b/hotspot/src/cpu/ppc/vm/globals_ppc.hpp	Tue Feb 16 12:01:37 2016 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2016, Oracle and/or its affiliates. All rights reserved.
  * Copyright (c) 2012, 2015 SAP SE. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
@@ -32,7 +32,6 @@
 // Sets the default values for platform dependent flags used by the runtime system.
 // (see globals.hpp)
 
-define_pd_global(bool, ConvertSleepToYield,   true);
 define_pd_global(bool, ShareVtableStubs,      false); // Improves performance markedly for mtrt and compress.
 define_pd_global(bool, NeedsDeoptSuspend,     false); // Only register window machines need this.
 
--- a/hotspot/src/cpu/sparc/vm/globals_sparc.hpp	Thu Feb 11 13:58:41 2016 -0800
+++ b/hotspot/src/cpu/sparc/vm/globals_sparc.hpp	Tue Feb 16 12:01:37 2016 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2016, 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
@@ -37,7 +37,6 @@
 // the load of the dispatch address and hence the jmp would still go to the location
 // according to the prior table. So, we let the thread continue and let it block by itself.
 define_pd_global(bool, DontYieldALot,               true);  // yield no more than 100 times per second
-define_pd_global(bool, ConvertSleepToYield,         false); // do not convert sleep(0) to yield. Helps GUI
 define_pd_global(bool, ShareVtableStubs,            false); // improves performance markedly for mtrt and compress
 define_pd_global(bool, NeedsDeoptSuspend,           true); // register window machines need this
 
--- a/hotspot/src/cpu/x86/vm/globals_x86.hpp	Thu Feb 11 13:58:41 2016 -0800
+++ b/hotspot/src/cpu/x86/vm/globals_x86.hpp	Tue Feb 16 12:01:37 2016 -0800
@@ -31,7 +31,6 @@
 // Sets the default values for platform dependent flags used by the runtime system.
 // (see globals.hpp)
 
-define_pd_global(bool, ConvertSleepToYield,      true);
 define_pd_global(bool, ShareVtableStubs,         true);
 define_pd_global(bool, NeedsDeoptSuspend,        false); // only register window machines need this
 
--- a/hotspot/src/cpu/zero/vm/globals_zero.hpp	Thu Feb 11 13:58:41 2016 -0800
+++ b/hotspot/src/cpu/zero/vm/globals_zero.hpp	Tue Feb 16 12:01:37 2016 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.
  * Copyright 2007, 2008, 2009, 2010, 2011 Red Hat, Inc.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
@@ -32,7 +32,6 @@
 // Set the default values for platform dependent flags used by the
 // runtime system.  See globals.hpp for details of what they do.
 
-define_pd_global(bool,  ConvertSleepToYield,  true);
 define_pd_global(bool,  ShareVtableStubs,     true);
 define_pd_global(bool,  NeedsDeoptSuspend,    false);
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/gc/shared/G1HeapRegionType.java	Tue Feb 16 12:01:37 2016 -0800
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2016, 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.
+ *
+ */
+
+package sun.jvm.hotspot.gc.shared;
+
+//These definitions should be kept in sync with the definitions in the HotSpot code.
+
+public enum G1HeapRegionType {
+  Free ("Free"),
+  Eden ("Eden"),
+  Survivor ("Survivor"),
+  StartsHumongous ("Starts Humongous"),
+  ContinuesHumongous ("Continues Humongous"),
+  Old ("Old"),
+  Archive ("Archive"),
+  G1HeapRegionTypeEndSentinel ("G1HeapRegionTypeEndSentinel");
+
+  private final String value;
+
+  G1HeapRegionType(String val) {
+    this.value = val;
+  }
+  public String value() {
+    return value;
+  }
+}
--- a/hotspot/src/os/bsd/vm/os_bsd.cpp	Thu Feb 11 13:58:41 2016 -0800
+++ b/hotspot/src/os/bsd/vm/os_bsd.cpp	Tue Feb 16 12:01:37 2016 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2016, 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
@@ -4042,61 +4042,6 @@
 //        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.
-// For specifics regarding the bug see GLIBC BUGID 261237 :
-//    http://www.mail-archive.com/debian-glibc@lists.debian.org/msg10837.html.
-// Briefly, pthread_cond_timedwait() calls with an expiry time that's not in the future
-// will either hang or corrupt the condvar, resulting in subsequent hangs if the condvar
-// is used.  (The simple C test-case provided in the GLIBC bug report manifests the
-// hang).  The JVM is vulernable via sleep(), Object.wait(timo), LockSupport.parkNanos()
-// and monitorenter when we're using 1-0 locking.  All those operations may result in
-// calls to pthread_cond_timedwait().  Using LD_ASSUME_KERNEL to use an older version
-// of libpthread avoids the problem, but isn't practical.
-//
-// Possible remedies:
-//
-// 1.   Establish a minimum relative wait time.  50 to 100 msecs seems to work.
-//      This is palliative and probabilistic, however.  If the thread is preempted
-//      between the call to compute_abstime() and pthread_cond_timedwait(), more
-//      than the minimum period may have passed, and the abstime may be stale (in the
-//      past) resultin in a hang.   Using this technique reduces the odds of a hang
-//      but the JVM is still vulnerable, particularly on heavily loaded systems.
-//
-// 2.   Modify park-unpark to use per-thread (per ParkEvent) pipe-pairs instead
-//      of the usual flag-condvar-mutex idiom.  The write side of the pipe is set
-//      NDELAY. unpark() reduces to write(), park() reduces to read() and park(timo)
-//      reduces to poll()+read().  This works well, but consumes 2 FDs per extant
-//      thread.
-//
-// 3.   Embargo pthread_cond_timedwait() and implement a native "chron" thread
-//      that manages timeouts.  We'd emulate pthread_cond_timedwait() by enqueuing
-//      a timeout request to the chron thread and then blocking via pthread_cond_wait().
-//      This also works well.  In fact it avoids kernel-level scalability impediments
-//      on certain platforms that don't handle lots of active pthread_cond_timedwait()
-//      timers in a graceful fashion.
-//
-// 4.   When the abstime value is in the past it appears that control returns
-//      correctly from pthread_cond_timedwait(), but the condvar is left corrupt.
-//      Subsequent timedwait/wait calls may hang indefinitely.  Given that, we
-//      can avoid the problem by reinitializing the condvar -- by cond_destroy()
-//      followed by cond_init() -- after all calls to pthread_cond_timedwait().
-//      It may be possible to avoid reinitialization by checking the return
-//      value from pthread_cond_timedwait().  In addition to reinitializing the
-//      condvar we must establish the invariant that cond_signal() is only called
-//      within critical sections protected by the adjunct mutex.  This prevents
-//      cond_signal() from "seeing" a condvar that's in the midst of being
-//      reinitialized or that is corrupt.  Sadly, this invariant obviates the
-//      desirable signal-after-unlock optimization that avoids futile context switching.
-//
-//      I'm also concerned that some versions of NTPL might allocate an auxilliary
-//      structure when a condvar is used or initialized.  cond_destroy()  would
-//      release the helper structure.  Our reinitialize-after-timedwait fix
-//      put excessive stress on malloc/free and locks protecting the c-heap.
-//
-// We currently use (4).  See the WorkAroundNTPLTimedWaitHang flag.
-// It may be possible to refine (4) by checking the kernel and NTPL verisons
-// and only enabling the work-around for vulnerable environments.
 
 // utility to compute the abstime argument to timedwait:
 // millis is the relative timeout time
@@ -4208,10 +4153,6 @@
 
   while (_Event < 0) {
     status = pthread_cond_timedwait(_cond, _mutex, &abst);
-    if (status != 0 && WorkAroundNPTLTimedWaitHang) {
-      pthread_cond_destroy(_cond);
-      pthread_cond_init(_cond, NULL);
-    }
     assert_status(status == 0 || status == EINTR ||
                   status == ETIMEDOUT,
                   status, "cond_timedwait");
@@ -4255,10 +4196,6 @@
   assert_status(status == 0, status, "mutex_lock");
   int AnyWaiters = _nParked;
   assert(AnyWaiters == 0 || AnyWaiters == 1, "invariant");
-  if (AnyWaiters != 0 && WorkAroundNPTLTimedWaitHang) {
-    AnyWaiters = 0;
-    pthread_cond_signal(_cond);
-  }
   status = pthread_mutex_unlock(_mutex);
   assert_status(status == 0, status, "mutex_unlock");
   if (AnyWaiters != 0) {
@@ -4391,7 +4328,7 @@
   if (_counter > 0)  { // no wait needed
     _counter = 0;
     status = pthread_mutex_unlock(_mutex);
-    assert(status == 0, "invariant");
+    assert_status(status == 0, status, "invariant");
     // Paranoia to ensure our locked and lock-free paths interact
     // correctly with each other and Java-level accesses.
     OrderAccess::fence();
@@ -4414,10 +4351,6 @@
     status = pthread_cond_wait(_cond, _mutex);
   } else {
     status = pthread_cond_timedwait(_cond, _mutex, &absTime);
-    if (status != 0 && WorkAroundNPTLTimedWaitHang) {
-      pthread_cond_destroy(_cond);
-      pthread_cond_init(_cond, NULL);
-    }
   }
   assert_status(status == 0 || status == EINTR ||
                 status == ETIMEDOUT,
@@ -4442,24 +4375,14 @@
 
 void Parker::unpark() {
   int status = pthread_mutex_lock(_mutex);
-  assert(status == 0, "invariant");
+  assert_status(status == 0, status, "invariant");
   const int s = _counter;
   _counter = 1;
+  status = pthread_mutex_unlock(_mutex);
+  assert_status(status == 0, status, "invariant");
   if (s < 1) {
-    if (WorkAroundNPTLTimedWaitHang) {
-      status = pthread_cond_signal(_cond);
-      assert(status == 0, "invariant");
-      status = pthread_mutex_unlock(_mutex);
-      assert(status == 0, "invariant");
-    } else {
-      status = pthread_mutex_unlock(_mutex);
-      assert(status == 0, "invariant");
-      status = pthread_cond_signal(_cond);
-      assert(status == 0, "invariant");
-    }
-  } else {
-    pthread_mutex_unlock(_mutex);
-    assert(status == 0, "invariant");
+    status = pthread_cond_signal(_cond);
+    assert_status(status == 0, status, "invariant");
   }
 }
 
--- a/hotspot/src/os/linux/vm/os_linux.cpp	Thu Feb 11 13:58:41 2016 -0800
+++ b/hotspot/src/os/linux/vm/os_linux.cpp	Tue Feb 16 12:01:37 2016 -0800
@@ -4771,6 +4771,25 @@
   }
 }
 
+// older glibc versions don't have this macro (which expands to
+// an optimized bit-counting function) so we have to roll our own
+#ifndef CPU_COUNT
+
+static int _cpu_count(const cpu_set_t* cpus) {
+  int count = 0;
+  // only look up to the number of configured processors
+  for (int i = 0; i < os::processor_count(); i++) {
+    if (CPU_ISSET(i, cpus)) {
+      count++;
+    }
+  }
+  return count;
+}
+
+#define CPU_COUNT(cpus) _cpu_count(cpus)
+
+#endif // CPU_COUNT
+
 // Get the current number of available processors for this process.
 // This value can change at any time during a process's lifetime.
 // sched_getaffinity gives an accurate answer as it accounts for cpusets.
@@ -4786,6 +4805,9 @@
   int configured_cpus = processor_count();  // upper bound on available cpus
   int cpu_count = 0;
 
+// old build platforms may not support dynamic cpu sets
+#ifdef CPU_ALLOC
+
   // To enable easy testing of the dynamic path on different platforms we
   // introduce a diagnostic flag: UseCpuAllocPath
   if (configured_cpus >= CPU_SETSIZE || UseCpuAllocPath) {
@@ -4814,10 +4836,18 @@
     log_trace(os)("active_processor_count: using static path - configured processors: %d",
                   configured_cpus);
   }
+#else // CPU_ALLOC
+// these stubs won't be executed
+#define CPU_COUNT_S(size, cpus) -1
+#define CPU_FREE(cpus)
+
+  log_trace(os)("active_processor_count: only static path available - configured processors: %d",
+                configured_cpus);
+#endif // CPU_ALLOC
 
   // pid 0 means the current thread - which we have to assume represents the process
   if (sched_getaffinity(0, cpus_size, cpus_p) == 0) {
-    if (cpus_p != &cpus) {
+    if (cpus_p != &cpus) { // can only be true when CPU_ALLOC used
       cpu_count = CPU_COUNT_S(cpus_size, cpus_p);
     }
     else {
@@ -4831,7 +4861,7 @@
             "which may exceed available processors", strerror(errno), cpu_count);
   }
 
-  if (cpus_p != &cpus) {
+  if (cpus_p != &cpus) { // can only be true when CPU_ALLOC used
     CPU_FREE(cpus_p);
   }
 
@@ -5349,61 +5379,6 @@
 //        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.
-// For specifics regarding the bug see GLIBC BUGID 261237 :
-//    http://www.mail-archive.com/debian-glibc@lists.debian.org/msg10837.html.
-// Briefly, pthread_cond_timedwait() calls with an expiry time that's not in the future
-// will either hang or corrupt the condvar, resulting in subsequent hangs if the condvar
-// is used.  (The simple C test-case provided in the GLIBC bug report manifests the
-// hang).  The JVM is vulernable via sleep(), Object.wait(timo), LockSupport.parkNanos()
-// and monitorenter when we're using 1-0 locking.  All those operations may result in
-// calls to pthread_cond_timedwait().  Using LD_ASSUME_KERNEL to use an older version
-// of libpthread avoids the problem, but isn't practical.
-//
-// Possible remedies:
-//
-// 1.   Establish a minimum relative wait time.  50 to 100 msecs seems to work.
-//      This is palliative and probabilistic, however.  If the thread is preempted
-//      between the call to compute_abstime() and pthread_cond_timedwait(), more
-//      than the minimum period may have passed, and the abstime may be stale (in the
-//      past) resultin in a hang.   Using this technique reduces the odds of a hang
-//      but the JVM is still vulnerable, particularly on heavily loaded systems.
-//
-// 2.   Modify park-unpark to use per-thread (per ParkEvent) pipe-pairs instead
-//      of the usual flag-condvar-mutex idiom.  The write side of the pipe is set
-//      NDELAY. unpark() reduces to write(), park() reduces to read() and park(timo)
-//      reduces to poll()+read().  This works well, but consumes 2 FDs per extant
-//      thread.
-//
-// 3.   Embargo pthread_cond_timedwait() and implement a native "chron" thread
-//      that manages timeouts.  We'd emulate pthread_cond_timedwait() by enqueuing
-//      a timeout request to the chron thread and then blocking via pthread_cond_wait().
-//      This also works well.  In fact it avoids kernel-level scalability impediments
-//      on certain platforms that don't handle lots of active pthread_cond_timedwait()
-//      timers in a graceful fashion.
-//
-// 4.   When the abstime value is in the past it appears that control returns
-//      correctly from pthread_cond_timedwait(), but the condvar is left corrupt.
-//      Subsequent timedwait/wait calls may hang indefinitely.  Given that, we
-//      can avoid the problem by reinitializing the condvar -- by cond_destroy()
-//      followed by cond_init() -- after all calls to pthread_cond_timedwait().
-//      It may be possible to avoid reinitialization by checking the return
-//      value from pthread_cond_timedwait().  In addition to reinitializing the
-//      condvar we must establish the invariant that cond_signal() is only called
-//      within critical sections protected by the adjunct mutex.  This prevents
-//      cond_signal() from "seeing" a condvar that's in the midst of being
-//      reinitialized or that is corrupt.  Sadly, this invariant obviates the
-//      desirable signal-after-unlock optimization that avoids futile context switching.
-//
-//      I'm also concerned that some versions of NTPL might allocate an auxilliary
-//      structure when a condvar is used or initialized.  cond_destroy()  would
-//      release the helper structure.  Our reinitialize-after-timedwait fix
-//      put excessive stress on malloc/free and locks protecting the c-heap.
-//
-// We currently use (4).  See the WorkAroundNTPLTimedWaitHang flag.
-// It may be possible to refine (4) by checking the kernel and NTPL verisons
-// and only enabling the work-around for vulnerable environments.
 
 // utility to compute the abstime argument to timedwait:
 // millis is the relative timeout time
@@ -5529,10 +5504,6 @@
 
   while (_Event < 0) {
     status = pthread_cond_timedwait(_cond, _mutex, &abst);
-    if (status != 0 && WorkAroundNPTLTimedWaitHang) {
-      pthread_cond_destroy(_cond);
-      pthread_cond_init(_cond, os::Linux::condAttr());
-    }
     assert_status(status == 0 || status == EINTR ||
                   status == ETIME || status == ETIMEDOUT,
                   status, "cond_timedwait");
@@ -5576,10 +5547,6 @@
   assert_status(status == 0, status, "mutex_lock");
   int AnyWaiters = _nParked;
   assert(AnyWaiters == 0 || AnyWaiters == 1, "invariant");
-  if (AnyWaiters != 0 && WorkAroundNPTLTimedWaitHang) {
-    AnyWaiters = 0;
-    pthread_cond_signal(_cond);
-  }
   status = pthread_mutex_unlock(_mutex);
   assert_status(status == 0, status, "mutex_unlock");
   if (AnyWaiters != 0) {
@@ -5731,7 +5698,7 @@
   if (_counter > 0)  { // no wait needed
     _counter = 0;
     status = pthread_mutex_unlock(_mutex);
-    assert(status == 0, "invariant");
+    assert_status(status == 0, status, "invariant");
     // Paranoia to ensure our locked and lock-free paths interact
     // correctly with each other and Java-level accesses.
     OrderAccess::fence();
@@ -5757,10 +5724,6 @@
   } else {
     _cur_index = isAbsolute ? ABS_INDEX : REL_INDEX;
     status = pthread_cond_timedwait(&_cond[_cur_index], _mutex, &absTime);
-    if (status != 0 && WorkAroundNPTLTimedWaitHang) {
-      pthread_cond_destroy(&_cond[_cur_index]);
-      pthread_cond_init(&_cond[_cur_index], isAbsolute ? NULL : os::Linux::condAttr());
-    }
   }
   _cur_index = -1;
   assert_status(status == 0 || status == EINTR ||
@@ -5786,33 +5749,17 @@
 
 void Parker::unpark() {
   int status = pthread_mutex_lock(_mutex);
-  assert(status == 0, "invariant");
+  assert_status(status == 0, status, "invariant");
   const int s = _counter;
   _counter = 1;
-  if (s < 1) {
-    // thread might be parked
-    if (_cur_index != -1) {
-      // thread is definitely parked
-      if (WorkAroundNPTLTimedWaitHang) {
-        status = pthread_cond_signal(&_cond[_cur_index]);
-        assert(status == 0, "invariant");
-        status = pthread_mutex_unlock(_mutex);
-        assert(status == 0, "invariant");
-      } else {
-        // must capture correct index before unlocking
-        int index = _cur_index;
-        status = pthread_mutex_unlock(_mutex);
-        assert(status == 0, "invariant");
-        status = pthread_cond_signal(&_cond[index]);
-        assert(status == 0, "invariant");
-      }
-    } else {
-      pthread_mutex_unlock(_mutex);
-      assert(status == 0, "invariant");
-    }
-  } else {
-    pthread_mutex_unlock(_mutex);
-    assert(status == 0, "invariant");
+  // must capture correct index before unlocking
+  int index = _cur_index;
+  status = pthread_mutex_unlock(_mutex);
+  assert_status(status == 0, status, "invariant");
+  if (s < 1 && index != -1) {
+    // thread is definitely parked
+    status = pthread_cond_signal(&_cond[index]);
+    assert_status(status == 0, status, "invariant");
   }
 }
 
--- a/hotspot/src/os_cpu/solaris_sparc/vm/vm_version_solaris_sparc.cpp	Thu Feb 11 13:58:41 2016 -0800
+++ b/hotspot/src/os_cpu/solaris_sparc/vm/vm_version_solaris_sparc.cpp	Tue Feb 16 12:01:37 2016 -0800
@@ -246,7 +246,6 @@
 bool PICL::open_library() {
   _dl_handle = dlopen("libpicl.so.1", RTLD_LAZY);
   if (_dl_handle == NULL) {
-    warning("PICL (libpicl.so.1) is missing. Performance will not be optimal.");
     return false;
   }
   if (!bind_library_functions()) {
--- a/hotspot/src/share/vm/gc/cms/compactibleFreeListSpace.cpp	Thu Feb 11 13:58:41 2016 -0800
+++ b/hotspot/src/share/vm/gc/cms/compactibleFreeListSpace.cpp	Tue Feb 16 12:01:37 2016 -0800
@@ -2206,13 +2206,13 @@
     }
     if (res == 0) {
       LogHandle(gc, verify) log;
-      log.info("Livelock: no rank reduction!");
-      log.info(" Current:  addr = " PTR_FORMAT ", size = " SIZE_FORMAT ", obj = %s, live = %s \n"
-               " Previous: addr = " PTR_FORMAT ", size = " SIZE_FORMAT ", obj = %s, live = %s \n",
+      log.error("Livelock: no rank reduction!");
+      log.error(" Current:  addr = " PTR_FORMAT ", size = " SIZE_FORMAT ", obj = %s, live = %s \n"
+                " Previous: addr = " PTR_FORMAT ", size = " SIZE_FORMAT ", obj = %s, live = %s \n",
         p2i(addr),       res,        was_obj      ?"true":"false", was_live      ?"true":"false",
         p2i(_last_addr), _last_size, _last_was_obj?"true":"false", _last_was_live?"true":"false");
       ResourceMark rm;
-      _sp->print_on(log.info_stream());
+      _sp->print_on(log.error_stream());
       guarantee(false, "Verification failed.");
     }
     _last_addr = addr;
--- a/hotspot/src/share/vm/gc/cms/concurrentMarkSweepGeneration.cpp	Thu Feb 11 13:58:41 2016 -0800
+++ b/hotspot/src/share/vm/gc/cms/concurrentMarkSweepGeneration.cpp	Tue Feb 16 12:01:37 2016 -0800
@@ -2224,8 +2224,8 @@
     if (!_marks->isMarked(addr)) {
       LogHandle(gc, verify) log;
       ResourceMark rm;
-      oop(addr)->print_on(log.info_stream());
-      log.info(" (" INTPTR_FORMAT " should have been marked)", p2i(addr));
+      oop(addr)->print_on(log.error_stream());
+      log.error(" (" INTPTR_FORMAT " should have been marked)", p2i(addr));
       _failed = true;
     }
     return true;
@@ -2350,9 +2350,9 @@
   verification_mark_bm()->iterate(&vcl);
   if (vcl.failed()) {
     LogHandle(gc, verify) log;
-    log.info("Verification failed");
+    log.error("Failed marking verification after remark");
     ResourceMark rm;
-    gch->print_on(log.info_stream());
+    gch->print_on(log.error_stream());
     fatal("CMS: failed marking verification after remark");
   }
 }
@@ -2923,7 +2923,7 @@
 
   CMSTokenSyncWithLocks ts(true, bitMapLock());
   GCTraceCPUTime tcpu;
-  CMSPhaseAccounting pa(this, "Concrurrent Mark");
+  CMSPhaseAccounting pa(this, "Concurrent Mark");
   bool res = markFromRootsWork();
   if (res) {
     _collectorState = Precleaning;
@@ -5880,8 +5880,8 @@
     if (!_cms_bm->isMarked(addr)) {
       LogHandle(gc, verify) log;
       ResourceMark rm;
-      oop(addr)->print_on(log.info_stream());
-      log.info(" (" INTPTR_FORMAT " should have been marked)", p2i(addr));
+      oop(addr)->print_on(log.error_stream());
+      log.error(" (" INTPTR_FORMAT " should have been marked)", p2i(addr));
       fatal("... aborting");
     }
   }
@@ -6661,8 +6661,8 @@
     if (!_cms_bm->isMarked(addr)) {
       LogHandle(gc, verify) log;
       ResourceMark rm;
-      oop(addr)->print_on(log.info_stream());
-      log.info(" (" INTPTR_FORMAT " should have been marked)", p2i(addr));
+      oop(addr)->print_on(log.error_stream());
+      log.error(" (" INTPTR_FORMAT " should have been marked)", p2i(addr));
       fatal("... aborting");
     }
 
--- a/hotspot/src/share/vm/gc/g1/concurrentMarkThread.cpp	Thu Feb 11 13:58:41 2016 -0800
+++ b/hotspot/src/share/vm/gc/g1/concurrentMarkThread.cpp	Tue Feb 16 12:01:37 2016 -0800
@@ -23,6 +23,7 @@
  */
 
 #include "precompiled.hpp"
+#include "classfile/classLoaderData.hpp"
 #include "gc/g1/concurrentMarkThread.inline.hpp"
 #include "gc/g1/g1CollectedHeap.inline.hpp"
 #include "gc/g1/g1CollectorPolicy.hpp"
@@ -123,6 +124,7 @@
     // wait until started is set.
     sleepBeforeNextCycle();
     if (_should_terminate) {
+      _cm->root_regions()->cancel_scan();
       break;
     }
 
@@ -132,6 +134,11 @@
       HandleMark   hm;
       double cycle_start = os::elapsedVTime();
 
+      {
+        GCConcPhaseTimer(_cm, "Concurrent Clearing of Claimed Marks");
+        ClassLoaderDataGraph::clear_claimed_marks();
+      }
+
       // We have to ensure that we finish scanning the root regions
       // before the next GC takes place. To ensure this we have to
       // make sure that we do not join the STS until the root regions
@@ -140,7 +147,7 @@
       // without the root regions have been scanned which would be a
       // correctness issue.
 
-      if (!cm()->has_aborted()) {
+      {
         GCConcPhaseTimer(_cm, "Concurrent Root Region Scanning");
         _cm->scanRootRegions();
       }
--- a/hotspot/src/share/vm/gc/g1/g1CollectedHeap.cpp	Thu Feb 11 13:58:41 2016 -0800
+++ b/hotspot/src/share/vm/gc/g1/g1CollectedHeap.cpp	Tue Feb 16 12:01:37 2016 -0800
@@ -1290,8 +1290,7 @@
       ref_processor_cm()->verify_no_references_recorded();
 
       // Abandon current iterations of concurrent marking and concurrent
-      // refinement, if any are in progress. We have to do this before
-      // wait_until_scan_finished() below.
+      // refinement, if any are in progress.
       concurrent_mark()->abort();
 
       // Make sure we'll choose a new allocation region afterwards.
@@ -2148,8 +2147,8 @@
   virtual bool doHeapRegion(HeapRegion* hr) {
     unsigned region_gc_time_stamp = hr->get_gc_time_stamp();
     if (_gc_time_stamp != region_gc_time_stamp) {
-      log_info(gc, verify)("Region " HR_FORMAT " has GC time stamp = %d, expected %d", HR_FORMAT_PARAMS(hr),
-                           region_gc_time_stamp, _gc_time_stamp);
+      log_error(gc, verify)("Region " HR_FORMAT " has GC time stamp = %d, expected %d", HR_FORMAT_PARAMS(hr),
+                            region_gc_time_stamp, _gc_time_stamp);
       _failures = true;
     }
     return false;
@@ -2848,7 +2847,7 @@
     (g1_policy()->young_list_target_length() * HeapRegion::GrainBytes) - survivor_used_bytes;
 
   VirtualSpaceSummary heap_summary = create_heap_space_summary();
-  return G1HeapSummary(heap_summary, used(), eden_used_bytes, eden_capacity_bytes, survivor_used_bytes);
+  return G1HeapSummary(heap_summary, used(), eden_used_bytes, eden_capacity_bytes, survivor_used_bytes, num_regions());
 }
 
 G1EvacSummary G1CollectedHeap::create_g1_evac_summary(G1EvacStats* stats) {
@@ -5186,8 +5185,8 @@
   NoYoungRegionsClosure() : _success(true) { }
   bool doHeapRegion(HeapRegion* r) {
     if (r->is_young()) {
-      log_info(gc, verify)("Region [" PTR_FORMAT ", " PTR_FORMAT ") tagged as young",
-                           p2i(r->bottom()), p2i(r->end()));
+      log_error(gc, verify)("Region [" PTR_FORMAT ", " PTR_FORMAT ") tagged as young",
+                            p2i(r->bottom()), p2i(r->end()));
       _success = false;
     }
     return false;
--- a/hotspot/src/share/vm/gc/g1/g1CollectorPolicy.cpp	Thu Feb 11 13:58:41 2016 -0800
+++ b/hotspot/src/share/vm/gc/g1/g1CollectorPolicy.cpp	Tue Feb 16 12:01:37 2016 -0800
@@ -293,29 +293,83 @@
   _heap_alignment = MAX3(card_table_alignment, _space_alignment, page_size);
 }
 
-void G1CollectorPolicy::initialize_flags() {
-  if (G1HeapRegionSize != HeapRegion::GrainBytes) {
-    FLAG_SET_ERGO(size_t, G1HeapRegionSize, HeapRegion::GrainBytes);
+G1CollectorState* G1CollectorPolicy::collector_state() const { return _g1->collector_state(); }
+
+// There are three command line options related to the young gen size:
+// NewSize, MaxNewSize and NewRatio (There is also -Xmn, but that is
+// just a short form for NewSize==MaxNewSize). G1 will use its internal
+// heuristics to calculate the actual young gen size, so these options
+// basically only limit the range within which G1 can pick a young gen
+// size. Also, these are general options taking byte sizes. G1 will
+// internally work with a number of regions instead. So, some rounding
+// will occur.
+//
+// If nothing related to the the young gen size is set on the command
+// line we should allow the young gen to be between G1NewSizePercent
+// and G1MaxNewSizePercent of the heap size. This means that every time
+// the heap size changes, the limits for the young gen size will be
+// recalculated.
+//
+// If only -XX:NewSize is set we should use the specified value as the
+// minimum size for young gen. Still using G1MaxNewSizePercent of the
+// heap as maximum.
+//
+// If only -XX:MaxNewSize is set we should use the specified value as the
+// maximum size for young gen. Still using G1NewSizePercent of the heap
+// as minimum.
+//
+// If -XX:NewSize and -XX:MaxNewSize are both specified we use these values.
+// No updates when the heap size changes. There is a special case when
+// NewSize==MaxNewSize. This is interpreted as "fixed" and will use a
+// different heuristic for calculating the collection set when we do mixed
+// collection.
+//
+// If only -XX:NewRatio is set we should use the specified ratio of the heap
+// as both min and max. This will be interpreted as "fixed" just like the
+// NewSize==MaxNewSize case above. But we will update the min and max
+// every time the heap size changes.
+//
+// NewSize and MaxNewSize override NewRatio. So, NewRatio is ignored if it is
+// combined with either NewSize or MaxNewSize. (A warning message is printed.)
+class G1YoungGenSizer : public CHeapObj<mtGC> {
+private:
+  enum SizerKind {
+    SizerDefaults,
+    SizerNewSizeOnly,
+    SizerMaxNewSizeOnly,
+    SizerMaxAndNewSize,
+    SizerNewRatio
+  };
+  SizerKind _sizer_kind;
+  uint _min_desired_young_length;
+  uint _max_desired_young_length;
+  bool _adaptive_size;
+  uint calculate_default_min_length(uint new_number_of_heap_regions);
+  uint calculate_default_max_length(uint new_number_of_heap_regions);
+
+  // Update the given values for minimum and maximum young gen length in regions
+  // given the number of heap regions depending on the kind of sizing algorithm.
+  void recalculate_min_max_young_length(uint number_of_heap_regions, uint* min_young_length, uint* max_young_length);
+
+public:
+  G1YoungGenSizer();
+  // Calculate the maximum length of the young gen given the number of regions
+  // depending on the sizing algorithm.
+  uint max_young_length(uint number_of_heap_regions);
+
+  void heap_size_changed(uint new_number_of_heap_regions);
+  uint min_desired_young_length() {
+    return _min_desired_young_length;
+  }
+  uint max_desired_young_length() {
+    return _max_desired_young_length;
   }
 
-  if (SurvivorRatio < 1) {
-    vm_exit_during_initialization("Invalid survivor ratio specified");
+  bool adaptive_young_list_length() const {
+    return _adaptive_size;
   }
-  CollectorPolicy::initialize_flags();
-  _young_gen_sizer = new G1YoungGenSizer(); // Must be after call to initialize_flags
-}
+};
 
-void G1CollectorPolicy::post_heap_initialize() {
-  uintx max_regions = G1CollectedHeap::heap()->max_regions();
-  size_t max_young_size = (size_t)_young_gen_sizer->max_young_length(max_regions) * HeapRegion::GrainBytes;
-  if (max_young_size != MaxNewSize) {
-    FLAG_SET_ERGO(size_t, MaxNewSize, max_young_size);
-  }
-
-  _ihop_control = create_ihop_control();
-}
-
-G1CollectorState* G1CollectorPolicy::collector_state() const { return _g1->collector_state(); }
 
 G1YoungGenSizer::G1YoungGenSizer() : _sizer_kind(SizerDefaults), _adaptive_size(true),
         _min_desired_young_length(0), _max_desired_young_length(0) {
@@ -412,6 +466,29 @@
           &_max_desired_young_length);
 }
 
+void G1CollectorPolicy::post_heap_initialize() {
+  uintx max_regions = G1CollectedHeap::heap()->max_regions();
+  size_t max_young_size = (size_t)_young_gen_sizer->max_young_length(max_regions) * HeapRegion::GrainBytes;
+  if (max_young_size != MaxNewSize) {
+    FLAG_SET_ERGO(size_t, MaxNewSize, max_young_size);
+  }
+
+  _ihop_control = create_ihop_control();
+}
+
+void G1CollectorPolicy::initialize_flags() {
+  if (G1HeapRegionSize != HeapRegion::GrainBytes) {
+    FLAG_SET_ERGO(size_t, G1HeapRegionSize, HeapRegion::GrainBytes);
+  }
+
+  if (SurvivorRatio < 1) {
+    vm_exit_during_initialization("Invalid survivor ratio specified");
+  }
+  CollectorPolicy::initialize_flags();
+  _young_gen_sizer = new G1YoungGenSizer(); // Must be after call to initialize_flags
+}
+
+
 void G1CollectorPolicy::init() {
   // Set aside an initial future to_space.
   _g1 = G1CollectedHeap::heap();
@@ -758,7 +835,7 @@
        curr = curr->get_next_young_region()) {
     SurvRateGroup* group = curr->surv_rate_group();
     if (group == NULL && !curr->is_survivor()) {
-      log_info(gc, verify)("## %s: encountered NULL surv_rate_group", name);
+      log_error(gc, verify)("## %s: encountered NULL surv_rate_group", name);
       ret = false;
     }
 
@@ -766,12 +843,12 @@
       int age = curr->age_in_surv_rate_group();
 
       if (age < 0) {
-        log_info(gc, verify)("## %s: encountered negative age", name);
+        log_error(gc, verify)("## %s: encountered negative age", name);
         ret = false;
       }
 
       if (age <= prev_age) {
-        log_info(gc, verify)("## %s: region ages are not strictly increasing (%d, %d)", name, age, prev_age);
+        log_error(gc, verify)("## %s: region ages are not strictly increasing (%d, %d)", name, age, prev_age);
         ret = false;
       }
       prev_age = age;
@@ -1601,6 +1678,10 @@
   return young_list_length < young_list_max_length;
 }
 
+bool G1CollectorPolicy::adaptive_young_list_length() const {
+  return _young_gen_sizer->adaptive_young_list_length();
+}
+
 void G1CollectorPolicy::update_max_gc_locker_expansion() {
   uint expansion_region_num = 0;
   if (GCLockerEdenExpansionPercent > 0) {
--- a/hotspot/src/share/vm/gc/g1/g1CollectorPolicy.hpp	Thu Feb 11 13:58:41 2016 -0800
+++ b/hotspot/src/share/vm/gc/g1/g1CollectorPolicy.hpp	Tue Feb 16 12:01:37 2016 -0800
@@ -43,6 +43,7 @@
 class HeapRegion;
 class CollectionSetChooser;
 class G1IHOPControl;
+class G1YoungGenSizer;
 
 // TraceYoungGenTime collects data on _both_ young and mixed evacuation pauses
 // (the latter may contain non-young regions - i.e. regions that are
@@ -90,81 +91,6 @@
   void print() const;
 };
 
-// There are three command line options related to the young gen size:
-// NewSize, MaxNewSize and NewRatio (There is also -Xmn, but that is
-// just a short form for NewSize==MaxNewSize). G1 will use its internal
-// heuristics to calculate the actual young gen size, so these options
-// basically only limit the range within which G1 can pick a young gen
-// size. Also, these are general options taking byte sizes. G1 will
-// internally work with a number of regions instead. So, some rounding
-// will occur.
-//
-// If nothing related to the the young gen size is set on the command
-// line we should allow the young gen to be between G1NewSizePercent
-// and G1MaxNewSizePercent of the heap size. This means that every time
-// the heap size changes, the limits for the young gen size will be
-// recalculated.
-//
-// If only -XX:NewSize is set we should use the specified value as the
-// minimum size for young gen. Still using G1MaxNewSizePercent of the
-// heap as maximum.
-//
-// If only -XX:MaxNewSize is set we should use the specified value as the
-// maximum size for young gen. Still using G1NewSizePercent of the heap
-// as minimum.
-//
-// If -XX:NewSize and -XX:MaxNewSize are both specified we use these values.
-// No updates when the heap size changes. There is a special case when
-// NewSize==MaxNewSize. This is interpreted as "fixed" and will use a
-// different heuristic for calculating the collection set when we do mixed
-// collection.
-//
-// If only -XX:NewRatio is set we should use the specified ratio of the heap
-// as both min and max. This will be interpreted as "fixed" just like the
-// NewSize==MaxNewSize case above. But we will update the min and max
-// every time the heap size changes.
-//
-// NewSize and MaxNewSize override NewRatio. So, NewRatio is ignored if it is
-// combined with either NewSize or MaxNewSize. (A warning message is printed.)
-class G1YoungGenSizer : public CHeapObj<mtGC> {
-private:
-  enum SizerKind {
-    SizerDefaults,
-    SizerNewSizeOnly,
-    SizerMaxNewSizeOnly,
-    SizerMaxAndNewSize,
-    SizerNewRatio
-  };
-  SizerKind _sizer_kind;
-  uint _min_desired_young_length;
-  uint _max_desired_young_length;
-  bool _adaptive_size;
-  uint calculate_default_min_length(uint new_number_of_heap_regions);
-  uint calculate_default_max_length(uint new_number_of_heap_regions);
-
-  // Update the given values for minimum and maximum young gen length in regions
-  // given the number of heap regions depending on the kind of sizing algorithm.
-  void recalculate_min_max_young_length(uint number_of_heap_regions, uint* min_young_length, uint* max_young_length);
-
-public:
-  G1YoungGenSizer();
-  // Calculate the maximum length of the young gen given the number of regions
-  // depending on the sizing algorithm.
-  uint max_young_length(uint number_of_heap_regions);
-
-  void heap_size_changed(uint new_number_of_heap_regions);
-  uint min_desired_young_length() {
-    return _min_desired_young_length;
-  }
-  uint max_desired_young_length() {
-    return _max_desired_young_length;
-  }
-
-  bool adaptive_young_list_length() const {
-    return _adaptive_size;
-  }
-};
-
 class G1CollectorPolicy: public CollectorPolicy {
  private:
   G1IHOPControl* _ihop_control;
@@ -784,9 +710,7 @@
     return _young_list_max_length;
   }
 
-  bool adaptive_young_list_length() const {
-    return _young_gen_sizer->adaptive_young_list_length();
-  }
+  bool adaptive_young_list_length() const;
 
   virtual bool should_process_references() const {
     return true;
--- a/hotspot/src/share/vm/gc/g1/g1ConcurrentMark.cpp	Thu Feb 11 13:58:41 2016 -0800
+++ b/hotspot/src/share/vm/gc/g1/g1ConcurrentMark.cpp	Tue Feb 16 12:01:37 2016 -0800
@@ -372,6 +372,16 @@
   return res;
 }
 
+void G1CMRootRegions::notify_scan_done() {
+  MutexLockerEx x(RootRegionScan_lock, Mutex::_no_safepoint_check_flag);
+  _scan_in_progress = false;
+  RootRegionScan_lock->notify_all();
+}
+
+void G1CMRootRegions::cancel_scan() {
+  notify_scan_done();
+}
+
 void G1CMRootRegions::scan_finished() {
   assert(scan_in_progress(), "pre-condition");
 
@@ -381,11 +391,7 @@
   }
   _next_survivor = NULL;
 
-  {
-    MutexLockerEx x(RootRegionScan_lock, Mutex::_no_safepoint_check_flag);
-    _scan_in_progress = false;
-    RootRegionScan_lock->notify_all();
-  }
+  notify_scan_done();
 }
 
 bool G1CMRootRegions::wait_until_scan_finished() {
@@ -978,13 +984,11 @@
 };
 
 void G1ConcurrentMark::scanRootRegions() {
-  // Start of concurrent marking.
-  ClassLoaderDataGraph::clear_claimed_marks();
-
   // scan_in_progress() will have been set to true only if there was
   // at least one root region to scan. So, if it's false, we
   // should not attempt to do any further work.
   if (root_regions()->scan_in_progress()) {
+    assert(!has_aborted(), "Aborting before root region scanning is finished not supported.");
     GCTraceConcTime(Info, gc) tt("Concurrent Root Region Scan");
 
     _parallel_marking_threads = calc_parallel_marking_threads();
--- a/hotspot/src/share/vm/gc/g1/g1ConcurrentMark.hpp	Thu Feb 11 13:58:41 2016 -0800
+++ b/hotspot/src/share/vm/gc/g1/g1ConcurrentMark.hpp	Tue Feb 16 12:01:37 2016 -0800
@@ -229,6 +229,8 @@
   volatile bool        _should_abort;
   HeapRegion* volatile _next_survivor;
 
+  void notify_scan_done();
+
 public:
   G1CMRootRegions();
   // We actually do most of the initialization in this method.
@@ -248,6 +250,8 @@
   // all have been claimed.
   HeapRegion* claim_next();
 
+  void cancel_scan();
+
   // Flag that we're done with root region scanning and notify anyone
   // who's waiting on it. If aborted is false, assume that all regions
   // have been claimed.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/gc/g1/g1HeapRegionTraceType.hpp	Tue Feb 16 12:01:37 2016 -0800
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2016, 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_GC_G1_G1HEAPREGIONTRACETYPE_HPP
+#define SHARE_VM_GC_G1_G1HEAPREGIONTRACETYPE_HPP
+
+#include "memory/allocation.hpp"
+#include "utilities/debug.hpp"
+
+class G1HeapRegionTraceType : AllStatic {
+ public:
+  enum Type {
+    Free,
+    Eden,
+    Survivor,
+    StartsHumongous,
+    ContinuesHumongous,
+    Old,
+    Archive,
+    G1HeapRegionTypeEndSentinel
+  };
+
+  static const char* to_string(G1HeapRegionTraceType::Type type) {
+    switch (type) {
+      case Free:               return "Free";
+      case Eden:               return "Eden";
+      case Survivor:           return "Survivor";
+      case StartsHumongous:    return "Starts Humongous";
+      case ContinuesHumongous: return "Continues Humongous";
+      case Old:                return "Old";
+      case Archive:            return "Archive";
+      default: ShouldNotReachHere(); return NULL;
+    }
+  }
+};
+
+#endif // SHARE_VM_GC_G1_G1HEAPREGIONTRACETYPE_HPP
--- a/hotspot/src/share/vm/gc/g1/g1HeapVerifier.cpp	Thu Feb 11 13:58:41 2016 -0800
+++ b/hotspot/src/share/vm/gc/g1/g1HeapVerifier.cpp	Tue Feb 16 12:01:37 2016 -0800
@@ -63,10 +63,10 @@
         LogHandle(gc, verify) log;
         log.info("Root location " PTR_FORMAT " points to dead obj " PTR_FORMAT, p2i(p), p2i(obj));
         if (_vo == VerifyOption_G1UseMarkWord) {
-          log.info("  Mark word: " PTR_FORMAT, p2i(obj->mark()));
+          log.error("  Mark word: " PTR_FORMAT, p2i(obj->mark()));
         }
         ResourceMark rm;
-        obj->print_on(log.info_stream());
+        obj->print_on(log.error_stream());
         _failures = true;
       }
     }
@@ -111,10 +111,10 @@
       // Verify that the strong code root list for this region
       // contains the nmethod
       if (!hrrs->strong_code_roots_list_contains(_nm)) {
-        log_info(gc, verify)("Code root location " PTR_FORMAT " "
-                             "from nmethod " PTR_FORMAT " not in strong "
-                             "code roots for region [" PTR_FORMAT "," PTR_FORMAT ")",
-                             p2i(p), p2i(_nm), p2i(hr->bottom()), p2i(hr->end()));
+        log_error(gc, verify)("Code root location " PTR_FORMAT " "
+                              "from nmethod " PTR_FORMAT " not in strong "
+                              "code roots for region [" PTR_FORMAT "," PTR_FORMAT ")",
+                              p2i(p), p2i(_nm), p2i(hr->bottom()), p2i(hr->end()));
         _failures = true;
       }
     }
@@ -292,8 +292,8 @@
         r->object_iterate(&not_dead_yet_cl);
         if (_vo != VerifyOption_G1UseNextMarking) {
           if (r->max_live_bytes() < not_dead_yet_cl.live_bytes()) {
-            log_info(gc, verify)("[" PTR_FORMAT "," PTR_FORMAT "] max_live_bytes " SIZE_FORMAT " < calculated " SIZE_FORMAT,
-                                 p2i(r->bottom()), p2i(r->end()), r->max_live_bytes(), not_dead_yet_cl.live_bytes());
+            log_error(gc, verify)("[" PTR_FORMAT "," PTR_FORMAT "] max_live_bytes " SIZE_FORMAT " < calculated " SIZE_FORMAT,
+                                  p2i(r->bottom()), p2i(r->end()), r->max_live_bytes(), not_dead_yet_cl.live_bytes());
             _failures = true;
           }
         } else {
@@ -402,13 +402,13 @@
   }
 
   if (failures) {
-    log_info(gc, verify)("Heap after failed verification:");
+    log_error(gc, verify)("Heap after failed verification:");
     // It helps to have the per-region information in the output to
     // help us track down what went wrong. This is why we call
     // print_extended_on() instead of print_on().
     LogHandle(gc, verify) log;
     ResourceMark rm;
-    _g1h->print_extended_on(log.info_stream());
+    _g1h->print_extended_on(log.error_stream());
   }
   guarantee(!failures, "there should not have been any failures");
 }
@@ -597,8 +597,8 @@
             "tams: " PTR_FORMAT " end: " PTR_FORMAT, p2i(tams), p2i(end));
   HeapWord* result = bitmap->getNextMarkedWordAddress(tams, end);
   if (result < end) {
-    log_info(gc, verify)("## wrong marked address on %s bitmap: " PTR_FORMAT, bitmap_name, p2i(result));
-    log_info(gc, verify)("## %s tams: " PTR_FORMAT " end: " PTR_FORMAT, bitmap_name, p2i(tams), p2i(end));
+    log_error(gc, verify)("## wrong marked address on %s bitmap: " PTR_FORMAT, bitmap_name, p2i(result));
+    log_error(gc, verify)("## %s tams: " PTR_FORMAT " end: " PTR_FORMAT, bitmap_name, p2i(tams), p2i(end));
     return false;
   }
   return true;
@@ -623,8 +623,8 @@
     res_n = verify_no_bits_over_tams("next", next_bitmap, ntams, end);
   }
   if (!res_p || !res_n) {
-    log_info(gc, verify)("#### Bitmap verification failed for " HR_FORMAT, HR_FORMAT_PARAMS(hr));
-    log_info(gc, verify)("#### Caller: %s", caller);
+    log_error(gc, verify)("#### Bitmap verification failed for " HR_FORMAT, HR_FORMAT_PARAMS(hr));
+    log_error(gc, verify)("#### Caller: %s", caller);
     return false;
   }
   return true;
@@ -676,41 +676,41 @@
     InCSetState cset_state = (InCSetState) G1CollectedHeap::heap()->_in_cset_fast_test.get_by_index(i);
     if (hr->is_humongous()) {
       if (hr->in_collection_set()) {
-        log_info(gc, verify)("## humongous region %u in CSet", i);
+        log_error(gc, verify)("## humongous region %u in CSet", i);
         _failures = true;
         return true;
       }
       if (cset_state.is_in_cset()) {
-        log_info(gc, verify)("## inconsistent cset state " CSETSTATE_FORMAT " for humongous region %u", cset_state.value(), i);
+        log_error(gc, verify)("## inconsistent cset state " CSETSTATE_FORMAT " for humongous region %u", cset_state.value(), i);
         _failures = true;
         return true;
       }
       if (hr->is_continues_humongous() && cset_state.is_humongous()) {
-        log_info(gc, verify)("## inconsistent cset state " CSETSTATE_FORMAT " for continues humongous region %u", cset_state.value(), i);
+        log_error(gc, verify)("## inconsistent cset state " CSETSTATE_FORMAT " for continues humongous region %u", cset_state.value(), i);
         _failures = true;
         return true;
       }
     } else {
       if (cset_state.is_humongous()) {
-        log_info(gc, verify)("## inconsistent cset state " CSETSTATE_FORMAT " for non-humongous region %u", cset_state.value(), i);
+        log_error(gc, verify)("## inconsistent cset state " CSETSTATE_FORMAT " for non-humongous region %u", cset_state.value(), i);
         _failures = true;
         return true;
       }
       if (hr->in_collection_set() != cset_state.is_in_cset()) {
-        log_info(gc, verify)("## in CSet %d / cset state " CSETSTATE_FORMAT " inconsistency for region %u",
+        log_error(gc, verify)("## in CSet %d / cset state " CSETSTATE_FORMAT " inconsistency for region %u",
                              hr->in_collection_set(), cset_state.value(), i);
         _failures = true;
         return true;
       }
       if (cset_state.is_in_cset()) {
         if (hr->is_young() != (cset_state.is_young())) {
-          log_info(gc, verify)("## is_young %d / cset state " CSETSTATE_FORMAT " inconsistency for region %u",
+          log_error(gc, verify)("## is_young %d / cset state " CSETSTATE_FORMAT " inconsistency for region %u",
                                hr->is_young(), cset_state.value(), i);
           _failures = true;
           return true;
         }
         if (hr->is_old() != (cset_state.is_old())) {
-          log_info(gc, verify)("## is_old %d / cset state " CSETSTATE_FORMAT " inconsistency for region %u",
+          log_error(gc, verify)("## is_old %d / cset state " CSETSTATE_FORMAT " inconsistency for region %u",
                                hr->is_old(), cset_state.value(), i);
           _failures = true;
           return true;
--- a/hotspot/src/share/vm/gc/g1/heapRegion.cpp	Thu Feb 11 13:58:41 2016 -0800
+++ b/hotspot/src/share/vm/gc/g1/heapRegion.cpp	Tue Feb 16 12:01:37 2016 -0800
@@ -26,11 +26,13 @@
 #include "code/nmethod.hpp"
 #include "gc/g1/g1BlockOffsetTable.inline.hpp"
 #include "gc/g1/g1CollectedHeap.inline.hpp"
+#include "gc/g1/g1HeapRegionTraceType.hpp"
 #include "gc/g1/g1OopClosures.inline.hpp"
 #include "gc/g1/heapRegion.inline.hpp"
 #include "gc/g1/heapRegionBounds.inline.hpp"
 #include "gc/g1/heapRegionManager.inline.hpp"
 #include "gc/g1/heapRegionRemSet.hpp"
+#include "gc/g1/heapRegionTracer.hpp"
 #include "gc/shared/genOopClosures.inline.hpp"
 #include "gc/shared/liveRange.hpp"
 #include "gc/shared/space.inline.hpp"
@@ -212,10 +214,41 @@
   _gc_efficiency = (double) reclaimable_bytes() / region_elapsed_time_ms;
 }
 
+void HeapRegion::set_free() {
+  report_region_type_change(G1HeapRegionTraceType::Free);
+  _type.set_free();
+}
+
+void HeapRegion::set_eden() {
+  report_region_type_change(G1HeapRegionTraceType::Eden);
+  _type.set_eden();
+}
+
+void HeapRegion::set_eden_pre_gc() {
+  report_region_type_change(G1HeapRegionTraceType::Eden);
+  _type.set_eden_pre_gc();
+}
+
+void HeapRegion::set_survivor() {
+  report_region_type_change(G1HeapRegionTraceType::Survivor);
+  _type.set_survivor();
+}
+
+void HeapRegion::set_old() {
+  report_region_type_change(G1HeapRegionTraceType::Old);
+  _type.set_old();
+}
+
+void HeapRegion::set_archive() {
+  report_region_type_change(G1HeapRegionTraceType::Archive);
+  _type.set_archive();
+}
+
 void HeapRegion::set_starts_humongous(HeapWord* obj_top, size_t fill_size) {
   assert(!is_humongous(), "sanity / pre-condition");
   assert(top() == bottom(), "should be empty");
 
+  report_region_type_change(G1HeapRegionTraceType::StartsHumongous);
   _type.set_starts_humongous();
   _humongous_start_region = this;
 
@@ -227,6 +260,7 @@
   assert(top() == bottom(), "should be empty");
   assert(first_hr->is_starts_humongous(), "pre-condition");
 
+  report_region_type_change(G1HeapRegionTraceType::ContinuesHumongous);
   _type.set_continues_humongous();
   _humongous_start_region = first_hr;
 }
@@ -272,6 +306,15 @@
   record_timestamp();
 }
 
+void HeapRegion::report_region_type_change(G1HeapRegionTraceType::Type to) {
+  HeapRegionTracer::send_region_type_change(_hrm_index,
+                                            get_trace_type(),
+                                            to,
+                                            (uintptr_t)bottom(),
+                                            used(),
+                                            (uint)allocation_context());
+}
+
 CompactibleSpace* HeapRegion::next_compaction_space() const {
   return G1CollectedHeap::heap()->next_compaction_region(this);
 }
@@ -479,7 +522,7 @@
         // Object is in the region. Check that its less than top
         if (_hr->top() <= (HeapWord*)obj) {
           // Object is above top
-          log_info(gc, verify)("Object " PTR_FORMAT " in region [" PTR_FORMAT ", " PTR_FORMAT ") is above top " PTR_FORMAT,
+          log_error(gc, verify)("Object " PTR_FORMAT " in region [" PTR_FORMAT ", " PTR_FORMAT ") is above top " PTR_FORMAT,
                                p2i(obj), p2i(_hr->bottom()), p2i(_hr->end()), p2i(_hr->top()));
           _failures = true;
           return;
@@ -513,19 +556,19 @@
     if (nm != NULL) {
       // Verify that the nemthod is live
       if (!nm->is_alive()) {
-        log_info(gc, verify)("region [" PTR_FORMAT "," PTR_FORMAT "] has dead nmethod " PTR_FORMAT " in its strong code roots",
-                             p2i(_hr->bottom()), p2i(_hr->end()), p2i(nm));
+        log_error(gc, verify)("region [" PTR_FORMAT "," PTR_FORMAT "] has dead nmethod " PTR_FORMAT " in its strong code roots",
+                              p2i(_hr->bottom()), p2i(_hr->end()), p2i(nm));
         _failures = true;
       } else {
         VerifyStrongCodeRootOopClosure oop_cl(_hr, nm);
         nm->oops_do(&oop_cl);
         if (!oop_cl.has_oops_in_region()) {
-          log_info(gc, verify)("region [" PTR_FORMAT "," PTR_FORMAT "] has nmethod " PTR_FORMAT " in its strong code roots with no pointers into region",
-                               p2i(_hr->bottom()), p2i(_hr->end()), p2i(nm));
+          log_error(gc, verify)("region [" PTR_FORMAT "," PTR_FORMAT "] has nmethod " PTR_FORMAT " in its strong code roots with no pointers into region",
+                                p2i(_hr->bottom()), p2i(_hr->end()), p2i(nm));
           _failures = true;
         } else if (oop_cl.failures()) {
-          log_info(gc, verify)("region [" PTR_FORMAT "," PTR_FORMAT "] has other failures for nmethod " PTR_FORMAT,
-                               p2i(_hr->bottom()), p2i(_hr->end()), p2i(nm));
+          log_error(gc, verify)("region [" PTR_FORMAT "," PTR_FORMAT "] has other failures for nmethod " PTR_FORMAT,
+                                p2i(_hr->bottom()), p2i(_hr->end()), p2i(nm));
           _failures = true;
         }
       }
@@ -558,8 +601,8 @@
   // on its strong code root list
   if (is_empty()) {
     if (strong_code_roots_length > 0) {
-      log_info(gc, verify)("region [" PTR_FORMAT "," PTR_FORMAT "] is empty but has " SIZE_FORMAT " code root entries",
-                           p2i(bottom()), p2i(end()), strong_code_roots_length);
+      log_error(gc, verify)("region [" PTR_FORMAT "," PTR_FORMAT "] is empty but has " SIZE_FORMAT " code root entries",
+                            p2i(bottom()), p2i(end()), strong_code_roots_length);
       *failures = true;
     }
     return;
@@ -567,8 +610,8 @@
 
   if (is_continues_humongous()) {
     if (strong_code_roots_length > 0) {
-      log_info(gc, verify)("region " HR_FORMAT " is a continuation of a humongous region but has " SIZE_FORMAT " code root entries",
-                           HR_FORMAT_PARAMS(this), strong_code_roots_length);
+      log_error(gc, verify)("region " HR_FORMAT " is a continuation of a humongous region but has " SIZE_FORMAT " code root entries",
+                            HR_FORMAT_PARAMS(this), strong_code_roots_length);
       *failures = true;
     }
     return;
@@ -661,26 +704,26 @@
           Mutex::_no_safepoint_check_flag);
 
         if (!_failures) {
-          log.info("----------");
+          log.error("----------");
         }
         ResourceMark rm;
         if (!_g1h->is_in_closed_subset(obj)) {
           HeapRegion* from = _g1h->heap_region_containing((HeapWord*)p);
-          log.info("Field " PTR_FORMAT " of live obj " PTR_FORMAT " in region [" PTR_FORMAT ", " PTR_FORMAT ")",
+          log.error("Field " PTR_FORMAT " of live obj " PTR_FORMAT " in region [" PTR_FORMAT ", " PTR_FORMAT ")",
             p2i(p), p2i(_containing_obj), p2i(from->bottom()), p2i(from->end()));
-          print_object(log.info_stream(), _containing_obj);
-          log.info("points to obj " PTR_FORMAT " not in the heap", p2i(obj));
+          print_object(log.error_stream(), _containing_obj);
+          log.error("points to obj " PTR_FORMAT " not in the heap", p2i(obj));
         } else {
           HeapRegion* from = _g1h->heap_region_containing((HeapWord*)p);
           HeapRegion* to = _g1h->heap_region_containing((HeapWord*)obj);
-          log.info("Field " PTR_FORMAT " of live obj " PTR_FORMAT " in region [" PTR_FORMAT ", " PTR_FORMAT ")",
+          log.error("Field " PTR_FORMAT " of live obj " PTR_FORMAT " in region [" PTR_FORMAT ", " PTR_FORMAT ")",
             p2i(p), p2i(_containing_obj), p2i(from->bottom()), p2i(from->end()));
-          print_object(log.info_stream(), _containing_obj);
-          log.info("points to dead obj " PTR_FORMAT " in region [" PTR_FORMAT ", " PTR_FORMAT ")",
+          print_object(log.error_stream(), _containing_obj);
+          log.error("points to dead obj " PTR_FORMAT " in region [" PTR_FORMAT ", " PTR_FORMAT ")",
             p2i(obj), p2i(to->bottom()), p2i(to->end()));
-          print_object(log.info_stream(), obj);
+          print_object(log.error_stream(), obj);
         }
-        log.info("----------");
+        log.error("----------");
         _failures = true;
         failed = true;
         _n_failures++;
@@ -730,17 +773,17 @@
             Mutex::_no_safepoint_check_flag);
 
           if (!_failures) {
-            log.info("----------");
+            log.error("----------");
           }
-          log.info("Missing rem set entry:");
-          log.info("Field " PTR_FORMAT " of obj " PTR_FORMAT ", in region " HR_FORMAT,
+          log.error("Missing rem set entry:");
+          log.error("Field " PTR_FORMAT " of obj " PTR_FORMAT ", in region " HR_FORMAT,
             p2i(p), p2i(_containing_obj), HR_FORMAT_PARAMS(from));
           ResourceMark rm;
-          _containing_obj->print_on(log.info_stream());
-          log.info("points to obj " PTR_FORMAT " in region " HR_FORMAT, p2i(obj), HR_FORMAT_PARAMS(to));
-          obj->print_on(log.info_stream());
-          log.info("Obj head CTE = %d, field CTE = %d.", cv_obj, cv_field);
-          log.info("----------");
+          _containing_obj->print_on(log.error_stream());
+          log.error("points to obj " PTR_FORMAT " in region " HR_FORMAT, p2i(obj), HR_FORMAT_PARAMS(to));
+          obj->print_on(log.error_stream());
+          log.error("Obj head CTE = %d, field CTE = %d.", cv_obj, cv_field);
+          log.error("----------");
           _failures = true;
           if (!failed) _n_failures++;
         }
@@ -774,13 +817,13 @@
                                    (vo == VerifyOption_G1UsePrevMarking &&
                                    ClassLoaderDataGraph::unload_list_contains(klass));
         if (!is_metaspace_object) {
-          log_info(gc, verify)("klass " PTR_FORMAT " of object " PTR_FORMAT " "
-                               "not metadata", p2i(klass), p2i(obj));
+          log_error(gc, verify)("klass " PTR_FORMAT " of object " PTR_FORMAT " "
+                                "not metadata", p2i(klass), p2i(obj));
           *failures = true;
           return;
         } else if (!klass->is_klass()) {
-          log_info(gc, verify)("klass " PTR_FORMAT " of object " PTR_FORMAT " "
-                               "not a klass", p2i(klass), p2i(obj));
+          log_error(gc, verify)("klass " PTR_FORMAT " of object " PTR_FORMAT " "
+                                "not a klass", p2i(klass), p2i(obj));
           *failures = true;
           return;
         } else {
@@ -811,7 +854,7 @@
           }
         }
       } else {
-        log_info(gc, verify)(PTR_FORMAT " not an oop", p2i(obj));
+        log_error(gc, verify)(PTR_FORMAT " not an oop", p2i(obj));
         *failures = true;
         return;
       }
@@ -827,13 +870,15 @@
   if (is_region_humongous) {
     oop obj = oop(this->humongous_start_region()->bottom());
     if ((HeapWord*)obj > bottom() || (HeapWord*)obj + obj->size() < bottom()) {
-      log_info(gc, verify)("this humongous region is not part of its' humongous object " PTR_FORMAT, p2i(obj));
+      log_error(gc, verify)("this humongous region is not part of its' humongous object " PTR_FORMAT, p2i(obj));
+      *failures = true;
+      return;
     }
   }
 
   if (!is_region_humongous && p != top()) {
-    log_info(gc, verify)("end of last object " PTR_FORMAT " "
-                         "does not match top " PTR_FORMAT, p2i(p), p2i(top()));
+    log_error(gc, verify)("end of last object " PTR_FORMAT " "
+                          "does not match top " PTR_FORMAT, p2i(p), p2i(top()));
     *failures = true;
     return;
   }
@@ -847,9 +892,9 @@
     HeapWord* addr_1 = p;
     HeapWord* b_start_1 = _bot_part.block_start_const(addr_1);
     if (b_start_1 != p) {
-      log_info(gc, verify)("BOT look up for top: " PTR_FORMAT " "
-                           " yielded " PTR_FORMAT ", expecting " PTR_FORMAT,
-                           p2i(addr_1), p2i(b_start_1), p2i(p));
+      log_error(gc, verify)("BOT look up for top: " PTR_FORMAT " "
+                            " yielded " PTR_FORMAT ", expecting " PTR_FORMAT,
+                            p2i(addr_1), p2i(b_start_1), p2i(p));
       *failures = true;
       return;
     }
@@ -859,9 +904,9 @@
     if (addr_2 < the_end) {
       HeapWord* b_start_2 = _bot_part.block_start_const(addr_2);
       if (b_start_2 != p) {
-        log_info(gc, verify)("BOT look up for top + 1: " PTR_FORMAT " "
-                             " yielded " PTR_FORMAT ", expecting " PTR_FORMAT,
-                             p2i(addr_2), p2i(b_start_2), p2i(p));
+        log_error(gc, verify)("BOT look up for top + 1: " PTR_FORMAT " "
+                              " yielded " PTR_FORMAT ", expecting " PTR_FORMAT,
+                              p2i(addr_2), p2i(b_start_2), p2i(p));
         *failures = true;
         return;
       }
@@ -873,9 +918,9 @@
     if (addr_3 < the_end) {
       HeapWord* b_start_3 = _bot_part.block_start_const(addr_3);
       if (b_start_3 != p) {
-        log_info(gc, verify)("BOT look up for top + diff: " PTR_FORMAT " "
-                             " yielded " PTR_FORMAT ", expecting " PTR_FORMAT,
-                             p2i(addr_3), p2i(b_start_3), p2i(p));
+        log_error(gc, verify)("BOT look up for top + diff: " PTR_FORMAT " "
+                              " yielded " PTR_FORMAT ", expecting " PTR_FORMAT,
+                              p2i(addr_3), p2i(b_start_3), p2i(p));
         *failures = true;
         return;
       }
@@ -885,9 +930,9 @@
     HeapWord* addr_4 = the_end - 1;
     HeapWord* b_start_4 = _bot_part.block_start_const(addr_4);
     if (b_start_4 != p) {
-      log_info(gc, verify)("BOT look up for end - 1: " PTR_FORMAT " "
-                           " yielded " PTR_FORMAT ", expecting " PTR_FORMAT,
-                           p2i(addr_4), p2i(b_start_4), p2i(p));
+      log_error(gc, verify)("BOT look up for end - 1: " PTR_FORMAT " "
+                            " yielded " PTR_FORMAT ", expecting " PTR_FORMAT,
+                            p2i(addr_4), p2i(b_start_4), p2i(p));
       *failures = true;
       return;
     }
@@ -924,7 +969,7 @@
           return;
         }
       } else {
-        log_info(gc, verify)(PTR_FORMAT " not an oop", p2i(obj));
+        log_error(gc, verify)(PTR_FORMAT " not an oop", p2i(obj));
         *failures = true;
         return;
       }
--- a/hotspot/src/share/vm/gc/g1/heapRegion.hpp	Thu Feb 11 13:58:41 2016 -0800
+++ b/hotspot/src/share/vm/gc/g1/heapRegion.hpp	Tue Feb 16 12:01:37 2016 -0800
@@ -27,6 +27,8 @@
 
 #include "gc/g1/g1AllocationContext.hpp"
 #include "gc/g1/g1BlockOffsetTable.hpp"
+#include "gc/g1/g1HeapRegionTraceType.hpp"
+#include "gc/g1/heapRegionTracer.hpp"
 #include "gc/g1/heapRegionType.hpp"
 #include "gc/g1/survRateGroup.hpp"
 #include "gc/shared/ageTable.hpp"
@@ -243,6 +245,8 @@
     return HeapRegion::block_size(addr); // Avoid virtual call
   }
 
+  void report_region_type_change(G1HeapRegionTraceType::Type to);
+
  protected:
   // The index of this region in the heap region sequence.
   uint  _hrm_index;
@@ -427,6 +431,7 @@
 
   const char* get_type_str() const { return _type.get_str(); }
   const char* get_short_type_str() const { return _type.get_short_str(); }
+  G1HeapRegionTraceType::Type get_trace_type() { return _type.get_trace_type(); }
 
   bool is_free() const { return _type.is_free(); }
 
@@ -637,15 +642,15 @@
     }
   }
 
-  void set_free() { _type.set_free(); }
+  void set_free();
 
-  void set_eden()        { _type.set_eden();        }
-  void set_eden_pre_gc() { _type.set_eden_pre_gc(); }
-  void set_survivor()    { _type.set_survivor();    }
+  void set_eden();
+  void set_eden_pre_gc();
+  void set_survivor();
 
-  void set_old() { _type.set_old(); }
+  void set_old();
 
-  void set_archive() { _type.set_archive(); }
+  void set_archive();
 
   // Determine if an object has been allocated since the last
   // mark performed by the collector. This returns true iff the object
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/gc/g1/heapRegionTracer.cpp	Tue Feb 16 12:01:37 2016 -0800
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2013, 2015, 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/g1/heapRegionTracer.hpp"
+#include "trace/tracing.hpp"
+
+void HeapRegionTracer::send_region_type_change(uint index,
+                                               G1HeapRegionTraceType::Type from,
+                                               G1HeapRegionTraceType::Type to,
+                                               uintptr_t start,
+                                               size_t used,
+                                               uint allocationContext) {
+  EventG1HeapRegionTypeChange e;
+  if (e.should_commit()) {
+    e.set_index(index);
+    e.set_from(from);
+    e.set_to(to);
+    e.set_start(start);
+    e.set_used(used);
+    e.set_allocContext(allocationContext);
+    e.commit();
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/gc/g1/heapRegionTracer.hpp	Tue Feb 16 12:01:37 2016 -0800
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2016, 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_GC_G1_HEAPREGIONTRACER_HPP
+#define SHARE_VM_GC_G1_HEAPREGIONTRACER_HPP
+
+#include "gc/g1/g1HeapRegionTraceType.hpp"
+#include "memory/allocation.hpp"
+
+class HeapRegionTracer : AllStatic {
+  public:
+    static void send_region_type_change(uint index,
+                                        G1HeapRegionTraceType::Type from,
+                                        G1HeapRegionTraceType::Type to,
+                                        uintptr_t start,
+                                        size_t used,
+                                        uint allocationContext);
+};
+
+#endif // SHARE_VM_GC_G1_HEAPREGIONTRACER_HPP
--- a/hotspot/src/share/vm/gc/g1/heapRegionType.cpp	Thu Feb 11 13:58:41 2016 -0800
+++ b/hotspot/src/share/vm/gc/g1/heapRegionType.cpp	Tue Feb 16 12:01:37 2016 -0800
@@ -23,6 +23,7 @@
  */
 
 #include "precompiled.hpp"
+#include "gc/g1/g1HeapRegionTraceType.hpp"
 #include "gc/g1/heapRegionType.hpp"
 
 bool HeapRegionType::is_valid(Tag tag) {
@@ -70,3 +71,19 @@
   // keep some compilers happy
   return NULL;
 }
+
+G1HeapRegionTraceType::Type HeapRegionType::get_trace_type() {
+  hrt_assert_is_valid(_tag);
+  switch (_tag) {
+    case FreeTag:               return G1HeapRegionTraceType::Free;
+    case EdenTag:               return G1HeapRegionTraceType::Eden;
+    case SurvTag:               return G1HeapRegionTraceType::Survivor;
+    case StartsHumongousTag:    return G1HeapRegionTraceType::StartsHumongous;
+    case ContinuesHumongousTag: return G1HeapRegionTraceType::ContinuesHumongous;
+    case OldTag:                return G1HeapRegionTraceType::Old;
+    case ArchiveTag:            return G1HeapRegionTraceType::Archive;
+  }
+  ShouldNotReachHere();
+  // keep some compilers happy
+  return G1HeapRegionTraceType::Free;
+}
--- a/hotspot/src/share/vm/gc/g1/heapRegionType.hpp	Thu Feb 11 13:58:41 2016 -0800
+++ b/hotspot/src/share/vm/gc/g1/heapRegionType.hpp	Tue Feb 16 12:01:37 2016 -0800
@@ -25,6 +25,7 @@
 #ifndef SHARE_VM_GC_G1_HEAPREGIONTYPE_HPP
 #define SHARE_VM_GC_G1_HEAPREGIONTYPE_HPP
 
+#include "gc/g1/g1HeapRegionTraceType.hpp"
 #include "memory/allocation.hpp"
 
 #define hrt_assert_is_valid(tag) \
@@ -141,6 +142,7 @@
 
   const char* get_str() const;
   const char* get_short_str() const;
+  G1HeapRegionTraceType::Type get_trace_type();
 
   HeapRegionType() : _tag(FreeTag) { hrt_assert_is_valid(_tag); }
 };
--- a/hotspot/src/share/vm/gc/g1/satbMarkQueue.cpp	Thu Feb 11 13:58:41 2016 -0800
+++ b/hotspot/src/share/vm/gc/g1/satbMarkQueue.cpp	Tue Feb 16 12:01:37 2016 -0800
@@ -221,13 +221,13 @@
 
 #ifdef ASSERT
 void SATBMarkQueueSet::dump_active_states(bool expected_active) {
-  log_info(gc, verify)("Expected SATB active state: %s", expected_active ? "ACTIVE" : "INACTIVE");
-  log_info(gc, verify)("Actual SATB active states:");
-  log_info(gc, verify)("  Queue set: %s", is_active() ? "ACTIVE" : "INACTIVE");
+  log_error(gc, verify)("Expected SATB active state: %s", expected_active ? "ACTIVE" : "INACTIVE");
+  log_error(gc, verify)("Actual SATB active states:");
+  log_error(gc, verify)("  Queue set: %s", is_active() ? "ACTIVE" : "INACTIVE");
   for (JavaThread* t = Threads::first(); t; t = t->next()) {
-    log_info(gc, verify)("  Thread \"%s\" queue: %s", t->name(), t->satb_mark_queue().is_active() ? "ACTIVE" : "INACTIVE");
+    log_error(gc, verify)("  Thread \"%s\" queue: %s", t->name(), t->satb_mark_queue().is_active() ? "ACTIVE" : "INACTIVE");
   }
-  log_info(gc, verify)("  Shared queue: %s", shared_satb_queue()->is_active() ? "ACTIVE" : "INACTIVE");
+  log_error(gc, verify)("  Shared queue: %s", shared_satb_queue()->is_active() ? "ACTIVE" : "INACTIVE");
 }
 
 void SATBMarkQueueSet::verify_active_states(bool expected_active) {
--- a/hotspot/src/share/vm/gc/g1/youngList.cpp	Thu Feb 11 13:58:41 2016 -0800
+++ b/hotspot/src/share/vm/gc/g1/youngList.cpp	Tue Feb 16 12:01:37 2016 -0800
@@ -99,10 +99,10 @@
   HeapRegion* last = NULL;
   while (curr != NULL) {
     if (!curr->is_young()) {
-      log_info(gc, verify)("### YOUNG REGION " PTR_FORMAT "-" PTR_FORMAT " "
-                           "incorrectly tagged (y: %d, surv: %d)",
-                           p2i(curr->bottom()), p2i(curr->end()),
-                           curr->is_young(), curr->is_survivor());
+      log_error(gc, verify)("### YOUNG REGION " PTR_FORMAT "-" PTR_FORMAT " "
+                            "incorrectly tagged (y: %d, surv: %d)",
+                            p2i(curr->bottom()), p2i(curr->end()),
+                            curr->is_young(), curr->is_survivor());
       ret = false;
     }
     ++length;
@@ -112,8 +112,8 @@
   ret = ret && (length == _length);
 
   if (!ret) {
-    log_info(gc, verify)("### YOUNG LIST seems not well formed!");
-    log_info(gc, verify)("###   list has %u entries, _length is %u", length, _length);
+    log_error(gc, verify)("### YOUNG LIST seems not well formed!");
+    log_error(gc, verify)("###   list has %u entries, _length is %u", length, _length);
   }
 
   return ret;
@@ -123,19 +123,19 @@
   bool ret = true;
 
   if (_length != 0) {
-    log_info(gc, verify)("### YOUNG LIST should have 0 length, not %u", _length);
+    log_error(gc, verify)("### YOUNG LIST should have 0 length, not %u", _length);
     ret = false;
   }
   if (check_sample && _last_sampled_rs_lengths != 0) {
-    log_info(gc, verify)("### YOUNG LIST has non-zero last sampled RS lengths");
+    log_error(gc, verify)("### YOUNG LIST has non-zero last sampled RS lengths");
     ret = false;
   }
   if (_head != NULL) {
-    log_info(gc, verify)("### YOUNG LIST does not have a NULL head");
+    log_error(gc, verify)("### YOUNG LIST does not have a NULL head");
     ret = false;
   }
   if (!ret) {
-    log_info(gc, verify)("### YOUNG LIST does not seem empty");
+    log_error(gc, verify)("### YOUNG LIST does not seem empty");
   }
 
   return ret;
--- a/hotspot/src/share/vm/gc/shared/ageTable.cpp	Thu Feb 11 13:58:41 2016 -0800
+++ b/hotspot/src/share/vm/gc/shared/ageTable.cpp	Tue Feb 16 12:01:37 2016 -0800
@@ -24,6 +24,7 @@
 
 #include "precompiled.hpp"
 #include "gc/shared/ageTable.inline.hpp"
+#include "gc/shared/ageTableTracer.hpp"
 #include "gc/shared/collectedHeap.hpp"
 #include "gc/shared/collectorPolicy.hpp"
 #include "gc/shared/gcPolicyCounters.hpp"
@@ -100,17 +101,19 @@
   log_debug(gc, age)("Desired survivor size " SIZE_FORMAT " bytes, new threshold " UINTX_FORMAT " (max threshold " UINTX_FORMAT ")",
                      desired_survivor_size*oopSize, (uintx) result, MaxTenuringThreshold);
 
-  if (log_is_enabled(Trace, gc, age) || UsePerfData) {
+  if (log_is_enabled(Trace, gc, age) || UsePerfData || AgeTableTracer::is_tenuring_distribution_event_enabled()) {
     size_t total = 0;
     uint age = 1;
     while (age < table_size) {
-      total += sizes[age];
-      if (sizes[age] > 0) {
+      size_t wordSize = sizes[age];
+      total += wordSize;
+      if (wordSize > 0) {
         log_trace(gc, age)("- age %3u: " SIZE_FORMAT_W(10) " bytes, " SIZE_FORMAT_W(10) " total",
-                            age, sizes[age]*oopSize, total*oopSize);
+                            age, wordSize*oopSize, total*oopSize);
       }
+      AgeTableTracer::send_tenuring_distribution_event(age, wordSize*oopSize);
       if (UsePerfData) {
-        _perf_sizes[age]->set_value(sizes[age]*oopSize);
+        _perf_sizes[age]->set_value(wordSize*oopSize);
       }
       age++;
     }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/gc/shared/ageTableTracer.cpp	Tue Feb 16 12:01:37 2016 -0800
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2016, 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/shared/ageTableTracer.hpp"
+#include "gc/shared/gcId.hpp"
+#include "trace/tracing.hpp"
+
+void AgeTableTracer::send_tenuring_distribution_event(uint age, size_t size) {
+  EventTenuringDistribution e;
+  if (e.should_commit()) {
+    e.set_gcId(GCId::current());
+    e.set_age(age);
+    e.set_size(size);
+    e.commit();
+  }
+}
+
+bool AgeTableTracer::is_tenuring_distribution_event_enabled() {
+  return EventTenuringDistribution::is_enabled();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/gc/shared/ageTableTracer.hpp	Tue Feb 16 12:01:37 2016 -0800
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2016, 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_GC_SHARED_AGETABLETRACER_HPP
+#define SHARE_VM_GC_SHARED_AGETABLETRACER_HPP
+
+#include "memory/allocation.hpp"
+
+class AgeTableTracer : AllStatic {
+  public:
+    static void send_tenuring_distribution_event(uint age, size_t size);
+    static bool is_tenuring_distribution_event_enabled();
+};
+
+#endif // SHARE_VM_GC_SHARED_AGETABLETRACER_HPP
--- a/hotspot/src/share/vm/gc/shared/concurrentGCThread.cpp	Thu Feb 11 13:58:41 2016 -0800
+++ b/hotspot/src/share/vm/gc/shared/concurrentGCThread.cpp	Tue Feb 16 12:01:37 2016 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2016, 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
@@ -60,7 +60,7 @@
 void ConcurrentGCThread::wait_for_universe_init() {
   MutexLockerEx x(CGC_lock, Mutex::_no_safepoint_check_flag);
   while (!is_init_completed() && !_should_terminate) {
-    CGC_lock->wait(Mutex::_no_safepoint_check_flag, 200);
+    CGC_lock->wait(Mutex::_no_safepoint_check_flag, 1);
   }
 }
 
--- a/hotspot/src/share/vm/gc/shared/concurrentGCThread.hpp	Thu Feb 11 13:58:41 2016 -0800
+++ b/hotspot/src/share/vm/gc/shared/concurrentGCThread.hpp	Tue Feb 16 12:01:37 2016 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2016, 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
@@ -32,7 +32,7 @@
   friend class VMStructs;
 
 protected:
-  bool _should_terminate;
+  bool volatile _should_terminate;
   bool _has_terminated;
 
   // Create and start the thread (setting it's priority high.)
--- a/hotspot/src/share/vm/gc/shared/gcHeapSummary.hpp	Thu Feb 11 13:58:41 2016 -0800
+++ b/hotspot/src/share/vm/gc/shared/gcHeapSummary.hpp	Tue Feb 16 12:01:37 2016 -0800
@@ -131,12 +131,14 @@
   size_t  _edenUsed;
   size_t  _edenCapacity;
   size_t  _survivorUsed;
+  uint    _numberOfRegions;
  public:
-   G1HeapSummary(VirtualSpaceSummary& heap_space, size_t heap_used, size_t edenUsed, size_t edenCapacity, size_t survivorUsed) :
-       GCHeapSummary(heap_space, heap_used), _edenUsed(edenUsed), _edenCapacity(edenCapacity), _survivorUsed(survivorUsed) { }
+   G1HeapSummary(VirtualSpaceSummary& heap_space, size_t heap_used, size_t edenUsed, size_t edenCapacity, size_t survivorUsed, uint numberOfRegions) :
+      GCHeapSummary(heap_space, heap_used), _edenUsed(edenUsed), _edenCapacity(edenCapacity), _survivorUsed(survivorUsed), _numberOfRegions(numberOfRegions) { }
    const size_t edenUsed() const { return _edenUsed; }
    const size_t edenCapacity() const { return _edenCapacity; }
    const size_t survivorUsed() const { return _survivorUsed; }
+   const uint   numberOfRegions() const { return _numberOfRegions; }
 
    virtual void accept(GCHeapSummaryVisitor* visitor) const {
      visitor->visit(this);
--- a/hotspot/src/share/vm/gc/shared/gcTraceSend.cpp	Thu Feb 11 13:58:41 2016 -0800
+++ b/hotspot/src/share/vm/gc/shared/gcTraceSend.cpp	Tue Feb 16 12:01:37 2016 -0800
@@ -359,6 +359,7 @@
       e.set_edenUsedSize(g1_heap_summary->edenUsed());
       e.set_edenTotalSize(g1_heap_summary->edenCapacity());
       e.set_survivorUsedSize(g1_heap_summary->survivorUsed());
+      e.set_numberOfRegions(g1_heap_summary->numberOfRegions());
       e.commit();
     }
   }
--- a/hotspot/src/share/vm/prims/methodComparator.cpp	Thu Feb 11 13:58:41 2016 -0800
+++ b/hotspot/src/share/vm/prims/methodComparator.cpp	Tue Feb 16 12:01:37 2016 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2016, 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
@@ -34,9 +34,6 @@
 BytecodeStream *MethodComparator::_s_new;
 ConstantPool* MethodComparator::_old_cp;
 ConstantPool* MethodComparator::_new_cp;
-BciMap *MethodComparator::_bci_map;
-bool MethodComparator::_switchable_test;
-GrowableArray<int> *MethodComparator::_fwd_jmps;
 
 bool MethodComparator::methods_EMCP(Method* old_method, Method* new_method) {
   if (old_method->code_size() != new_method->code_size())
@@ -55,7 +52,6 @@
   BytecodeStream s_new(new_method);
   _s_old = &s_old;
   _s_new = &s_new;
-  _switchable_test = false;
   Bytecodes::Code c_old, c_new;
 
   while ((c_old = s_old.next()) >= 0) {
@@ -68,64 +64,6 @@
   return true;
 }
 
-
-bool MethodComparator::methods_switchable(Method* old_method, Method* new_method,
-                                          BciMap &bci_map) {
-  if (old_method->code_size() > new_method->code_size())
-    // Something has definitely been deleted in the new method, compared to the old one.
-    return false;
-
-  if (! check_stack_and_locals_size(old_method, new_method))
-    return false;
-
-  _old_cp = old_method->constants();
-  _new_cp = new_method->constants();
-  BytecodeStream s_old(old_method);
-  BytecodeStream s_new(new_method);
-  _s_old = &s_old;
-  _s_new = &s_new;
-  _bci_map = &bci_map;
-  _switchable_test = true;
-  GrowableArray<int> fwd_jmps(16);
-  _fwd_jmps = &fwd_jmps;
-  Bytecodes::Code c_old, c_new;
-
-  while ((c_old = s_old.next()) >= 0) {
-    if ((c_new = s_new.next()) < 0)
-      return false;
-    if (! (c_old == c_new && args_same(c_old, c_new))) {
-      int old_bci = s_old.bci();
-      int new_st_bci = s_new.bci();
-      bool found_match = false;
-      do {
-        c_new = s_new.next();
-        if (c_new == c_old && args_same(c_old, c_new)) {
-          found_match = true;
-          break;
-        }
-      } while (c_new >= 0);
-      if (! found_match)
-        return false;
-      int new_end_bci = s_new.bci();
-      bci_map.store_fragment_location(old_bci, new_st_bci, new_end_bci);
-    }
-  }
-
-  // Now we can test all forward jumps
-  for (int i = 0; i < fwd_jmps.length() / 2; i++) {
-    if (! bci_map.old_and_new_locations_same(fwd_jmps.at(i*2), fwd_jmps.at(i*2+1))) {
-      RC_TRACE(0x00800000,
-        ("Fwd jump miss: old dest = %d, calc new dest = %d, act new dest = %d",
-        fwd_jmps.at(i*2), bci_map.new_bci_for_old(fwd_jmps.at(i*2)),
-        fwd_jmps.at(i*2+1)));
-      return false;
-    }
-  }
-
-  return true;
-}
-
-
 bool MethodComparator::args_same(Bytecodes::Code c_old, Bytecodes::Code c_new) {
   // BytecodeStream returns the correct standard Java bytecodes for various "fast"
   // bytecode versions, so we don't have to bother about them here..
@@ -275,22 +213,8 @@
   case Bytecodes::_jsr       : {
     int old_ofs = _s_old->bytecode().get_offset_s2(c_old);
     int new_ofs = _s_new->bytecode().get_offset_s2(c_new);
-    if (_switchable_test) {
-      int old_dest = _s_old->bci() + old_ofs;
-      int new_dest = _s_new->bci() + new_ofs;
-      if (old_ofs < 0 && new_ofs < 0) {
-        if (! _bci_map->old_and_new_locations_same(old_dest, new_dest))
-          return false;
-      } else if (old_ofs > 0 && new_ofs > 0) {
-        _fwd_jmps->append(old_dest);
-        _fwd_jmps->append(new_dest);
-      } else {
-        return false;
-      }
-    } else {
-      if (old_ofs != new_ofs)
-        return false;
-    }
+    if (old_ofs != new_ofs)
+      return false;
     break;
   }
 
@@ -312,73 +236,19 @@
   case Bytecodes::_jsr_w  : {
     int old_ofs = _s_old->bytecode().get_offset_s4(c_old);
     int new_ofs = _s_new->bytecode().get_offset_s4(c_new);
-    if (_switchable_test) {
-      int old_dest = _s_old->bci() + old_ofs;
-      int new_dest = _s_new->bci() + new_ofs;
-      if (old_ofs < 0 && new_ofs < 0) {
-        if (! _bci_map->old_and_new_locations_same(old_dest, new_dest))
-          return false;
-      } else if (old_ofs > 0 && new_ofs > 0) {
-        _fwd_jmps->append(old_dest);
-        _fwd_jmps->append(new_dest);
-      } else {
-        return false;
-      }
-    } else {
-      if (old_ofs != new_ofs)
-        return false;
-    }
+    if (old_ofs != new_ofs)
+      return false;
     break;
   }
 
   case Bytecodes::_lookupswitch : // fall through
   case Bytecodes::_tableswitch  : {
-    if (_switchable_test) {
-      address aligned_bcp_old = (address) round_to((intptr_t)_s_old->bcp() + 1, jintSize);
-      address aligned_bcp_new = (address) round_to((intptr_t)_s_new->bcp() + 1, jintSize);
-      int default_old = (int) Bytes::get_Java_u4(aligned_bcp_old);
-      int default_new = (int) Bytes::get_Java_u4(aligned_bcp_new);
-      _fwd_jmps->append(_s_old->bci() + default_old);
-      _fwd_jmps->append(_s_new->bci() + default_new);
-      if (c_old == Bytecodes::_lookupswitch) {
-        int npairs_old = (int) Bytes::get_Java_u4(aligned_bcp_old + jintSize);
-        int npairs_new = (int) Bytes::get_Java_u4(aligned_bcp_new + jintSize);
-        if (npairs_old != npairs_new)
-          return false;
-        for (int i = 0; i < npairs_old; i++) {
-          int match_old = (int) Bytes::get_Java_u4(aligned_bcp_old + (2+2*i)*jintSize);
-          int match_new = (int) Bytes::get_Java_u4(aligned_bcp_new + (2+2*i)*jintSize);
-          if (match_old != match_new)
-            return false;
-          int ofs_old = (int) Bytes::get_Java_u4(aligned_bcp_old + (2+2*i+1)*jintSize);
-          int ofs_new = (int) Bytes::get_Java_u4(aligned_bcp_new + (2+2*i+1)*jintSize);
-          _fwd_jmps->append(_s_old->bci() + ofs_old);
-          _fwd_jmps->append(_s_new->bci() + ofs_new);
-        }
-      } else if (c_old == Bytecodes::_tableswitch) {
-        int lo_old = (int) Bytes::get_Java_u4(aligned_bcp_old + jintSize);
-        int lo_new = (int) Bytes::get_Java_u4(aligned_bcp_new + jintSize);
-        if (lo_old != lo_new)
-          return false;
-        int hi_old = (int) Bytes::get_Java_u4(aligned_bcp_old + 2*jintSize);
-        int hi_new = (int) Bytes::get_Java_u4(aligned_bcp_new + 2*jintSize);
-        if (hi_old != hi_new)
-          return false;
-        for (int i = 0; i < hi_old - lo_old + 1; i++) {
-          int ofs_old = (int) Bytes::get_Java_u4(aligned_bcp_old + (3+i)*jintSize);
-          int ofs_new = (int) Bytes::get_Java_u4(aligned_bcp_new + (3+i)*jintSize);
-          _fwd_jmps->append(_s_old->bci() + ofs_old);
-          _fwd_jmps->append(_s_new->bci() + ofs_new);
-        }
-      }
-    } else { // !_switchable_test, can use fast rough compare
-      int len_old = _s_old->instruction_size();
-      int len_new = _s_new->instruction_size();
-      if (len_old != len_new)
-        return false;
-      if (memcmp(_s_old->bcp(), _s_new->bcp(), len_old) != 0)
-        return false;
-    }
+    int len_old = _s_old->instruction_size();
+    int len_new = _s_new->instruction_size();
+    if (len_old != len_new)
+      return false;
+    if (memcmp(_s_old->bcp(), _s_new->bcp(), len_old) != 0)
+      return false;
     break;
   }
   }
--- a/hotspot/src/share/vm/prims/methodComparator.hpp	Thu Feb 11 13:58:41 2016 -0800
+++ b/hotspot/src/share/vm/prims/methodComparator.hpp	Tue Feb 16 12:01:37 2016 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2016, 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
@@ -29,8 +29,6 @@
 #include "oops/constantPool.hpp"
 #include "oops/method.hpp"
 
-class BciMap;
-
 // methodComparator provides an interface for determining if methods of
 // different versions of classes are equivalent or switchable
 
@@ -39,9 +37,6 @@
   static BytecodeStream *_s_old, *_s_new;
   static ConstantPool* _old_cp;
   static ConstantPool* _new_cp;
-  static BciMap *_bci_map;
-  static bool _switchable_test;
-  static GrowableArray<int> *_fwd_jmps;
 
   static bool args_same(Bytecodes::Code c_old, Bytecodes::Code c_new);
   static bool pool_constants_same(int cpi_old, int cpi_new);
@@ -55,79 +50,6 @@
   // these indices eventually point to the same constants for both method versions.
   static bool methods_EMCP(Method* old_method, Method* new_method);
 
-  static bool methods_switchable(Method* old_method, Method* new_method, BciMap &bci_map);
-};
-
-
-// ByteCode Index Map. For two versions of the same method, where the new version may contain
-// fragments not found in the old version, provides a mapping from an index of a bytecode in
-// the old method to the index of the same bytecode in the new method.
-
-class BciMap {
- private:
-  int *_old_bci, *_new_st_bci, *_new_end_bci;
-  int _cur_size, _cur_pos;
-  int _pos;
-
- public:
-  BciMap() {
-    _cur_size = 50;
-    _old_bci = (int*) malloc(sizeof(int) * _cur_size);
-    _new_st_bci = (int*) malloc(sizeof(int) * _cur_size);
-    _new_end_bci = (int*) malloc(sizeof(int) * _cur_size);
-    _cur_pos = 0;
-  }
-
-  ~BciMap() {
-    free(_old_bci);
-    free(_new_st_bci);
-    free(_new_end_bci);
-  }
-
-  // Store the position of an added fragment, e.g.
-  //
-  //                              |<- old_bci
-  // -----------------------------------------
-  // Old method   |invokevirtual 5|aload 1|...
-  // -----------------------------------------
-  //
-  //                                 |<- new_st_bci          |<- new_end_bci
-  // --------------------------------------------------------------------
-  // New method       |invokevirual 5|aload 2|invokevirtual 6|aload 1|...
-  // --------------------------------------------------------------------
-  //                                 ^^^^^^^^^^^^^^^^^^^^^^^^
-  //                                    Added fragment
-
-  void store_fragment_location(int old_bci, int new_st_bci, int new_end_bci) {
-    if (_cur_pos == _cur_size) {
-      _cur_size += 10;
-      _old_bci = (int*) realloc(_old_bci, sizeof(int) * _cur_size);
-      _new_st_bci = (int*) realloc(_new_st_bci, sizeof(int) * _cur_size);
-      _new_end_bci = (int*) realloc(_new_end_bci, sizeof(int) * _cur_size);
-    }
-    _old_bci[_cur_pos] = old_bci;
-    _new_st_bci[_cur_pos] = new_st_bci;
-    _new_end_bci[_cur_pos] = new_end_bci;
-    _cur_pos++;
-  }
-
-  int new_bci_for_old(int old_bci) {
-    if (_cur_pos == 0 || old_bci < _old_bci[0]) return old_bci;
-    _pos = 1;
-    while (_pos < _cur_pos && old_bci >= _old_bci[_pos])
-      _pos++;
-    return _new_end_bci[_pos-1] + (old_bci - _old_bci[_pos-1]);
-  }
-
-  // Test if two indexes - one in the old method and another in the new one - correspond
-  // to the same bytecode
-  bool old_and_new_locations_same(int old_dest_bci, int new_dest_bci) {
-    if (new_bci_for_old(old_dest_bci) == new_dest_bci)
-      return true;
-    else if (_old_bci[_pos-1] == old_dest_bci)
-      return (new_dest_bci == _new_st_bci[_pos-1]);
-    else return false;
-  }
 };
 
 #endif // SHARE_VM_PRIMS_METHODCOMPARATOR_HPP
--- a/hotspot/src/share/vm/prims/unsafe.cpp	Thu Feb 11 13:58:41 2016 -0800
+++ b/hotspot/src/share/vm/prims/unsafe.cpp	Tue Feb 16 12:01:37 2016 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2016, 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
@@ -660,6 +660,36 @@
   Copy::conjoint_memory_atomic(src, dst, sz);
 UNSAFE_END
 
+// This function is a leaf since if the source and destination are both in native memory
+// the copy may potentially be very large, and we don't want to disable GC if we can avoid it.
+// If either source or destination (or both) are on the heap, the function will enter VM using
+// JVM_ENTRY_FROM_LEAF
+JVM_LEAF(void, Unsafe_CopySwapMemory0(JNIEnv *env, jobject unsafe, jobject srcObj, jlong srcOffset, jobject dstObj, jlong dstOffset, jlong size, jlong elemSize)) {
+  UnsafeWrapper("Unsafe_CopySwapMemory0");
+
+  size_t sz = (size_t)size;
+  size_t esz = (size_t)elemSize;
+
+  if (srcObj == NULL && dstObj == NULL) {
+    // Both src & dst are in native memory
+    address src = (address)srcOffset;
+    address dst = (address)dstOffset;
+
+    Copy::conjoint_swap(src, dst, sz, esz);
+  } else {
+    // At least one of src/dst are on heap, transition to VM to access raw pointers
+
+    JVM_ENTRY_FROM_LEAF(env, void, Unsafe_CopySwapMemory0) {
+      oop srcp = JNIHandles::resolve(srcObj);
+      oop dstp = JNIHandles::resolve(dstObj);
+
+      address src = (address)index_oop_from_field_offset_long(srcp, srcOffset);
+      address dst = (address)index_oop_from_field_offset_long(dstp, dstOffset);
+
+      Copy::conjoint_swap(src, dst, sz, esz);
+    } JVM_END
+  }
+} JVM_END
 
 ////// Random queries
 
@@ -1363,6 +1393,7 @@
     {CC "getLoadAverage",     CC "([DI)I",               FN_PTR(Unsafe_Loadavg)},
 
     {CC "copyMemory",         CC "(" OBJ "J" OBJ "JJ)V", FN_PTR(Unsafe_CopyMemory)},
+    {CC "copySwapMemory0",    CC "(" OBJ "J" OBJ "JJJ)V", FN_PTR(Unsafe_CopySwapMemory0)},
     {CC "setMemory",          CC "(" OBJ "JJB)V",        FN_PTR(Unsafe_SetMemory)},
 
     {CC "defineAnonymousClass", CC "(" DAC_Args ")" CLS, FN_PTR(Unsafe_DefineAnonymousClass)},
--- a/hotspot/src/share/vm/runtime/arguments.cpp	Thu Feb 11 13:58:41 2016 -0800
+++ b/hotspot/src/share/vm/runtime/arguments.cpp	Tue Feb 16 12:01:37 2016 -0800
@@ -333,6 +333,8 @@
   // --- Non-alias flags - sorted by obsolete_in then expired_in:
   { "MaxGCMinorPauseMillis",        JDK_Version::jdk(8), JDK_Version::undefined(), JDK_Version::undefined() },
   { "UseParNewGC",                  JDK_Version::jdk(9), JDK_Version::undefined(), JDK_Version::jdk(10) },
+  { "ConvertSleepToYield",          JDK_Version::jdk(9), JDK_Version::jdk(10),     JDK_Version::jdk(11) },
+  { "ConvertYieldToSleep",          JDK_Version::jdk(9), JDK_Version::jdk(10),     JDK_Version::jdk(11) },
 
   // --- Deprecated alias flags (see also aliased_jvm_flags) - sorted by obsolete_in then expired_in:
   { "DefaultMaxRAMFraction",        JDK_Version::jdk(8), JDK_Version::undefined(), JDK_Version::undefined() },
--- a/hotspot/src/share/vm/runtime/globals.hpp	Thu Feb 11 13:58:41 2016 -0800
+++ b/hotspot/src/share/vm/runtime/globals.hpp	Tue Feb 16 12:01:37 2016 -0800
@@ -1239,9 +1239,8 @@
   product_pd(bool, DontYieldALot,                                           \
           "Throw away obvious excess yield calls")                          \
                                                                             \
-  product_pd(bool, ConvertSleepToYield,                                     \
-          "Convert sleep(0) to thread yield "                               \
-          "(may be off for Solaris to improve GUI)")                        \
+  product(bool, ConvertSleepToYield, true,                                  \
+          "Convert sleep(0) to thread yield ")                              \
                                                                             \
   product(bool, ConvertYieldToSleep, false,                                 \
           "Convert yield to a sleep of MinSleepInterval to simulate Win32 " \
@@ -1279,10 +1278,6 @@
   experimental(intx, hashCode, 5,                                           \
                "(Unstable) select hashCode generation algorithm")           \
                                                                             \
-  experimental(intx, WorkAroundNPTLTimedWaitHang, 0,                        \
-               "(Unstable, Linux-specific) "                                \
-               "avoid NPTL-FUTEX hang pthread_cond_timedwait")              \
-                                                                            \
   product(bool, FilterSpuriousWakeups, true,                                \
           "When true prevents OS-level spurious, or premature, wakeups "    \
           "from Object.wait (Ignored for Windows)")                         \
@@ -2012,11 +2007,15 @@
           range(min_intx, 100)                                              \
                                                                             \
   product(uintx, InitiatingHeapOccupancyPercent, 45,                        \
-          "Percentage of the (entire) heap occupancy to start a "           \
-          "concurrent GC cycle. It is used by GCs that trigger a "          \
-          "concurrent GC cycle based on the occupancy of the entire heap, " \
-          "not just one of the generations (e.g., G1). A value of 0 "       \
-          "denotes 'do constant GC cycles'.")                               \
+          "The percent occupancy (IHOP) of the current old generation "     \
+          "capacity above which a concurrent mark cycle will be initiated " \
+          "Its value may change over time if adaptive IHOP is enabled, "    \
+          "otherwise the value remains constant. "                          \
+          "In the latter case a value of 0 will result as frequent as "     \
+          "possible concurrent marking cycles. A value of 100 disables "    \
+          "concurrent marking. "                                            \
+          "Fragmentation waste in the old generation is not considered "    \
+          "free space in this calculation. (G1 collector only)")            \
           range(0, 100)                                                     \
                                                                             \
   manageable(intx, CMSTriggerInterval, -1,                                  \
--- a/hotspot/src/share/vm/runtime/init.cpp	Thu Feb 11 13:58:41 2016 -0800
+++ b/hotspot/src/share/vm/runtime/init.cpp	Tue Feb 16 12:01:37 2016 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2016, 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
@@ -181,8 +181,7 @@
   }
 }
 
-
-static bool _init_completed = false;
+static volatile bool _init_completed = false;
 
 bool is_init_completed() {
   return _init_completed;
--- a/hotspot/src/share/vm/runtime/interfaceSupport.hpp	Thu Feb 11 13:58:41 2016 -0800
+++ b/hotspot/src/share/vm/runtime/interfaceSupport.hpp	Tue Feb 16 12:01:37 2016 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2016, 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
@@ -417,6 +417,14 @@
   os::verify_stack_alignment();                                      \
   /* begin of body */
 
+#define VM_ENTRY_BASE_FROM_LEAF(result_type, header, thread)         \
+  TRACE_CALL(result_type, header)                                    \
+  debug_only(ResetNoHandleMark __rnhm;)                              \
+  HandleMarkCleaner __hm(thread);                                    \
+  Thread* THREAD = thread;                                           \
+  os::verify_stack_alignment();                                      \
+  /* begin of body */
+
 
 // ENTRY routines may lock, GC and throw exceptions
 
@@ -584,6 +592,14 @@
     VM_LEAF_BASE(result_type, header)
 
 
+#define JVM_ENTRY_FROM_LEAF(env, result_type, header)                \
+  { {                                                                \
+    JavaThread* thread=JavaThread::thread_from_jni_environment(env); \
+    ThreadInVMfromNative __tiv(thread);                              \
+    debug_only(VMNativeEntryWrapper __vew;)                          \
+    VM_ENTRY_BASE_FROM_LEAF(result_type, header, thread)
+
+
 #define JVM_END } }
 
 #endif // SHARE_VM_RUNTIME_INTERFACESUPPORT_HPP
--- a/hotspot/src/share/vm/trace/trace.xml	Thu Feb 11 13:58:41 2016 -0800
+++ b/hotspot/src/share/vm/trace/trace.xml	Tue Feb 16 12:01:37 2016 -0800
@@ -283,6 +283,7 @@
       <value type="BYTES64" field="edenUsedSize" label="Eden Used Size" />
       <value type="BYTES64" field="edenTotalSize" label="Eden Total Size" />
       <value type="BYTES64" field="survivorUsedSize" label="Survivor Used Size" />
+      <value type="UINT" field="numberOfRegions" label="Number of Regions" />
     </event>
 
     <event id="GCGarbageCollection" path="vm/gc/collector/garbage_collection" label="Garbage Collection"
@@ -478,6 +479,23 @@
       <value type="BYTES64" field="size" label="Allocation Size" />
     </event>
 
+    <event id="TenuringDistribution" path="vm/gc/detailed/tenuring_distribution" label="Tenuring Distribution"
+           is_instant="true">
+      <value type="UINT" field="gcId" label="GC ID" relation="GC_ID"/>
+      <value type="UINT" field="age" label="Age" />
+      <value type="BYTES64" field="size" label="Size" />
+    </event>
+
+    <event id="G1HeapRegionTypeChange" path="vm/gc/detailed/g1_heap_region_type_change" label="G1 Heap Region Type Change"
+           description="Information about a G1 heap region type change." is_instant="true">
+      <value type="UINT" field="index" label="Index" />
+      <value type="G1HEAPREGIONTYPE" field="from" label="From Type" />
+      <value type="G1HEAPREGIONTYPE" field="to" label="To Type" />
+      <value type="ADDRESS" field="start" label="Start" />
+      <value type="BYTES64" field="used" label="Used" />
+      <value type="UINT" field="allocContext" label="Allocation Context" />
+    </event>
+
     <!-- Compiler events -->
 
     <event id="Compilation" path="vm/compiler/compilation" label="Compilation"
--- a/hotspot/src/share/vm/trace/tracetypes.xml	Thu Feb 11 13:58:41 2016 -0800
+++ b/hotspot/src/share/vm/trace/tracetypes.xml	Tue Feb 16 12:01:37 2016 -0800
@@ -126,6 +126,11 @@
       <value type="UTF8" field="when" label="when" />
     </content_type>
 
+    <content_type id="G1HeapRegionType" hr_name="G1 Heap Region Type"
+                  type="U1" jvm_type="G1HEAPREGIONTYPE">
+      <value type="UTF8" field="type" label="type" />
+    </content_type>
+    
     <content_type id="G1YCType" hr_name="G1 YC Type"
                   type="U1" jvm_type="G1YCTYPE">
       <value type="UTF8" field="type" label="type" />
@@ -345,6 +350,10 @@
     <primary_type symbol="GCWHEN" datatype="U1" contenttype="GCWHEN"
                   type="u1" sizeop="sizeof(u1)" />
 
+    <!-- G1HEAPREGIONTYPE -->
+    <primary_type symbol="G1HEAPREGIONTYPE" datatype="U1" contenttype="G1HEAPREGIONTYPE"
+                  type="u1" sizeop="sizeof(u1)" />
+
     <!-- G1YCType -->
     <primary_type symbol="G1YCTYPE" datatype="U1" contenttype="G1YCTYPE"
                   type="u1" sizeop="sizeof(u1)" />
--- a/hotspot/src/share/vm/utilities/copy.cpp	Thu Feb 11 13:58:41 2016 -0800
+++ b/hotspot/src/share/vm/utilities/copy.cpp	Tue Feb 16 12:01:37 2016 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2016, 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
@@ -53,6 +53,175 @@
   }
 }
 
+class CopySwap : AllStatic {
+public:
+  /**
+   * Copy and byte swap elements
+   *
+   * @param src address of source
+   * @param dst address of destination
+   * @param byte_count number of bytes to copy
+   * @param elem_size size of the elements to copy-swap
+   */
+  static void conjoint_swap(address src, address dst, size_t byte_count, size_t elem_size) {
+    assert(src != NULL, "address must not be NULL");
+    assert(dst != NULL, "address must not be NULL");
+    assert(elem_size == 2 || elem_size == 4 || elem_size == 8,
+           "incorrect element size: " SIZE_FORMAT, elem_size);
+    assert(is_size_aligned(byte_count, elem_size),
+           "byte_count " SIZE_FORMAT " must be multiple of element size " SIZE_FORMAT, byte_count, elem_size);
+
+    address src_end = src + byte_count;
+
+    if (dst <= src || dst >= src_end) {
+      do_conjoint_swap<RIGHT>(src, dst, byte_count, elem_size);
+    } else {
+      do_conjoint_swap<LEFT>(src, dst, byte_count, elem_size);
+    }
+  }
+
+private:
+  /**
+   * Byte swap a 16-bit value
+   */
+  static uint16_t byte_swap(uint16_t x) {
+    return (x << 8) | (x >> 8);
+  }
+
+  /**
+   * Byte swap a 32-bit value
+   */
+  static uint32_t byte_swap(uint32_t x) {
+    uint16_t lo = (uint16_t)x;
+    uint16_t hi = (uint16_t)(x >> 16);
+
+    return ((uint32_t)byte_swap(lo) << 16) | (uint32_t)byte_swap(hi);
+  }
+
+  /**
+   * Byte swap a 64-bit value
+   */
+  static uint64_t byte_swap(uint64_t x) {
+    uint32_t lo = (uint32_t)x;
+    uint32_t hi = (uint32_t)(x >> 32);
+
+    return ((uint64_t)byte_swap(lo) << 32) | (uint64_t)byte_swap(hi);
+  }
+
+  enum CopyDirection {
+    RIGHT, // lower -> higher address
+    LEFT   // higher -> lower address
+  };
+
+  /**
+   * Copy and byte swap elements
+   *
+   * <T> - type of element to copy
+   * <D> - copy direction
+   * <is_src_aligned> - true if src argument is aligned to element size
+   * <is_dst_aligned> - true if dst argument is aligned to element size
+   *
+   * @param src address of source
+   * @param dst address of destination
+   * @param byte_count number of bytes to copy
+   */
+  template <typename T, CopyDirection D, bool is_src_aligned, bool is_dst_aligned>
+  static void do_conjoint_swap(address src, address dst, size_t byte_count) {
+    address cur_src, cur_dst;
+
+    switch (D) {
+    case RIGHT:
+      cur_src = src;
+      cur_dst = dst;
+      break;
+    case LEFT:
+      cur_src = src + byte_count - sizeof(T);
+      cur_dst = dst + byte_count - sizeof(T);
+      break;
+    }
+
+    for (size_t i = 0; i < byte_count / sizeof(T); i++) {
+      T tmp;
+
+      if (is_src_aligned) {
+        tmp = *(T*)cur_src;
+      } else {
+        memcpy(&tmp, cur_src, sizeof(T));
+      }
+
+      tmp = byte_swap(tmp);
+
+      if (is_dst_aligned) {
+        *(T*)cur_dst = tmp;
+      } else {
+        memcpy(cur_dst, &tmp, sizeof(T));
+      }
+
+      switch (D) {
+      case RIGHT:
+        cur_src += sizeof(T);
+        cur_dst += sizeof(T);
+        break;
+      case LEFT:
+        cur_src -= sizeof(T);
+        cur_dst -= sizeof(T);
+        break;
+      }
+    }
+  }
+
+  /**
+   * Copy and byte swap elements
+   *
+   * <T> - type of element to copy
+   * <D> - copy direction
+   *
+   * @param src address of source
+   * @param dst address of destination
+   * @param byte_count number of bytes to copy
+   */
+  template <typename T, CopyDirection direction>
+  static void do_conjoint_swap(address src, address dst, size_t byte_count) {
+    if (is_ptr_aligned(src, sizeof(T))) {
+      if (is_ptr_aligned(dst, sizeof(T))) {
+        do_conjoint_swap<T,direction,true,true>(src, dst, byte_count);
+      } else {
+        do_conjoint_swap<T,direction,true,false>(src, dst, byte_count);
+      }
+    } else {
+      if (is_ptr_aligned(dst, sizeof(T))) {
+        do_conjoint_swap<T,direction,false,true>(src, dst, byte_count);
+      } else {
+        do_conjoint_swap<T,direction,false,false>(src, dst, byte_count);
+      }
+    }
+  }
+
+
+  /**
+   * Copy and byte swap elements
+   *
+   * <D> - copy direction
+   *
+   * @param src address of source
+   * @param dst address of destination
+   * @param byte_count number of bytes to copy
+   * @param elem_size size of the elements to copy-swap
+   */
+  template <CopyDirection D>
+  static void do_conjoint_swap(address src, address dst, size_t byte_count, size_t elem_size) {
+    switch (elem_size) {
+    case 2: do_conjoint_swap<uint16_t,D>(src, dst, byte_count); break;
+    case 4: do_conjoint_swap<uint32_t,D>(src, dst, byte_count); break;
+    case 8: do_conjoint_swap<uint64_t,D>(src, dst, byte_count); break;
+    default: guarantee(false, "do_conjoint_swap: Invalid elem_size %zd\n", elem_size);
+    }
+  }
+};
+
+void Copy::conjoint_swap(address src, address dst, size_t byte_count, size_t elem_size) {
+  CopySwap::conjoint_swap(src, dst, byte_count, elem_size);
+}
 
 // Fill bytes; larger units are filled atomically if everything is aligned.
 void Copy::fill_to_memory_atomic(void* to, size_t size, jubyte value) {
--- a/hotspot/src/share/vm/utilities/copy.hpp	Thu Feb 11 13:58:41 2016 -0800
+++ b/hotspot/src/share/vm/utilities/copy.hpp	Tue Feb 16 12:01:37 2016 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2016, 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
@@ -227,6 +227,16 @@
     }
   }
 
+  /**
+   * Copy and *unconditionally* byte swap elements
+   *
+   * @param src address of source
+   * @param dst address of destination
+   * @param byte_count number of bytes to copy
+   * @param elem_size size of the elements to copy-swap
+   */
+  static void conjoint_swap(address src, address dst, size_t byte_count, size_t elem_size);
+
   // Fill methods
 
   // Fill word-aligned words, not atomic on each word
--- a/hotspot/test/runtime/CommandLine/VMDeprecatedOptions.java	Thu Feb 11 13:58:41 2016 -0800
+++ b/hotspot/test/runtime/CommandLine/VMDeprecatedOptions.java	Tue Feb 16 12:01:37 2016 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2016, 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
@@ -40,6 +40,8 @@
         // deprecated non-alias flags:
         {"MaxGCMinorPauseMillis", "1032"},
         {"UseParNewGC", "false"},
+        {"ConvertSleepToYield", "false" },
+        {"ConvertYieldToSleep", "false" },
 
         // deprecated alias flags (see also aliased_jvm_flags):
         {"DefaultMaxRAMFraction", "4"},